Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'dev'

  • Loading branch information...
commit 64693828b858b7b46468896aa7bd21fb85c1fa21 2 parents d28429f + 734d598
@ptaoussanis authored
View
8 README.md
@@ -1,7 +1,7 @@
Current [semantic](http://semver.org/) version:
```clojure
-[com.taoensso/timbre "0.8.1"]
+[com.taoensso/timbre "0.8.2"]
```
**Breaking changes** since _0.7.x_:
@@ -45,14 +45,13 @@ lein2 all test
Depend on Timbre in your `project.clj`:
```clojure
-[com.taoensso/timbre "0.8.1"]
+[com.taoensso/timbre "0.8.2"]
```
and `use` the library:
```clojure
-(ns my-app
- (:use [taoensso.timbre :as timbre :only (trace debug info warn error fatal spy)]))
+(ns my-app (:use [taoensso.timbre :as timbre :only (trace debug info warn error fatal spy)]))
```
### Start Logging
@@ -110,6 +109,7 @@ Configuring Timbre couldn't be simpler. Let's check out (some of) the defaults:
:appenders
{:standard-out { <...> }
+ :spit { <...> }
<...> }
:shared-appender-config {}}
View
2  project.clj
@@ -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!"
:url "https://github.com/ptaoussanis/timbre"
:license {:name "Eclipse Public License"}
View
26 src/taoensso/timbre.clj
@@ -32,7 +32,8 @@
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
;;; Control log filtering by namespace patterns (e.g. ["my-app.*"]).
@@ -60,7 +61,19 @@
:max-message-per-msecs nil
:fn (fn [{:keys [error? prefix message more]}]
(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-level! [level] (set-config! [:current-level] level))
@@ -104,9 +117,10 @@
[{apfn :fn :keys [async? max-message-per-msecs] :as appender}]
(->
;; Wrap to add compile-time stuff to runtime appender arguments
- (let [{:keys [timestamp-pattern timestamp-locale prefix-fn] :as ap-config}
- @config
- timestamp-fn (make-timestamp-fn timestamp-pattern timestamp-locale)]
+ (let [{ap-config :shared-appender-config
+ :keys [timestamp-pattern timestamp-locale prefix-fn]} @config
+
+ timestamp-fn (make-timestamp-fn timestamp-pattern timestamp-locale)]
(fn [{:keys [instant] :as apfn-args}]
(let [apfn-args (merge apfn-args {:ap-config ap-config
@@ -186,7 +200,7 @@
(apply juxt))))))))
(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] ...)"
(atom (constantly true)))
View
22 src/taoensso/timbre/utils.clj
@@ -14,4 +14,24 @@
@d-result
(let [d-result (delay (apply f args))]
(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))
Please sign in to comment.
Something went wrong with that request. Please try again.