Refactor log macro implementations

This commit is contained in:
Peter Taoussanis 2013-08-07 22:50:39 +07:00
parent fd03c042e9
commit 77beb18032
4 changed files with 52 additions and 63 deletions

View File

@ -307,62 +307,55 @@
;;;; Define logging macros ;;;; Define logging macros
(defn send-to-appenders! "Implementation detail - subject to change."
[level base-appender-args log-vargs ns throwable message & [juxt-fn file line]]
(when-let [juxt-fn (or juxt-fn (@appenders-juxt-cache level))]
(juxt-fn
(conj (or base-appender-args {})
{:instant (Date.)
:ns ns
:file file ; No tools.logging support
:line line ; No tools.logging support
:level level
:error? (error-level? level)
:args log-vargs ; No tools.logging support
:throwable throwable
:message message}))
nil))
(defn logging-enabled? (defn logging-enabled?
"Returns true when current logging level is sufficient and current namespace "Returns true iff current logging level is sufficient and current namespace
is unfiltered." unfiltered."
[level] (and (sufficient-level? level) (@ns-filter-cache *ns*))) [level] (and (sufficient-level? level) (@ns-filter-cache *ns*)))
(defmacro log* (defmacro log* "Implementation detail - subject to change."
"Implementation detail - subject to change. [message-fn level base-appender-args & log-args]
Prepares given arguments for, and then dispatches to all level-relevant `(when (logging-enabled? ~level)
appender-fns. " (when-let [juxt-fn# (@appenders-juxt-cache ~level)]
(let [[x1# & xn# :as xs#] (vector ~@log-args)
has-throwable?# (instance? Throwable x1#)
log-vargs# (vec (if has-throwable?# xn# xs#))]
(send-to-appenders!
~level
~base-appender-args
log-vargs#
~(str *ns*)
(when has-throwable?# x1#)
(when-let [mf# ~message-fn]
(when-not (empty? log-vargs#)
(apply mf# log-vargs#)))
juxt-fn#
(let [file# ~*file*] (when (not= file# "NO_SOURCE_PATH") file#))
;; TODO Waiting on http://dev.clojure.org/jira/browse/CLJ-865:
~(:line (meta &form)))))))
;; For tools.logging.impl/Logger support (defmacro log "Logs using print-style args."
([base-appender-args level log-vargs ns throwable message juxt-fn]
`(when-let [juxt-fn# (or ~juxt-fn (@appenders-juxt-cache ~level))]
(juxt-fn#
(conj (or ~base-appender-args {})
{:instant (Date.)
:ns ~ns
:file ~*file*
;; :line ~(:line (meta &form))
:level ~level
:error? (error-level? ~level)
:args ~log-vargs ; No native tools.logging support
:throwable ~throwable
:message ~message}))
nil))
([base-appender-args level log-args message-fn]
`(when-let [juxt-fn# (@appenders-juxt-cache ~level)]
(let [[x1# & xn# :as xs#] (vector ~@log-args)
has-throwable?# (instance? Throwable x1#)
log-vargs# (vec (if has-throwable?# xn# xs#))]
(log* ~base-appender-args
~level
log-vargs#
~(str *ns*)
(when has-throwable?# x1#)
(when-let [mf# ~message-fn]
(when-not (empty? log-vargs#)
(apply mf# log-vargs#)))
juxt-fn#)))))
(defmacro log
"When logging is enabled, actually logs given arguments with level-relevant
appender-fns using print-style :message."
{:arglists '([level & message] [level throwable & message])} {:arglists '([level & message] [level throwable & message])}
[level & sigs] [level & sigs] `(log* print-str ~level {} ~@sigs))
`(when (logging-enabled? ~level)
(log* {} ~level ~sigs print-str)))
(defmacro logf (defmacro logf "Logs using format-style args."
"When logging is enabled, actually logs given arguments with level-relevant
appender-fns using format-style :message."
{:arglists '([level fmt & fmt-args] [level throwable fmt & fmt-args])} {:arglists '([level fmt & fmt-args] [level throwable fmt & fmt-args])}
[level & sigs] [level & sigs] `(log* format ~level {} ~@sigs))
`(when (logging-enabled? ~level)
(log* {} ~level ~sigs format)))
(defmacro log-errors [& body] `(try ~@body (catch Throwable t# (error t#)))) (defmacro log-errors [& body] `(try ~@body (catch Throwable t# (error t#))))
(defmacro log-and-rethrow-errors [& body] (defmacro log-and-rethrow-errors [& body]
@ -387,12 +380,12 @@
(let [level-name (name level)] (let [level-name (name level)]
`(do `(do
(defmacro ~(symbol level-name) (defmacro ~(symbol level-name)
~(str "Log given arguments at " level " level using print-style args.") ~(str "Logs at " level " level using print-style args.")
~'{:arglists '([& message] [throwable & message])} ~'{:arglists '([& message] [throwable & message])}
[& sigs#] `(log ~~level ~@sigs#)) [& sigs#] `(log ~~level ~@sigs#))
(defmacro ~(symbol (str level-name "f")) (defmacro ~(symbol (str level-name "f"))
~(str "Log given arguments at " level " level using format-style args.") ~(str "Logs at " level " level using format-style args.")
~'{:arglists '([fmt & fmt-args] [throwable fmt & fmt-args])} ~'{:arglists '([fmt & fmt-args] [throwable fmt & fmt-args])}
[& sigs#] `(logf ~~level ~@sigs#))))) [& sigs#] `(logf ~~level ~@sigs#)))))

View File

@ -28,11 +28,9 @@
(let [name (utils/fq-keyword name)] (let [name (utils/fq-keyword name)]
`(let [{result# :result stats# :stats} (with-fdata ~level ~@body)] `(let [{result# :result stats# :stats} (with-fdata ~level ~@body)]
(when stats# (when stats#
(timbre/log* {:frequency-stats stats#} (timbre/log* print-str ~level {:frequency-stats stats#}
~level (str "Frequencies " ~name)
[(str "Frequencies " ~name) (str "\n" (format-fdata stats#))))
(str "\n" (format-fdata stats#))]
print-str))
result#))) result#)))
(defmacro sampling-log-frequencies (defmacro sampling-log-frequencies

View File

@ -29,11 +29,9 @@
(let [name (utils/fq-keyword name)] (let [name (utils/fq-keyword name)]
`(let [{result# :result stats# :stats} (with-pdata ~level ~@body)] `(let [{result# :result stats# :stats} (with-pdata ~level ~@body)]
(when stats# (when stats#
(timbre/log* {:profile-stats stats#} (timbre/log* print-str ~level {:profile-stats stats#}
~level (str "Profiling " ~name)
[(str "Profiling " ~name) (str "\n" (format-pdata stats#))))
(str "\n" (format-pdata stats#))]
print-str))
result#))) result#)))
(defmacro sampling-profile (defmacro sampling-profile

View File

@ -11,8 +11,8 @@
;; `write!`, the best we can do is `[message]`. This inconsistency means ;; `write!`, the best we can do is `[message]`. This inconsistency means
;; that :args consumers (like the rate limiter and Postal appender) will ;; that :args consumers (like the rate limiter and Postal appender) will
;; necessarily behave differently under tools.logging. ;; necessarily behave differently under tools.logging.
(timbre/log* {} level [message] logger-ns throwable (timbre/send-to-appenders! level {} [message] logger-ns throwable
(when (string? message) message) nil))) (when (string? message) message))))
(deftype LoggerFactory [] (deftype LoggerFactory []
clojure.tools.logging.impl/LoggerFactory clojure.tools.logging.impl/LoggerFactory