mirror of https://github.com/status-im/timbre.git
Add new appender opt: `:appender-fmt-output-opts`
This commit is contained in:
parent
f83b417cb0
commit
f04aba6e0d
|
@ -92,13 +92,15 @@
|
||||||
"APPENDERS
|
"APPENDERS
|
||||||
An appender is a map with keys:
|
An appender is a map with keys:
|
||||||
:doc, :min-level, :enabled?, :async?, :fn,
|
:doc, :min-level, :enabled?, :async?, :fn,
|
||||||
:rate-limit ([ncalls-limit window-ms] form).
|
:rate-limit ; [ncalls-limit window-ms],
|
||||||
|
:fmt-output-opts ; Extra opts passed to `fmt-output-fn`.
|
||||||
|
|
||||||
An appender's fn takes a single map with keys:
|
An appender's fn takes a single map with keys:
|
||||||
:level, :throwable
|
:level, :throwable
|
||||||
:args, ; Raw logging macro args (as given to `info`, etc.).
|
:args, ; Raw logging macro args (as given to `info`, etc.).
|
||||||
:message, ; Stringified logging macro args, or nil.
|
:message, ; Stringified logging macro args, or nil.
|
||||||
:default-output ; Output of `fmt-output-fn`, used by built-in appenders.
|
:output ; Output of `fmt-output-fn`, used by built-in appenders
|
||||||
|
; as final, formatted appender output.
|
||||||
:ap-config ; `shared-appender-config`.
|
:ap-config ; `shared-appender-config`.
|
||||||
:profile-stats ; From `profile` macro.
|
:profile-stats ; From `profile` macro.
|
||||||
And also: :instant, :timestamp, :hostname, :ns, :error?
|
And also: :instant, :timestamp, :hostname, :ns, :error?
|
||||||
|
@ -129,30 +131,33 @@
|
||||||
(str timestamp " " hostname " " (-> level name str/upper-case)
|
(str timestamp " " hostname " " (-> level name str/upper-case)
|
||||||
" [" ns "]"))
|
" [" ns "]"))
|
||||||
|
|
||||||
;; Default output formatter used by built-in appenders. Custom appenders
|
;; Output formatter used by built-in appenders. Custom appenders may (but are
|
||||||
;; may (but are not required to use) its output (:default-output).
|
;; not required to use) its output (:output). Extra per-appender opts can be
|
||||||
|
;; supplied as an optional second (map) arg.
|
||||||
:fmt-output-fn
|
:fmt-output-fn
|
||||||
(fn [{:keys [level throwable message timestamp hostname ns]}]
|
(fn [{:keys [level throwable message timestamp hostname ns]}
|
||||||
|
;; Any extra appender-specific opts:
|
||||||
|
& [{:keys [nofonts?] :as appender-fmt-output-opts}]]
|
||||||
;; <timestamp> <hostname> <LEVEL> [<ns>] - <message> <throwable>
|
;; <timestamp> <hostname> <LEVEL> [<ns>] - <message> <throwable>
|
||||||
(format "%s %s %s [%s] - %s%s"
|
(format "%s %s %s [%s] - %s%s"
|
||||||
timestamp hostname (-> level name str/upper-case) ns (or message "")
|
timestamp hostname (-> level name str/upper-case) ns (or message "")
|
||||||
(or (stacktrace throwable "\n") "")))
|
(or (stacktrace throwable "\n" (when nofonts? {})) "")))
|
||||||
|
|
||||||
:shared-appender-config {} ; Provided to all appenders via :ap-config key
|
:shared-appender-config {} ; Provided to all appenders via :ap-config key
|
||||||
:appenders
|
:appenders
|
||||||
{:standard-out
|
{:standard-out
|
||||||
{:doc "Prints to *out*/*err*. Enabled by default."
|
{:doc "Prints to *out*/*err*. Enabled by default."
|
||||||
:min-level nil :enabled? true :async? false :rate-limit nil
|
:min-level nil :enabled? true :async? false :rate-limit nil
|
||||||
:fn (fn [{:keys [error? default-output]}]
|
:fn (fn [{:keys [error? output]}]
|
||||||
(binding [*out* (if error? *err* *out*)]
|
(binding [*out* (if error? *err* *out*)]
|
||||||
(str-println default-output)))}
|
(str-println output)))}
|
||||||
|
|
||||||
:spit
|
:spit
|
||||||
{:doc "Spits to `(:spit-filename :shared-appender-config)` file."
|
{:doc "Spits to `(:spit-filename :shared-appender-config)` file."
|
||||||
:min-level nil :enabled? false :async? false :rate-limit nil
|
:min-level nil :enabled? false :async? false :rate-limit nil
|
||||||
:fn (fn [{:keys [ap-config default-output]}]
|
:fn (fn [{:keys [ap-config output]}]
|
||||||
(when-let [filename (:spit-filename ap-config)]
|
(when-let [filename (:spit-filename ap-config)]
|
||||||
(try (spit filename default-output :append true)
|
(try (spit filename output :append true)
|
||||||
(catch java.io.IOException _))))}}})
|
(catch java.io.IOException _))))}}})
|
||||||
|
|
||||||
(utils/defonce* config (atom example-config))
|
(utils/defonce* config (atom example-config))
|
||||||
|
@ -164,7 +169,7 @@
|
||||||
(defn- wrap-appender-fn
|
(defn- wrap-appender-fn
|
||||||
"Wraps compile-time appender fn with additional runtime capabilities
|
"Wraps compile-time appender fn with additional runtime capabilities
|
||||||
controlled by compile-time config."
|
controlled by compile-time config."
|
||||||
[config {apfn :fn :keys [async? rate-limit] :as appender}]
|
[config {apfn :fn :keys [async? rate-limit fmt-output-opts] :as appender}]
|
||||||
(let [rate-limit (or rate-limit ; Backwards comp:
|
(let [rate-limit (or rate-limit ; Backwards comp:
|
||||||
(if-let [x (:max-message-per-msecs appender)] [1 x]
|
(if-let [x (:max-message-per-msecs appender)] [1 x]
|
||||||
(when-let [x (:limit-per-msecs appender)] [1 x])))]
|
(when-let [x (:limit-per-msecs appender)] [1 x])))]
|
||||||
|
@ -174,6 +179,14 @@
|
||||||
(->> ; Wrapping applies per appender, bottom-to-top
|
(->> ; Wrapping applies per appender, bottom-to-top
|
||||||
apfn
|
apfn
|
||||||
|
|
||||||
|
;; Custom appender-level fmt-output-opts
|
||||||
|
((fn [apfn] ; Compile-time:
|
||||||
|
(if-not fmt-output-opts apfn ; Common case (no appender-level fmt opts)
|
||||||
|
(fn [apfn-args] ; Runtime:
|
||||||
|
;; Replace default (juxt-level) output:
|
||||||
|
(apfn (assoc apfn-args :output
|
||||||
|
((:fmt-output-fn config) apfn-args fmt-output-opts)))))))
|
||||||
|
|
||||||
;; Rate limit support
|
;; Rate limit support
|
||||||
((fn [apfn]
|
((fn [apfn]
|
||||||
;; Compile-time:
|
;; Compile-time:
|
||||||
|
@ -253,8 +266,8 @@
|
||||||
juxtfn-args (assoc juxtfn-args :timestamp (timestamp-fn instant))
|
juxtfn-args (assoc juxtfn-args :timestamp (timestamp-fn instant))
|
||||||
juxtfn-args (assoc juxtfn-args
|
juxtfn-args (assoc juxtfn-args
|
||||||
;; DEPRECATED, here for backwards comp:
|
;; DEPRECATED, here for backwards comp:
|
||||||
:prefix (when-let [f prefix-fn] (f juxtfn-args))
|
:prefix (when-let [f prefix-fn] (f juxtfn-args))
|
||||||
:default-output (when-let [f fmt-output-fn] (f juxtfn-args)))]
|
:output (when-let [f fmt-output-fn] (f juxtfn-args)))]
|
||||||
(juxtfn juxtfn-args)))))))
|
(juxtfn juxtfn-args)))))))
|
||||||
|
|
||||||
;; Middleware transforms/filters support
|
;; Middleware transforms/filters support
|
||||||
|
@ -300,6 +313,7 @@
|
||||||
;; since configs will usually be assigned to a var for which we have proper
|
;; since configs will usually be assigned to a var for which we have proper
|
||||||
;; identity.
|
;; identity.
|
||||||
(fn [{:keys [appenders] :as config}]
|
(fn [{:keys [appenders] :as config}]
|
||||||
|
(assert (map? appenders))
|
||||||
{:appenders-juxt
|
{:appenders-juxt
|
||||||
(zipmap levels-ordered
|
(zipmap levels-ordered
|
||||||
(->> levels-ordered
|
(->> levels-ordered
|
||||||
|
@ -525,4 +539,13 @@
|
||||||
(mapv (fn [arg] (if-not (map? arg) arg
|
(mapv (fn [arg] (if-not (map? arg) arg
|
||||||
(if-not (contains? arg :password) arg
|
(if-not (contains? arg :password) arg
|
||||||
(assoc arg :password "****"))))
|
(assoc arg :password "****"))))
|
||||||
args))))]))
|
args))))])
|
||||||
|
|
||||||
|
;; fmt-output-opts
|
||||||
|
(-> (merge example-config
|
||||||
|
{:appenders
|
||||||
|
{:fmt-output-opts-test
|
||||||
|
{:min-level :error :enabled? true
|
||||||
|
:fmt-output-opts {:nofonts? true}
|
||||||
|
:fn (fn [{:keys [output]}] (str-println output))}}})
|
||||||
|
(log :report (Exception. "Oh noes") "Hello")))
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
^{:host \"mail.isp.net\" :user \"jsmith\" :pass \"sekrat!!1\"}
|
^{:host \"mail.isp.net\" :user \"jsmith\" :pass \"sekrat!!1\"}
|
||||||
{:from \"Bob's logger <me@draines.com>\" :to \"foo@example.com\"}")
|
{:from \"Bob's logger <me@draines.com>\" :to \"foo@example.com\"}")
|
||||||
:min-level :error :enabled? true :async? true
|
:min-level :error :enabled? true :async? true
|
||||||
|
:fmt-output-opts {:nofonts? true}
|
||||||
:rate-limit [5 (* 1000 60 2)] ; 5 calls / 2 mins
|
:rate-limit [5 (* 1000 60 2)] ; 5 calls / 2 mins
|
||||||
:fn (fn [{:keys [ap-config default-output]}]
|
:fn (fn [{:keys [ap-config output]}]
|
||||||
(when-let [postal-config (:postal ap-config)]
|
(when-let [postal-config (:postal ap-config)]
|
||||||
(postal/send-message
|
(postal/send-message
|
||||||
(assoc postal-config
|
(assoc postal-config
|
||||||
:subject (-> default-output (str/trim) (str-trunc 150)
|
:subject (-> output (str/trim) (str-trunc 150) (str/replace #"\s+" " "))
|
||||||
(str/replace #"\s+" " "))
|
:body output))))})
|
||||||
:body default-output))))})
|
|
||||||
|
|
Loading…
Reference in New Issue