Merge branch 'dev'

This commit is contained in:
Peter Taoussanis 2012-10-19 15:43:23 +07:00
commit 64693828b8
4 changed files with 46 additions and 12 deletions

View File

@ -1,7 +1,7 @@
Current [semantic](http://semver.org/) version: Current [semantic](http://semver.org/) version:
```clojure ```clojure
[com.taoensso/timbre "0.8.1"] [com.taoensso/timbre "0.8.2"]
``` ```
**Breaking changes** since _0.7.x_: **Breaking changes** since _0.7.x_:
@ -45,14 +45,13 @@ lein2 all test
Depend on Timbre in your `project.clj`: Depend on Timbre in your `project.clj`:
```clojure ```clojure
[com.taoensso/timbre "0.8.1"] [com.taoensso/timbre "0.8.2"]
``` ```
and `use` the library: and `use` the library:
```clojure ```clojure
(ns my-app (ns my-app (:use [taoensso.timbre :as timbre :only (trace debug info warn error fatal spy)]))
(:use [taoensso.timbre :as timbre :only (trace debug info warn error fatal spy)]))
``` ```
### Start Logging ### Start Logging
@ -110,6 +109,7 @@ Configuring Timbre couldn't be simpler. Let's check out (some of) the defaults:
:appenders :appenders
{:standard-out { <...> } {:standard-out { <...> }
:spit { <...> }
<...> } <...> }
:shared-appender-config {}} :shared-appender-config {}}

View File

@ -1,4 +1,4 @@
(defproject com.taoensso/timbre "0.8.1" (defproject com.taoensso/timbre "0.8.2"
:description "Simple, flexible, all-Clojure logging. No XML!" :description "Simple, flexible, all-Clojure logging. No XML!"
:url "https://github.com/ptaoussanis/timbre" :url "https://github.com/ptaoussanis/timbre"
:license {:name "Eclipse Public License"} :license {:name "Eclipse Public License"}

View File

@ -32,7 +32,8 @@
Other keys include: :instant, :timestamp, :hostname, :ns, :error? Other keys include: :instant, :timestamp, :hostname, :ns, :error?
See source code for examples."} See source code for examples and `utils/deep-merge` for a convenient way
to reconfigure appenders."}
(atom {:current-level :debug (atom {:current-level :debug
;;; Control log filtering by namespace patterns (e.g. ["my-app.*"]). ;;; Control log filtering by namespace patterns (e.g. ["my-app.*"]).
@ -60,7 +61,19 @@
:max-message-per-msecs nil :max-message-per-msecs nil
:fn (fn [{:keys [error? prefix message more]}] :fn (fn [{:keys [error? prefix message more]}]
(binding [*out* (if error? *err* *out*)] (binding [*out* (if error? *err* *out*)]
(apply str-println prefix "-" message more)))}}})) (apply str-println prefix "-" message more)))}
:spit
{:doc "Spits to (:spit-filename :shared-appender-config) file."
:min-level nil :enabled? false :async? false
:max-message-per-msecs nil
:fn (fn [{:keys [ap-config prefix message more]}]
(when-let [filename (:spit-filename ap-config)]
(try (spit filename
(with-out-str (apply str-println prefix "-"
message more))
:append true)
(catch java.io.IOException _))))}}}))
(defn set-config! [[k & ks] val] (swap! config assoc-in (cons k ks) val)) (defn set-config! [[k & ks] val] (swap! config assoc-in (cons k ks) val))
(defn set-level! [level] (set-config! [:current-level] level)) (defn set-level! [level] (set-config! [:current-level] level))
@ -104,8 +117,9 @@
[{apfn :fn :keys [async? max-message-per-msecs] :as appender}] [{apfn :fn :keys [async? max-message-per-msecs] :as appender}]
(-> (->
;; Wrap to add compile-time stuff to runtime appender arguments ;; Wrap to add compile-time stuff to runtime appender arguments
(let [{:keys [timestamp-pattern timestamp-locale prefix-fn] :as ap-config} (let [{ap-config :shared-appender-config
@config :keys [timestamp-pattern timestamp-locale prefix-fn]} @config
timestamp-fn (make-timestamp-fn timestamp-pattern timestamp-locale)] timestamp-fn (make-timestamp-fn timestamp-pattern timestamp-locale)]
(fn [{:keys [instant] :as apfn-args}] (fn [{:keys [instant] :as apfn-args}]
@ -186,7 +200,7 @@
(apply juxt)))))))) (apply juxt))))))))
(reset! appenders-juxt-cache))) (reset! appenders-juxt-cache)))
;;; Namespace filter ;;; Namespace filter ; TODO Generalize to arbitrary fn filters?
(def ns-filter-cache "@ns-filter-cache => (fn relevant-ns? [ns] ...)" (def ns-filter-cache "@ns-filter-cache => (fn relevant-ns? [ns] ...)"
(atom (constantly true))) (atom (constantly true)))

View File

@ -15,3 +15,23 @@
(let [d-result (delay (apply f args))] (let [d-result (delay (apply f args))]
(swap! cache assoc args {:time-cached now :d-result d-result}) (swap! cache assoc args {:time-cached now :d-result d-result})
@d-result)))))) @d-result))))))
(defn deep-merge-with ; From clojure.contrib.map-utils
"Like `merge-with` but merges maps recursively, applying the given fn
only when there's a non-map at a particular level.
(deepmerge-with + {:a {:b {:c 1 :d {:x 1 :y 2}} :e 3} :f 4}
{:a {:b {:c 2 :d {:z 9} :z 3} :e 100}})
=> {:a {:b {:z 3, :c 3, :d {:z 9, :x 1, :y 2}}, :e 103}, :f 4}"
[f & maps]
(apply
(fn m [& maps]
(if (every? map? maps)
(apply merge-with m maps)
(apply f maps)))
maps))
(defn deep-merge
"Partial of `deep-merge-with`."
[& maps]
(apply deep-merge-with (fn [x y] y) maps))