Companion logging library for Cyrus Leiningen template.
WARNING! This library carries an opinion. It brings the following dependencies:
[cyrus/dovetail "0.3.0"]
All the examples bellow assume:
(require '[dovetail.core :as log])
Default behavior:
(timbre/infof "%s" (take 5 (range)))
INFO [nREPL-worker-42] d.c-test - clojure.lang.LazySeq@1b554e1
(timbre/infof "%s" "123")
INFO [nREPL-worker-42] d.c-test - 123
(timbre/infof "%s" 123)
INFO [nREPL-worker-42] d.c-test - 123
(timbre/infof "%s" "")
INFO [nREPL-worker-42] d.c-test -
(timbre/infof "%s" nil)
INFO [nREPL-worker-42] d.c-test - null
(timbre/infof "%5D")
CompilerException java.util.UnknownFormatConversionException: Conversion = 'D', compiling: ...
cyrus-logging behavior:
(log/info "%s" (take 5 (range)))
INFO [nREPL-worker-42] d.c-test - (0 1 2 3 4)
(log/info "%s" "123")
INFO [nREPL-worker-42] d.c-test - "123"
(log/info "%s" 123)
INFO [nREPL-worker-42] d.c-test - 123
(log/info "%s" "")
INFO [nREPL-worker-42] d.c-test - ""
(log/info "%s" nil)
INFO [nREPL-worker-42] d.c-test - nil
(log/info "%5D")
INFO [nREPL-worker-42] d.c-test - %5D
In the last example the string is not processed with formatting, because there are no further arguments. This also works when first argument is a Throwable:
(log/info (Exception. "error") "%5D")
INFO [nREPL-worker-42] d.c-test - %5D
clojure.core/eval core.clj: 3206
...
See Throwable as first argument for more details.
Encoding function can be replaced:
(log/set-%s-encoder! json/encode)
(log/info "%s" (take 5 (range)))
INFO [nREPL-worker-42] d.c-test - [0,1,2,3,4]
(log/info "%s" "123")
INFO [nREPL-worker-42] d.c-test - "123"
(log/info "%s" 123)
INFO [nREPL-worker-42] d.c-test - 123
(log/info "%s" "")
INFO [nREPL-worker-42] d.c-test - ""
(log/info "%s" nil)
INFO [nREPL-worker-42] d.c-test - null
(log/info "%s" {:foo "bar"})
INFO [nREPL-worker-42] d.c-test - {"foo":"bar"}
Default output function can be enabled as:
(log/set-output-fn! log/default-log-output-fn)
- no timestamp
- space-padded level
- context (if present)
- current thread name
- abbreviated namespace
- formatted message
- stacktrace of the throwable (if present)ย โ on a new line
(log/with-context "[GET /api/hello]"
(log/warn (Exception. "Not ready") "The data is %s" [1, 2, 3]))
WARN [nREPL-worker-42] [GET /api/hello] d.c-test - The data is [1 2 3]
clojure.core/eval core.clj: 3206
...
user/eval5574 REPL Input
...
dovetail.core-test/eval5578 core_test.clj: 109
java.lang.Exception: Not ready
Sometimes we need :info
logging level, but want to exclude some very chatty library from the output.
(log/set-level! :info)
(log/set-ns-log-levels!
{"chatty.library.*" :warn})
Or, we might want to enable our namespaces to output :debug
, but leave others at :info
:
(log/set-level! :debug)
(log/set-ns-log-levels!
{"our.app.*" :debug
:all :info})
In general, effective level is the higher of overall and per-namespace:
;; Equivalent to :info overall
(log/set-level! :debug)
(log/set-ns-log-levels!
{:all :info})
;; Same
(log/set-level! :info)
(log/set-ns-log-levels!
{:all :debug})
If a namespace matches several selectors, then the most specific one takes effect:
;; for our.app.ns effectibe level will be :info
(log/set-ns-log-levels!
{"our.app.*" :info
"our.*" :debug})
All helper functions (not only error
) support Throwable
as first argument:
(log/info (Exception. "HAHA") "Something bad happened")
INFO [nREPL-worker-42] d.c-test - Something bad happened
clojure.core/eval core.clj: 3206
...
user/eval15501 REPL Input
...
dovetail.core-test/eval15508 core_test.clj: 92
java.lang.Exception: HAHA
If your application supports setting log level via an environment variable,
it's better to be flexible and accept both LOG_LEVEL=debug
and LOG_LEVEL=DEBUG
.
cyrus-logging also includes set-level!
function, so that you don't have to explicitly require taoensso.timbre
namespace.
(defn -main [& args]
;; Default log level
(log/set-level! :info)
;; Will do nothing if LOG_LEVEL is not set
(log/set-log-level-from-env! (System/getenv "LOG_LEVEL"))
...)
Timbre includes pretty, which makes stacktraces look pretty colorful in the terminal. However, this might get in the way if you collect logs from the stdout and aggregate them for viewing later.
If you call disable-console-logging-colors
from -main
, it will only affect production runs, but will let you
enjoy colorful stacktraces when REPL-driven developing:
(defn -main [& args]
(log/disable-console-logging-colors)
...)
Copyright ยฉ 2017 Dmitrii Balakhonskii
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.