mirror of https://github.com/status-im/timbre.git
Final hk?
This commit is contained in:
parent
6ab9c4ac59
commit
7c969ca0e6
39
CHANGELOG.md
39
CHANGELOG.md
|
@ -1,5 +1,44 @@
|
||||||
> This project uses [Break Versioning](https://github.com/ptaoussanis/encore/blob/master/BREAK-VERSIONING.md) as of **Aug 16, 2014**.
|
> This project uses [Break Versioning](https://github.com/ptaoussanis/encore/blob/master/BREAK-VERSIONING.md) as of **Aug 16, 2014**.
|
||||||
|
|
||||||
|
## v4.0.0-beta1 / 2015 May 26
|
||||||
|
|
||||||
|
> This is a **MAJOR** update. Your custom appenders **WILL BREAK**. Your configuration **MIGHT BREAK**. Your call sites should be fine. I've updated all included appenders, but **haven't tested** any 3rd-party appenders.
|
||||||
|
|
||||||
|
* **New**: full **ClojureScript** support, including a default js/console appender [#51]
|
||||||
|
* **New**: support for compile-time ns filtering + elision (both Clj+Cljs)
|
||||||
|
* **New**: support for MDC-like contexts [#42]
|
||||||
|
* **New**: default :println appender has picked up a :stream opt [#49]
|
||||||
|
* **New**: create necessary spit appender paths [#93]
|
||||||
|
* **New**: full-power fn-level `log*` util [#99]
|
||||||
|
* **New**: added a reference appender example [here](https://github.com/ptaoussanis/timbre/blob/master/src/taoensso/timbre/appenders/example_appender.clj)
|
||||||
|
* **Implementation**: modernized + simplified codebase
|
||||||
|
* **Implementation**: significant performance improvements across the board
|
||||||
|
* **Implementation**: use delays to avoid unnecessarily producing unused arg msgs [#71]
|
||||||
|
* **Fix**: auto shutdown agents to prevent slow app shutdown [#61]
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
[com.taoensso/timbre "4.0.0-beta1"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Migration checklist
|
||||||
|
|
||||||
|
* Removed vars: `timbre/config`, `timbre/level-atom`, `default-fmt-output-fn`
|
||||||
|
* The fn signature for `set-config!` has changed: `[ks val]` -> `[config]`
|
||||||
|
* Middleware now apply left->right, not right->left
|
||||||
|
* Renamed default appender: `:standard-out` -> `:println`
|
||||||
|
* Renamed config opts: `:timestamp-pattern`, `:timestamp-locale` -> `:timestamp-opts {:pattern _ :locale _ :timezone _}`
|
||||||
|
* Appender :rate-limit format has changed: `[ncalls ms]` -> `[[ncalls ms] <...>]`
|
||||||
|
* Renamed appender args: `:ns`->`:?ns-str`, `:file`->`:?file`, `:line`->`:?line`
|
||||||
|
* Appender args now wrapped with delays: `:throwable`->`:?err_`, `:message`->`:msg_`, `:timestamp`->`:timestamp_`, `:hostname`->`:hostname_`, `:args`->`:vargs_`
|
||||||
|
* Appender args removed: `:output`, `:ap-config`
|
||||||
|
* Appender args added: `:output-fn (fn [data])`, `:appender-opts`
|
||||||
|
* `stacktrace` util fn signature changed: `[throwable & [sep fonts]` -> `[err & [opts]]`
|
||||||
|
* All bundles 3rd-party appenders have moved to a new `3rd-party` ns
|
||||||
|
|
||||||
|
Apologies for the hassle in migrating. The changes made here all bring serious benefits (performance, simplicity, future extensibility, cross-platform support) and I'm confident that v4's the last time I'll need to touch the core design. Future work will be focused on polish, stability, and better+more bundled appenders.
|
||||||
|
|
||||||
|
/ Peter Taoussanis
|
||||||
|
|
||||||
## v3.4.0 / 2015 Feb 16
|
## v3.4.0 / 2015 Feb 16
|
||||||
|
|
||||||
> This should be a **non-breaking** release that only bumps some old dependencies.
|
> This should be a **non-breaking** release that only bumps some old dependencies.
|
||||||
|
|
85
README.md
85
README.md
|
@ -133,79 +133,24 @@ This is the biggest win over Java logging IMO. Here's `timbre/example-config` (a
|
||||||
The `example-config` source code contains further settings and details.
|
The `example-config` source code contains further settings and details.
|
||||||
See also `set-config!`, `merge-config!`, `set-level!`."
|
See also `set-config!`, `merge-config!`, `set-level!`."
|
||||||
|
|
||||||
(merge
|
{:level :debug ; e/o #{:trace :debug :info :warn :error :fatal :report}
|
||||||
{:level :debug ; e/o #{:trace :debug :info :warn :error :fatal :report}
|
|
||||||
|
|
||||||
;; Control log filtering by namespaces/patterns. Useful for turning off
|
;; Control log filtering by namespaces/patterns. Useful for turning off
|
||||||
;; logging in noisy libraries, etc.:
|
;; logging in noisy libraries, etc.:
|
||||||
:whitelist [] #_["my-app.foo-ns"]
|
:whitelist [] #_["my-app.foo-ns"]
|
||||||
:blacklist [] #_["taoensso.*"]
|
:blacklist [] #_["taoensso.*"]
|
||||||
|
|
||||||
:middleware [] ; (fns [data]) -> ?data, applied left->right
|
:middleware [] ; (fns [data]) -> ?data, applied left->right
|
||||||
|
|
||||||
#+clj :timestamp-opts
|
:appenders
|
||||||
#+clj default-timestamp-opts ; {:pattern _ :locale _ :timezone _}
|
{:simple-println ; Appender id
|
||||||
|
;; Appender definition (just a map):
|
||||||
:output-fn default-output-fn ; (fn [data]) -> string
|
{:min-level nil :enabled? true :async? false
|
||||||
|
:rate-limit [[1 250] [10 5000]] ; 1/250ms, 10/5s
|
||||||
:appenders
|
:fn ; Appender's fn
|
||||||
#+clj
|
(fn [data]
|
||||||
{:println ; Appender id
|
(let [{:keys [output-fn]} data]
|
||||||
;; Appender <map>:
|
(println (output-fn data))))}}})
|
||||||
{:doc "Prints to (:stream <appender-opts>) IO stream. Enabled by default."
|
|
||||||
:min-level nil :enabled? true :async? false :rate-limit nil
|
|
||||||
|
|
||||||
;; Any custom appender opts:
|
|
||||||
:opts {:stream :auto ; e/o #{:std-err :std-out :auto <stream>}
|
|
||||||
}
|
|
||||||
|
|
||||||
:fn
|
|
||||||
(fn [data]
|
|
||||||
(let [{:keys [output-fn error? appender-opts]} data
|
|
||||||
{:keys [stream]} appender-opts
|
|
||||||
stream (case stream
|
|
||||||
(nil :auto) (if error? default-err *out*)
|
|
||||||
:std-err default-err
|
|
||||||
:std-out default-out
|
|
||||||
stream)]
|
|
||||||
(binding [*out* stream] (println (output-fn data)))))}
|
|
||||||
|
|
||||||
:spit
|
|
||||||
{:doc "Spits to (:spit-filename <appender-opts>) file."
|
|
||||||
:min-level nil :enabled? false :async? false :rate-limit nil
|
|
||||||
:opts {:spit-filename "timbre-spit.log"}
|
|
||||||
:fn
|
|
||||||
(fn [data]
|
|
||||||
(let [{:keys [output-fn appender-opts]} data
|
|
||||||
{:keys [spit-filename]} appender-opts]
|
|
||||||
(when-let [fname (enc/as-?nblank spit-filename)]
|
|
||||||
(try (ensure-spit-dir-exists! fname)
|
|
||||||
(spit fname (str (output-fn data) "\n") :append true)
|
|
||||||
(catch java.io.IOException _)))))}}
|
|
||||||
|
|
||||||
#+cljs
|
|
||||||
{:console
|
|
||||||
{:doc "Logs to js/console when it exists. Enabled by default."
|
|
||||||
:min-level nil :enabled? true :async? false :rate-limit nil
|
|
||||||
:opts {}
|
|
||||||
:fn
|
|
||||||
(let [have-logger? (and (exists? js/console) (.-log js/console))
|
|
||||||
have-warn-logger? (and have-logger? (.-warn js/console))
|
|
||||||
have-error-logger? (and have-logger? (.-error js/console))
|
|
||||||
adjust-level {:fatal (if have-error-logger? :error :info)
|
|
||||||
:error (if have-error-logger? :error :info)
|
|
||||||
:warn (if have-warn-logger? :warn :info)}]
|
|
||||||
(if-not have-logger?
|
|
||||||
(fn [data] nil)
|
|
||||||
(fn [data]
|
|
||||||
(let [{:keys [level appender-opts output-fn]} data
|
|
||||||
{:keys []} appender-opts
|
|
||||||
output (output-fn data)]
|
|
||||||
|
|
||||||
(case (adjust-level level)
|
|
||||||
:error (.error js/console output)
|
|
||||||
:warn (.warn js/console output)
|
|
||||||
(.log js/console output))))))}}}))
|
|
||||||
```
|
```
|
||||||
|
|
||||||
A few things to note:
|
A few things to note:
|
||||||
|
|
|
@ -12,11 +12,6 @@
|
||||||
[java.text SimpleDateFormat]
|
[java.text SimpleDateFormat]
|
||||||
[java.io File]))
|
[java.io File]))
|
||||||
|
|
||||||
;;;; TODO
|
|
||||||
;; - Try ease backward comp, update README, CHANGELOG
|
|
||||||
;; - Document shutdown-agents,
|
|
||||||
;; Ref. https://github.com/ptaoussanis/timbre/pull/100/files
|
|
||||||
|
|
||||||
;;;; Encore version check
|
;;;; Encore version check
|
||||||
|
|
||||||
#+clj
|
#+clj
|
||||||
|
@ -105,79 +100,78 @@
|
||||||
The `example-config` source code contains further settings and details.
|
The `example-config` source code contains further settings and details.
|
||||||
See also `set-config!`, `merge-config!`, `set-level!`."
|
See also `set-config!`, `merge-config!`, `set-level!`."
|
||||||
|
|
||||||
(merge
|
{:level :debug ; e/o #{:trace :debug :info :warn :error :fatal :report}
|
||||||
{:level :debug ; e/o #{:trace :debug :info :warn :error :fatal :report}
|
|
||||||
|
|
||||||
;; Control log filtering by namespaces/patterns. Useful for turning off
|
;; Control log filtering by namespaces/patterns. Useful for turning off
|
||||||
;; logging in noisy libraries, etc.:
|
;; logging in noisy libraries, etc.:
|
||||||
:whitelist [] #_["my-app.foo-ns"]
|
:whitelist [] #_["my-app.foo-ns"]
|
||||||
:blacklist [] #_["taoensso.*"]
|
:blacklist [] #_["taoensso.*"]
|
||||||
|
|
||||||
:middleware [] ; (fns [data]) -> ?data, applied left->right
|
:middleware [] ; (fns [data]) -> ?data, applied left->right
|
||||||
|
|
||||||
#+clj :timestamp-opts
|
#+clj :timestamp-opts
|
||||||
#+clj default-timestamp-opts ; {:pattern _ :locale _ :timezone _}
|
#+clj default-timestamp-opts ; {:pattern _ :locale _ :timezone _}
|
||||||
|
|
||||||
:output-fn default-output-fn ; (fn [data]) -> string
|
:output-fn default-output-fn ; (fn [data]) -> string
|
||||||
|
|
||||||
:appenders
|
:appenders
|
||||||
#+clj
|
#+clj
|
||||||
{:println ; Appender id
|
{:println ; Appender id
|
||||||
;; Appender <map>:
|
;; Appender map:
|
||||||
{:doc "Prints to (:stream <appender-opts>) IO stream. Enabled by default."
|
{:doc "Prints to (:stream <appender-opts>) IO stream. Enabled by default."
|
||||||
:min-level nil :enabled? true :async? false :rate-limit nil
|
:min-level nil :enabled? true :async? false :rate-limit nil
|
||||||
|
|
||||||
;; Any custom appender opts:
|
;; Any custom appender opts:
|
||||||
:opts {:stream :auto ; e/o #{:std-err :std-out :auto <stream>}
|
:opts {:stream :auto ; e/o #{:std-err :std-out :auto <stream>}
|
||||||
}
|
}
|
||||||
|
|
||||||
:fn
|
:fn
|
||||||
(fn [data]
|
(fn [data]
|
||||||
(let [{:keys [output-fn error? appender-opts]} data
|
(let [{:keys [output-fn error? appender-opts]} data
|
||||||
{:keys [stream]} appender-opts
|
{:keys [stream]} appender-opts
|
||||||
stream (case stream
|
stream (case stream
|
||||||
(nil :auto) (if error? default-err *out*)
|
(nil :auto) (if error? default-err *out*)
|
||||||
:std-err default-err
|
:std-err default-err
|
||||||
:std-out default-out
|
:std-out default-out
|
||||||
stream)]
|
stream)]
|
||||||
(binding [*out* stream] (println (output-fn data)))))}
|
(binding [*out* stream] (println (output-fn data)))))}
|
||||||
|
|
||||||
:spit
|
:spit
|
||||||
{:doc "Spits to (:spit-filename <appender-opts>) file."
|
{:doc "Spits to (:spit-filename <appender-opts>) file."
|
||||||
:min-level nil :enabled? false :async? false :rate-limit nil
|
:min-level nil :enabled? false :async? false :rate-limit nil
|
||||||
:opts {:spit-filename "timbre-spit.log"}
|
:opts {:spit-filename "timbre-spit.log"}
|
||||||
:fn
|
:fn
|
||||||
(fn [data]
|
(fn [data]
|
||||||
(let [{:keys [output-fn appender-opts]} data
|
(let [{:keys [output-fn appender-opts]} data
|
||||||
{:keys [spit-filename]} appender-opts]
|
{:keys [spit-filename]} appender-opts]
|
||||||
(when-let [fname (enc/as-?nblank spit-filename)]
|
(when-let [fname (enc/as-?nblank spit-filename)]
|
||||||
(try (ensure-spit-dir-exists! fname)
|
(try (ensure-spit-dir-exists! fname)
|
||||||
(spit fname (str (output-fn data) "\n") :append true)
|
(spit fname (str (output-fn data) "\n") :append true)
|
||||||
(catch java.io.IOException _)))))}}
|
(catch java.io.IOException _)))))}}
|
||||||
|
|
||||||
#+cljs
|
#+cljs
|
||||||
{:console
|
{:console
|
||||||
{:doc "Logs to js/console when it exists. Enabled by default."
|
{:doc "Logs to js/console when it exists. Enabled by default."
|
||||||
:min-level nil :enabled? true :async? false :rate-limit nil
|
:min-level nil :enabled? true :async? false :rate-limit nil
|
||||||
:opts {}
|
:opts {}
|
||||||
:fn
|
:fn
|
||||||
(let [have-logger? (and (exists? js/console) (.-log js/console))
|
(let [have-logger? (and (exists? js/console) (.-log js/console))
|
||||||
have-warn-logger? (and have-logger? (.-warn js/console))
|
have-warn-logger? (and have-logger? (.-warn js/console))
|
||||||
have-error-logger? (and have-logger? (.-error js/console))
|
have-error-logger? (and have-logger? (.-error js/console))
|
||||||
adjust-level {:fatal (if have-error-logger? :error :info)
|
adjust-level {:fatal (if have-error-logger? :error :info)
|
||||||
:error (if have-error-logger? :error :info)
|
:error (if have-error-logger? :error :info)
|
||||||
:warn (if have-warn-logger? :warn :info)}]
|
:warn (if have-warn-logger? :warn :info)}]
|
||||||
(if-not have-logger?
|
(if-not have-logger?
|
||||||
(fn [data] nil)
|
(fn [data] nil)
|
||||||
(fn [data]
|
(fn [data]
|
||||||
(let [{:keys [level appender-opts output-fn]} data
|
(let [{:keys [level appender-opts output-fn]} data
|
||||||
{:keys []} appender-opts
|
{:keys []} appender-opts
|
||||||
output (output-fn data)]
|
output (output-fn data)]
|
||||||
|
|
||||||
(case (adjust-level level)
|
(case (adjust-level level)
|
||||||
:error (.error js/console output)
|
:error (.error js/console output)
|
||||||
:warn (.warn js/console output)
|
:warn (.warn js/console output)
|
||||||
(.log js/console output))))))}}}))
|
(.log js/console output))))))}}})
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(set-config! example-config)
|
(set-config! example-config)
|
||||||
|
@ -195,8 +189,8 @@
|
||||||
(defn set-config! [m] (swap-config! (fn [_old] m)))
|
(defn set-config! [m] (swap-config! (fn [_old] m)))
|
||||||
(defn merge-config! [m] (swap-config! (fn [old] (enc/nested-merge old m))))
|
(defn merge-config! [m] (swap-config! (fn [old] (enc/nested-merge old m))))
|
||||||
|
|
||||||
(defn set-level! [level] (swap-config! (fn [m] (merge m {:level level}))))
|
(defn set-level! [level] (swap-config! (fn [m] (merge m {:level level}))))
|
||||||
(defn with-level [level & body]
|
(defmacro with-level [level & body]
|
||||||
`(binding [*config* (merge *config* {:level ~level})] ~@body))
|
`(binding [*config* (merge *config* {:level ~level})] ~@body))
|
||||||
|
|
||||||
(comment (set-level! :info) *config*)
|
(comment (set-level! :info) *config*)
|
||||||
|
@ -205,11 +199,11 @@
|
||||||
|
|
||||||
(def ordered-levels [:trace :debug :info :warn :error :fatal :report])
|
(def ordered-levels [:trace :debug :info :warn :error :fatal :report])
|
||||||
(def ^:private scored-levels (zipmap ordered-levels (next (range))))
|
(def ^:private scored-levels (zipmap ordered-levels (next (range))))
|
||||||
|
(def ^:private valid-levels (set ordered-levels))
|
||||||
(def ^:private valid-level
|
(def ^:private valid-level
|
||||||
(let [valid-level-set (set ordered-levels)]
|
(fn [level]
|
||||||
(fn [level]
|
(or (valid-levels level)
|
||||||
(or (valid-level-set level)
|
(throw (ex-info (str "Invalid logging level: " level) {:level level})))))
|
||||||
(throw (ex-info (str "Invalid logging level: " level) {:level level}))))))
|
|
||||||
|
|
||||||
(comment (valid-level :info))
|
(comment (valid-level :info))
|
||||||
|
|
||||||
|
@ -220,7 +214,9 @@
|
||||||
|
|
||||||
#+clj (defn- env-val [id] (when-let [s (System/getenv id)] (enc/read-edn s)))
|
#+clj (defn- env-val [id] (when-let [s (System/getenv id)] (enc/read-edn s)))
|
||||||
#+clj (def ^:private compile-time-level
|
#+clj (def ^:private compile-time-level
|
||||||
(have [:or nil? valid-level] (keyword (env-val "TIMBRE_LEVEL"))))
|
(have [:or nil? valid-level]
|
||||||
|
(keyword (or (env-val "TIMBRE_LEVEL")
|
||||||
|
(env-val "TIMBRE_LOG_LEVEL")))))
|
||||||
|
|
||||||
(defn get-active-level [& [config]] (or (:level (or config *config*)) :report))
|
(defn get-active-level [& [config]] (or (:level (or config *config*)) :report))
|
||||||
|
|
||||||
|
@ -307,7 +303,7 @@
|
||||||
|
|
||||||
(comment (def rf (get-rate-limiter :my-appender [[10 5000]])))
|
(comment (def rf (get-rate-limiter :my-appender [[10 5000]])))
|
||||||
|
|
||||||
;;;; Logging core
|
;;;; Internal logging core
|
||||||
|
|
||||||
(defn log?
|
(defn log?
|
||||||
"Would Timbre currently log at the given logging level?
|
"Would Timbre currently log at the given logging level?
|
||||||
|
@ -328,14 +324,15 @@
|
||||||
|
|
||||||
(declare get-hostname)
|
(declare get-hostname)
|
||||||
|
|
||||||
(defn log* "Core fn-level logger. Implementation detail."
|
(defn log1-fn
|
||||||
[config level ?ns-str ?file ?line msg-type vargs_ & [base-data]]
|
"Core fn-level logger. Implementation detail!"
|
||||||
|
[config level ?ns-str ?file ?line msg-type vargs_ & [?base-data]]
|
||||||
(when (log? level ?ns-str config)
|
(when (log? level ?ns-str config)
|
||||||
(let [instant (enc/now-dt)
|
(let [instant (enc/now-dt)
|
||||||
vargs*_ (delay (vsplit-err1 (force vargs_)))
|
vargs*_ (delay (vsplit-err1 (force vargs_)))
|
||||||
?err_ (delay (get @vargs*_ 0))
|
?err_ (delay (get @vargs*_ 0))
|
||||||
vargs_ (delay (get @vargs*_ 1))
|
vargs_ (delay (get @vargs*_ 1))
|
||||||
data (merge base-data *context*
|
data (merge ?base-data *context*
|
||||||
{:config config ; Entire config!
|
{:config config ; Entire config!
|
||||||
;; :context *context* ; Extra destructure's a nuisance
|
;; :context *context* ; Extra destructure's a nuisance
|
||||||
:instant instant
|
:instant instant
|
||||||
|
@ -352,9 +349,9 @@
|
||||||
(when-not (nil? msg-type)
|
(when-not (nil? msg-type)
|
||||||
(when-let [vargs (have [:or nil? vector?] (force vargs_))]
|
(when-let [vargs (have [:or nil? vector?] (force vargs_))]
|
||||||
(case msg-type
|
(case msg-type
|
||||||
:print (enc/spaced-str vargs)
|
:p (enc/spaced-str vargs)
|
||||||
:format (let [[fmt args] (enc/vsplit-first vargs)]
|
:f (let [[fmt args] (enc/vsplit-first vargs)]
|
||||||
(enc/format* fmt args))))))
|
(enc/format* fmt args))))))
|
||||||
?data
|
?data
|
||||||
(reduce ; Apply middleware: data->?data
|
(reduce ; Apply middleware: data->?data
|
||||||
(fn [acc mf]
|
(fn [acc mf]
|
||||||
|
@ -418,41 +415,49 @@
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(log* *config* :info nil nil nil :print (delay [(do (println "hi") :x) :y])))
|
(log1-fn *config* :info nil nil nil :p (delay [(do (println "hi") :x) :y]) nil))
|
||||||
|
|
||||||
;;;; Logging macros
|
(defmacro log1-macro
|
||||||
|
"Core macro-level logger. Implementation detail!"
|
||||||
(defmacro log "Core macro-level logger."
|
[config level msg-type args & [?base-data]]
|
||||||
[config level msg-type args & [base-data]]
|
|
||||||
|
|
||||||
;; Compile-time elision:
|
;; Compile-time elision:
|
||||||
(when (or (nil? compile-time-level) (level>= level compile-time-level))
|
(when (or (nil? compile-time-level)
|
||||||
|
(not (valid-levels level)) ; Not a compile-time level
|
||||||
|
(level>= level compile-time-level))
|
||||||
|
|
||||||
(when (compile-time-ns-filter (str *ns*))
|
(when (compile-time-ns-filter (str *ns*))
|
||||||
|
|
||||||
(let [ns-str (str *ns*)
|
(let [ns-str (str *ns*)
|
||||||
?file (let [f *file*] (when (not= f "NO_SOURCE_PATH") f))
|
?file (let [f *file*] (when (not= f "NO_SOURCE_PATH") f))
|
||||||
;; TODO Waiting on http://dev.clojure.org/jira/browse/CLJ-865:
|
;; TODO Waiting on http://dev.clojure.org/jira/browse/CLJ-865:
|
||||||
?line (:line (meta &form))]
|
?line (:line (meta &form))]
|
||||||
`(log* ~config ~level ~ns-str ~?file ~?line ~msg-type
|
`(log1-fn ~config ~level ~ns-str ~?file ~?line ~msg-type
|
||||||
(delay [~@args]) ~base-data)))))
|
(delay [~@args]) ~?base-data)))))
|
||||||
|
|
||||||
|
;;;; API-level stuff
|
||||||
|
|
||||||
;;; Log using print-style args
|
;;; Log using print-style args
|
||||||
(defmacro trace [& args] `(log *config* :trace :print ~args))
|
(defmacro log* [config level & args] `(log1-macro ~config ~level :p ~args))
|
||||||
(defmacro debug [& args] `(log *config* :debug :print ~args))
|
(defmacro log [level & args] `(log1-macro *config* ~level :p ~args))
|
||||||
(defmacro info [& args] `(log *config* :info :print ~args))
|
(defmacro trace [& args] `(log1-macro *config* :trace :p ~args))
|
||||||
(defmacro warn [& args] `(log *config* :warn :print ~args))
|
(defmacro debug [& args] `(log1-macro *config* :debug :p ~args))
|
||||||
(defmacro error [& args] `(log *config* :error :print ~args))
|
(defmacro info [& args] `(log1-macro *config* :info :p ~args))
|
||||||
(defmacro fatal [& args] `(log *config* :fatal :print ~args))
|
(defmacro warn [& args] `(log1-macro *config* :warn :p ~args))
|
||||||
(defmacro report [& args] `(log *config* :report :print ~args))
|
(defmacro error [& args] `(log1-macro *config* :error :p ~args))
|
||||||
|
(defmacro fatal [& args] `(log1-macro *config* :fatal :p ~args))
|
||||||
|
(defmacro report [& args] `(log1-macro *config* :report :p ~args))
|
||||||
|
|
||||||
;;; Log using format-style args
|
;;; Log using format-style args
|
||||||
(defmacro tracef [& args] `(log *config* :trace :format ~args))
|
(defmacro logf* [config level & args] `(log1-macro ~config ~level :f ~args))
|
||||||
(defmacro debugf [& args] `(log *config* :debug :format ~args))
|
(defmacro logf [level & args] `(log1-macro *config* ~level :f ~args))
|
||||||
(defmacro infof [& args] `(log *config* :info :format ~args))
|
(defmacro tracef [& args] `(log1-macro *config* :trace :f ~args))
|
||||||
(defmacro warnf [& args] `(log *config* :warn :format ~args))
|
(defmacro debugf [& args] `(log1-macro *config* :debug :f ~args))
|
||||||
(defmacro errorf [& args] `(log *config* :error :format ~args))
|
(defmacro infof [& args] `(log1-macro *config* :info :f ~args))
|
||||||
(defmacro fatalf [& args] `(log *config* :fatal :format ~args))
|
(defmacro warnf [& args] `(log1-macro *config* :warn :f ~args))
|
||||||
(defmacro reportf [& args] `(log *config* :report :format ~args))
|
(defmacro errorf [& args] `(log1-macro *config* :error :f ~args))
|
||||||
|
(defmacro fatalf [& args] `(log1-macro *config* :fatal :f ~args))
|
||||||
|
(defmacro reportf [& args] `(log1-macro *config* :report :f ~args))
|
||||||
|
|
||||||
(comment
|
(comment
|
||||||
(infof "hello %s" "world")
|
(infof "hello %s" "world")
|
||||||
|
@ -485,7 +490,7 @@
|
||||||
([config level name expr]
|
([config level name expr]
|
||||||
`(log-and-rethrow-errors
|
`(log-and-rethrow-errors
|
||||||
(let [result# ~expr]
|
(let [result# ~expr]
|
||||||
(log ~config ~level :print [~name "=>" result#])
|
(log* ~config ~level [~name "=>" result#])
|
||||||
result#))))
|
result#))))
|
||||||
|
|
||||||
#+clj
|
#+clj
|
||||||
|
@ -540,7 +545,7 @@
|
||||||
(binding [aviso-ex/*fonts* fonts] (aviso-ex/format-exception err))
|
(binding [aviso-ex/*fonts* fonts] (aviso-ex/format-exception err))
|
||||||
(aviso-ex/format-exception err)))
|
(aviso-ex/format-exception err)))
|
||||||
|
|
||||||
(comment (stacktrace (Exception. "Boo")))
|
(comment (stacktrace (Exception. "Boo") {:stacktrace-fonts {}}))
|
||||||
|
|
||||||
#+clj
|
#+clj
|
||||||
(def ^:private ensure-spit-dir-exists!
|
(def ^:private ensure-spit-dir-exists!
|
||||||
|
@ -556,9 +561,17 @@
|
||||||
`(do (assert (<= 0 ~probability 1) "Probability: 0 <= p <= 1")
|
`(do (assert (<= 0 ~probability 1) "Probability: 0 <= p <= 1")
|
||||||
(when (< (rand) ~probability) ~@body)))
|
(when (< (rand) ~probability) ~@body)))
|
||||||
|
|
||||||
;;;; Shutdown hook ; Workaround for http://dev.clojure.org/jira/browse/CLJ-124
|
;;;; EXPERIMENTAL shutdown hook
|
||||||
|
;; Workaround for http://dev.clojure.org/jira/browse/CLJ-124
|
||||||
|
|
||||||
#+clj
|
#+clj
|
||||||
(defonce ^:private shutdown-hook
|
(defonce ^:private shutdown-hook
|
||||||
(.addShutdownHook (Runtime/getRuntime)
|
(.addShutdownHook (Runtime/getRuntime)
|
||||||
(Thread. (fn [] (shutdown-agents)))))
|
(Thread. (fn [] (shutdown-agents)))))
|
||||||
|
|
||||||
|
;;;; Deprecated
|
||||||
|
|
||||||
|
(defn str-println [& xs] (enc/spaced-str xs))
|
||||||
|
(defmacro with-log-level [level & body] `(with-level ~level ~@body))
|
||||||
|
(defmacro with-logging-config [config & body] `(with-config ~config ~@body))
|
||||||
|
(defn logging-enabled? [level compile-time-ns] (log? level (str compile-time-ns)))
|
||||||
|
|
|
@ -42,3 +42,7 @@
|
||||||
:error (android.util.Log/e ns output)
|
:error (android.util.Log/e ns output)
|
||||||
:fatal (android.util.Log/e ns output)
|
:fatal (android.util.Log/e ns output)
|
||||||
:report (android.util.Log/i ns output)))))})))
|
:report (android.util.Log/i ns output)))))})))
|
||||||
|
|
||||||
|
;;;; Deprecated
|
||||||
|
|
||||||
|
(def make-logcat-appender make-appender)
|
||||||
|
|
|
@ -73,3 +73,7 @@
|
||||||
:name "Lazylus Logus"
|
:name "Lazylus Logus"
|
||||||
:chan "bob"}}}})
|
:chan "bob"}}}})
|
||||||
(timbre/error "A multiple\nline message\nfor you"))
|
(timbre/error "A multiple\nline message\nfor you"))
|
||||||
|
|
||||||
|
;;;; Deprecated
|
||||||
|
|
||||||
|
(def make-irc-appender make-appender)
|
||||||
|
|
|
@ -73,3 +73,7 @@
|
||||||
(let [default-appender-config {:enabled? true :min-level nil}]
|
(let [default-appender-config {:enabled? true :min-level nil}]
|
||||||
(merge default-appender-config appender-config
|
(merge default-appender-config appender-config
|
||||||
{:fn (make-appender-fn path pattern)})))
|
{:fn (make-appender-fn path pattern)})))
|
||||||
|
|
||||||
|
;;;; Deprecated
|
||||||
|
|
||||||
|
(def make-rolling-appender make-appender)
|
||||||
|
|
|
@ -35,3 +35,7 @@
|
||||||
(zmq/register socket :pollout :pollerr))]
|
(zmq/register socket :pollout :pollerr))]
|
||||||
(merge default-appender-config appender-config
|
(merge default-appender-config appender-config
|
||||||
{:fn (make-appender-fn socket poller)})))
|
{:fn (make-appender-fn socket poller)})))
|
||||||
|
|
||||||
|
;;;; Deprecated
|
||||||
|
|
||||||
|
(def make-zmq-appender make-appender)
|
||||||
|
|
|
@ -144,3 +144,7 @@
|
||||||
|
|
||||||
(count (query-entries {} :info 2))
|
(count (query-entries {} :info 2))
|
||||||
(count (query-entries {} :info 2 :asc)))
|
(count (query-entries {} :info 2 :asc)))
|
||||||
|
|
||||||
|
;;;; Deprecated
|
||||||
|
|
||||||
|
(def make-carmine-appender make-appender)
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
[taoensso.timbre :as timbre]
|
[taoensso.timbre :as timbre]
|
||||||
[taoensso.encore :as enc :refer (have have?)]))
|
[taoensso.encore :as enc :refer (have have?)]))
|
||||||
|
|
||||||
(defn make-postal-appender
|
(defn make-appender
|
||||||
"Returns a Postal email appender.
|
"Returns a Postal email appender.
|
||||||
A Postal config map can be provided here as an argument, or as a :postal key
|
A Postal config map can be provided here as an argument, or as a :postal key
|
||||||
in :shared-appender-config.
|
in :shared-appender-config.
|
||||||
|
@ -44,3 +44,7 @@
|
||||||
(str/replace #"\s+" " ")
|
(str/replace #"\s+" " ")
|
||||||
(enc/substr 0 subject-len))
|
(enc/substr 0 subject-len))
|
||||||
:body (body-fn output)))))))})))
|
:body (body-fn output)))))))})))
|
||||||
|
|
||||||
|
;;;; Deprecated
|
||||||
|
|
||||||
|
(def make-postal-appender make-appender)
|
||||||
|
|
|
@ -78,7 +78,7 @@
|
||||||
[level id & body]
|
[level id & body]
|
||||||
`(let [{result# :result stats# :stats} (with-pdata ~level ~@body)]
|
`(let [{result# :result stats# :stats} (with-pdata ~level ~@body)]
|
||||||
(when stats#
|
(when stats#
|
||||||
(timbre/log timbre/*config* ~level :format
|
(timbre/log1-macro timbre/*config* ~level :f
|
||||||
["Profiling: %s\n%s" (fq-keyword ~id) (format-stats stats#)]
|
["Profiling: %s\n%s" (fq-keyword ~id) (format-stats stats#)]
|
||||||
{:profile-stats stats#}))
|
{:profile-stats stats#}))
|
||||||
result#))
|
result#))
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
?ns-str nil ; No support
|
?ns-str nil ; No support
|
||||||
?file nil ; ''
|
?file nil ; ''
|
||||||
?line nil ; ''
|
?line nil ; ''
|
||||||
msg-type :print ; No support for pre-msg raw args
|
msg-type :p ; No support for pre-msg raw args
|
||||||
]
|
]
|
||||||
(timbre/log* config level ?ns-str ?file ?line msg-type [message]))))
|
(timbre/log1-fn config level ?ns-str ?file ?line msg-type [message]))))
|
||||||
|
|
||||||
(deftype LoggerFactory []
|
(deftype LoggerFactory []
|
||||||
clojure.tools.logging.impl/LoggerFactory
|
clojure.tools.logging.impl/LoggerFactory
|
||||||
|
|
Loading…
Reference in New Issue