by Alex Miller
Use Timbre to configure your logger and add logging messages to your code.
Before starting, add [com.taoensso/timbre "2.7.1"]
to your project’s
dependencies or start a REPL using lein-try:
$ lein try com.taoensso/timbre
To write a function that writes log messages, use the Timbre functions info, error, etc:
(require '[taoensso.timbre :as log])
(defn div-4 [n]
(log/info "Starting")
(try
(/ 4 n)
(catch Throwable t
(log/error t "oh no!"))
(finally
(log/info "Ending"))))
The div-4 function takes a single argument and returns 4/n.
The log/info calls will create a log message output at the "info" level. Similarly, the log/error call will create a log message at the "error" output level. Passing an exception as the first argument will cause the stack trace to be printed as well.
If you call div-4 with values that will succeed or throw an error, you will see output like the following in your REPL:
(div-4 2)
;; -> 2
;; *out*
;; 2013-Nov-22 10:34:11 -0500 laptop INFO [user] - Starting
;; 2013-Nov-22 10:34:11 -0500 laptop INFO [user] - Ending
(div-4 0)
;; -> 2013-Nov-22 10:34:47 -0500 laptop ERROR [user] -
;; oh no! java.lang.ArithmeticException: Divide by zero
;; -> nil
;; *out*
;; 2013-Nov-22 10:34:21 -0500 laptop INFO [user] - Starting
;; 2013-Nov-22 10:34:21 -0500 laptop ERROR [user] -
;; oh no! java.lang.ArithmeticException: Divide by zero
;; ... Exception stacktrace
;; 2013-Nov-22 10:34:21 -0500 laptop INFO [user] - Ending
Timbre is a great way to get started with logging in your code. Using a log library allows you to specify later where the output will go, possibly to more than one location or filtered by namespace.
Timbre writes logs to any number of configured "appenders" (output destinations). By default, a single appender is configured to write to standard out.
For example, to add a second appender for a file, you can dynamically modify the configuration by enabling the preconfigured spit appender:
;; Turn it on
(log/set-config! [:appenders :spit :enabled?] true)
;; Set the log file location
(log/set-config! [:shared-appender-config :spit-filename] "out.log")
Note that the output file’s directory must exist and the user must be able to write to the file. Once this configuration has been completed, any log messages will be written to both the console and the file.
The available logging levels are :trace, :debug, :info, :warn, :error, and :fatal. The default log level is set to :debug, so all logging levels greater than or equal to :debug will be recorded (everything but :trace).
To change the logging level at runtime, change the configuration:
(log/set-level! :warn)
While Timbre is an excellent library for simple logging in your Clojure app, it may not be sufficient if you are integrating with many Java libraries. There are a variety of popular Java logging frameworks and logging facades. If you wish to leverage the existing Java logging infrastructure, you might find the tools.logging framework more suitable.