Pure Clojure/Script logging library https://www.taoensso.com
Go to file
Peter Taoussanis d9a68f1e58 README tweaks. 2012-07-03 16:30:50 +07:00
src/taoensso Added ns filtering, `logging-enabled`. Misc housekeeping. 2012-07-03 16:29:11 +07:00
test/test_timbre BREAKING: New ns structure. 2012-07-03 16:27:20 +07:00
.gitignore A few minor superficial tweaks. 2012-06-12 22:02:24 +07:00
.travis.yml Allow Travis to test dev branches. 2012-07-03 16:24:29 +07:00
README.md README tweaks. 2012-07-03 16:30:50 +07:00
epl-v10.html 0.5.2 2012-07-01 18:08:45 +07:00
project.clj 0.5.2 2012-07-01 18:08:45 +07:00

README.md

NOTICE

The Timbre Clojars group was recently changed. Please update your project.clj to use:

[com.taoensso/timbre "{VERSION}"]

Timbre, a (sane) logging library for Clojure

Logging with Java can be maddeningly, unnecessarily hard. Particularly if all you want is something simple that works out the box.

tools.logging helps, but it doesn't save you from the mess of logger dependencies and configuration hell.

Timbre is an attempt to make simple logging simple and more complex logging possible.

What's In The Box?

  • Small, uncomplicated all-Clojure library.
  • Super-simple map-based config: no arcane XML or properties files.
  • Decent performance (low overhead).
  • Flexible fn-centric appender model.
  • Sensible built-in appenders including simple email appender.
  • Tunable flood control.
  • Asynchronous logging support.

Status Build Status

Tower is still currently experimental. It has not yet been thoroughly tested in production and its API is subject to change. To run tests against all supported Clojure versions, use:

lein2 all test

Getting Started

Leiningen

Depend on Timbre in your project.clj:

[com.taoensso/timbre "0.5.2"]

and use the library:

(ns my-app
  (:use [timbre.core :as timbre :only (trace debug info warn error fatal spy)])

Start Logging

By default, Timbre gives you basic print output to *out*/*err* at a debug logging level:

(info "This will print")
=> 2012-May-28 17:26:11:444 +0700 INFO [timbre.tests] - This will print

(trace "This won't print due to insufficient logging level")
=> nil

There's little overhead for checking logging levels:

(time (trace (Thread/sleep 5000)))
=> "Elapsed time: 0.054 msecs"

(time (when true))
=> "Elapsed time: 0.051 msecs"

First-argument exceptions generate a stack trace:

(info (Exception. "Oh noes") "arg1" "arg2")
=> 2012-May-28 17:35:16:132 +0700 INFO [timbre.tests] - arg1 arg2
java.lang.Exception: Oh noes
            NO_SOURCE_FILE:1 timbre.tests/eval6409
          Compiler.java:6511 clojure.lang.Compiler.eval
          [...]

Configuration

Configuring Timbre couldn't be simpler. Let's check out (some of) the defaults:

@timbre/config
=>
{:current-level :debug

 :ns-whitelist []
 :ns-blacklist []

 :appenders
 {:standard-out
  {:doc "Prints everything to *out*."
   :min-level nil :enabled? false :async? false
   :max-message-per-msecs nil
   :fn (fn [{:keys [more] :as args}]
         (apply timbre/str-println (timbre/prefixed-message args) more))}
  ;; ...
  }

 :shared-appender-config
 {:timestamp-pattern "yyyy-MMM-dd HH:mm:ss ZZ"
  :locale nil
  :postal nil}}

Easily adjust the current logging level:

(timbre/set-level! :warn)

And the default timestamp formatting for log messages:

(timbre/set-config! [:shared-appender-config :timestamp-pattern]
                    "yyyy-MMM-dd HH:mm:ss ZZ")
(timbre/set-config! [:shared-appender-config :locale]
                    (java.util.Locale/GERMAN))

Filter logging output by namespaces:

(timbre/set-config! [:ns-whitelist] ["some.library.core" "my-app.*"])

Enable the standard Postal-based email appender:

(timbre/set-config! [:shared-appender-config :postal]
                    ^{:host "mail.isp.net" :user "jsmith" :pass "sekrat!!1"}
                    {:from "me@draines.com" :to "foo@example.com"})

(timbre/set-config! [:appenders :postal :enabled?] true)

Rate-limit to one email per message per minute:

(timbre/set-config! [:appenders :postal :max-message-per-msecs] 60000)

And make sure emails are sent asynchronously:

(timbre/set-config! [:appenders :postal :async?] true)

Custom Appenders

Writing a custom appender is dead-easy:

(timbre/set-config!
 [:appenders :my-appender]
 {:doc       "Hello-world appender"
  :min-level :debug
  :enabled?  true
  :async?    false
  :max-message-per-msecs nil ; No rate limiting
  :fn (fn [{:keys [ap-config level error? instant timestamp
                  ns message more] :as args}]
        (when-not (:production-mode? ap-config)
          (apply println timestamp "Hello world!" message more)))

And because appender fns are just regular Clojure fns, you have unlimited power: write to your database, send a message over the network, check some other state (e.g. environment config) before making a choice, etc.

See (doc timbre/config) for more information on appenders.

Timbre Supports the ClojureWerkz Project Goals

ClojureWerkz is a growing collection of open-source, batteries-included Clojure libraries that emphasise modern targets, great documentation, and thorough testing.

Contact & Contribution

Reach me (Peter Taoussanis) at ptaoussanis at gmail.com for questions/comments/suggestions/whatever. I'm very open to ideas if you have any!

I'm also on Twitter: @ptaoussanis.

License

Copyright © 2012 Peter Taoussanis

Distributed under the Eclipse Public License, the same as Clojure.