2012-06-29 14:13:28 +07:00
# NOTICE
The Timbre Clojars group was recently changed. Please update your `project.clj` to use:
```clojure
[com.taoensso/timbre "{VERSION}"]
```
2012-05-28 18:22:23 +07:00
# Timbre, a (sane) logging library for Clojure
2012-05-27 23:22:02 -07:00
2012-05-28 15:13:11 +07:00
Logging with Java can be maddeningly, unnecessarily hard. Particularly if all you want is something *simple that works out the box* .
[tools.logging ](https://github.com/clojure/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.
2012-05-30 16:15:15 +07:00
* **Super-simple map-based config**: no arcane XML or properties files.
2012-05-28 15:13:11 +07:00
* Decent performance (**low overhead**).
* Flexible **fn-centric appender model** .
* Sensible built-in appenders including simple **email appender** .
* Tunable **flood control** .
* **Asynchronous** logging support.
2012-07-03 16:30:50 +07:00
## Status [](http://travis-ci.org/ptaoussanis/timbre)
2012-05-28 15:13:11 +07:00
2012-07-03 16:30:50 +07:00
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:
```bash
lein2 all test
```
2012-05-28 15:13:11 +07:00
## Getting Started
### Leiningen
2012-06-29 14:13:28 +07:00
Depend on Timbre in your `project.clj` :
```clojure
2012-07-01 18:08:56 +07:00
[com.taoensso/timbre "0.5.2"]
2012-06-29 14:13:28 +07:00
```
2012-07-03 16:30:50 +07:00
and `use` the library:
2012-05-28 15:13:11 +07:00
```clojure
(ns my-app
(:use [timbre.core :as timbre :only (trace debug info warn error fatal spy)])
```
### Start Logging
2012-05-28 17:49:54 +07:00
By default, Timbre gives you basic print output to `*out*` /`*err*` at a `debug` logging level:
```clojure
2012-05-28 17:57:23 +07:00
(info "This will print")
2012-05-28 18:22:23 +07:00
=> 2012-May-28 17:26:11:444 +0700 INFO [timbre.tests] - This will print
2012-05-28 17:49:54 +07:00
(trace "This won't print due to insufficient logging level")
=> nil
```
There's little overhead for checking logging levels:
```clojure
(time (trace (Thread/sleep 5000)))
=> "Elapsed time: 0.054 msecs"
(time (when true))
=> "Elapsed time: 0.051 msecs"
```
2012-05-28 17:57:23 +07:00
First-argument exceptions generate a stack trace:
2012-05-28 17:49:54 +07:00
```clojure
(info (Exception. "Oh noes") "arg1" "arg2")
2012-05-28 18:22:23 +07:00
=> 2012-May-28 17:35:16:132 +0700 INFO [timbre.tests] - arg1 arg2
2012-05-28 17:49:54 +07:00
java.lang.Exception: Oh noes
2012-05-28 18:22:23 +07:00
NO_SOURCE_FILE:1 timbre.tests/eval6409
2012-05-28 17:49:54 +07:00
Compiler.java:6511 clojure.lang.Compiler.eval
[...]
```
2012-05-28 15:13:11 +07:00
### Configuration
2012-07-03 16:30:50 +07:00
Configuring Timbre couldn't be simpler. Let's check out (some of) the defaults:
```clojure
@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}}
```
2012-05-28 17:49:54 +07:00
Easily adjust the current logging level:
```clojure
2012-05-28 20:17:38 +07:00
(timbre/set-level! :warn)
2012-05-28 17:49:54 +07:00
```
2012-05-30 20:07:34 +07:00
And the default timestamp formatting for log messages:
2012-05-30 16:15:15 +07:00
```clojure
2012-05-30 20:07:34 +07:00
(timbre/set-config! [:shared-appender-config :timestamp-pattern]
2012-05-30 16:15:15 +07:00
"yyyy-MMM-dd HH:mm:ss ZZ")
(timbre/set-config! [:shared-appender-config :locale]
(java.util.Locale/GERMAN))
```
2012-07-03 16:30:50 +07:00
Filter logging output by namespaces:
```clojure
(timbre/set-config! [:ns-whitelist] ["some.library.core" "my-app.*"])
```
2012-05-28 17:57:23 +07:00
Enable the standard [Postal ](https://github.com/drewr/postal )-based email appender:
2012-05-28 17:49:54 +07:00
```clojure
2012-05-28 20:17:38 +07:00
(timbre/set-config! [:shared-appender-config :postal]
^{:host "mail.isp.net" :user "jsmith" :pass "sekrat!!1"}
{:from "me@draines .com" :to "foo@example .com"})
2012-05-28 17:49:54 +07:00
2012-05-28 20:17:38 +07:00
(timbre/set-config! [:appenders :postal :enabled?] true)
2012-05-28 17:49:54 +07:00
```
2012-05-28 18:22:23 +07:00
Rate-limit to one email per message per minute:
2012-05-28 17:49:54 +07:00
```clojure
2012-05-28 20:25:25 +07:00
(timbre/set-config! [:appenders :postal :max-message-per-msecs] 60000)
2012-05-28 17:49:54 +07:00
```
And make sure emails are sent asynchronously:
```clojure
2012-05-28 20:17:38 +07:00
(timbre/set-config! [:appenders :postal :async?] true)
2012-05-28 17:49:54 +07:00
```
### Custom Appenders
2012-07-03 16:30:50 +07:00
Writing a custom appender is dead-easy:
2012-05-28 17:49:54 +07:00
```clojure
2012-05-28 20:17:38 +07:00
(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
2012-05-31 00:05:36 +07:00
:fn (fn [{:keys [ap-config level error? instant timestamp
2012-05-30 16:15:15 +07:00
ns message more] :as args}]
2012-05-30 13:47:53 +07:00
(when-not (:production-mode? ap-config)
2012-05-31 00:05:36 +07:00
(apply println timestamp "Hello world!" message more)))
2012-05-28 17:49:54 +07:00
```
2012-05-30 13:47:53 +07:00
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.
2012-05-28 17:49:54 +07:00
See `(doc timbre/config)` for more information on appenders.
2012-05-28 15:13:11 +07:00
2012-06-16 13:53:38 +07:00
## Timbre Supports the ClojureWerkz Project Goals
2012-06-20 17:53:06 +07:00
ClojureWerkz is a growing collection of open-source, batteries-included [Clojure libraries ](http://clojurewerkz.org/ ) that emphasise modern targets, great documentation, and thorough testing.
2012-06-16 13:53:38 +07:00
2012-05-28 15:13:11 +07:00
## Contact & Contribution
2012-05-30 12:52:09 +07:00
Reach me (Peter Taoussanis) at *ptaoussanis at gmail.com* for questions/comments/suggestions/whatever. I'm very open to ideas if you have any!
2012-05-28 17:57:23 +07:00
I'm also on Twitter: [@ptaoussanis ](https://twitter.com/#!/ptaoussanis ).
2012-05-28 15:13:11 +07:00
## License
2012-06-12 22:02:24 +07:00
Copyright © 2012 Peter Taoussanis
2012-06-16 22:37:51 +07:00
Distributed under the [Eclipse Public License ](http://www.eclipse.org/legal/epl-v10.html ), the same as Clojure.