[#183] Add support for appender-level middleware

Motivating use case: let users apply custom ns-filtering or other
conditional logic at an appender level *without* needing to actually
modify the appender fn.

This is just a natural generalization of the recently added support
for appender-level ns filters, etc.
This commit is contained in:
Peter Taoussanis 2016-07-19 11:26:17 +07:00
parent 7894ea3d19
commit bf619cbe6e
2 changed files with 22 additions and 13 deletions

View File

@ -133,6 +133,7 @@ This is the biggest win over Java logging IMO. **All** of Timbre's behaviour is
:timestamp-opts ; Optional override for inherited {:pattern _ :locale _ :timezone _} :timestamp-opts ; Optional override for inherited {:pattern _ :locale _ :timezone _}
:ns-whitelist ; Optional, stacks with active config's whitelist :ns-whitelist ; Optional, stacks with active config's whitelist
:ns-blacklist ; Optional, stacks with active config's blacklist :ns-blacklist ; Optional, stacks with active config's blacklist
:middleware-fn ; Optional, stacks with active config's middleware
:fn ; (fn [data]) -> side effects, with keys described below :fn ; (fn [data]) -> side effects, with keys described below
An appender's fn takes a single data map with keys: An appender's fn takes a single data map with keys:

View File

@ -69,6 +69,7 @@
:timestamp-opts ; Optional override for inherited {:pattern _ :locale _ :timezone _} :timestamp-opts ; Optional override for inherited {:pattern _ :locale _ :timezone _}
:ns-whitelist ; Optional, stacks with active config's whitelist :ns-whitelist ; Optional, stacks with active config's whitelist
:ns-blacklist ; Optional, stacks with active config's blacklist :ns-blacklist ; Optional, stacks with active config's blacklist
:middleware-fn ; Optional, stacks with active config's middleware
:fn ; (fn [data]) -> side effects, with keys described below :fn ; (fn [data]) -> side effects, with keys described below
An appender's fn takes a single data map with keys: An appender's fn takes a single data map with keys:
@ -512,26 +513,33 @@
#+clj (assoc data :timestamp_ timestamp_) #+clj (assoc data :timestamp_ timestamp_)
#+cljs data)) #+cljs data))
data ; Final data prep before going to appender data
(conj data (conj data
{:appender-id id {:appender-id id
:appender appender :appender appender
:output-fn output-fn :output-fn output-fn
:output_ output_ :output_ output_
#+clj :timestamp_ #+clj timestamp_})] #+clj :timestamp_ #+clj timestamp_})
;; NB Unless `async?`, we currently allow appenders to ?data ; Final data prep before going to appender
;; throw since it's not particularly obvious how/where (if-let [mfn (:middleware-fn appender)]
;; we should report problems. Throwing early seems (mfn data)
;; preferable to just silently dropping errors. In data)]
;; effect, we currently require appenders to take
;; responsibility over appropriate trapping.
#+cljs (apfn data) (when-let [data ?data] ; Not filtered by middleware
#+clj
(if async? ;; NB Unless `async?`, we currently allow appenders
(send-off (get-agent id) (fn [_] (apfn data))) ;; to throw since it's not particularly obvious
(apfn data)))))))) ;; how/where we should report problems. Throwing
;; early seems preferable to just silently dropping
;; errors. In effect, we currently require appenders
;; to take responsibility over appropriate trapping.
#+cljs (apfn data)
#+clj
(if async?
(send-off (get-agent id) (fn [_] (apfn data)))
(apfn data)))))))))
nil nil
(:appenders config)))))) (:appenders config))))))
nil)) nil))