Permalink
Browse files

Merge branch 'perf'

  • Loading branch information...
2 parents 77beb18 + 0b46344 commit a1bf2860849f54941aa850012d70c2a897bf0985 @ptaoussanis committed Aug 21, 2013
View
@@ -1,3 +1,8 @@
+## v2.5.0 → v2.6.0
+ * Perf: make ns filtering a compile-time check.
+ * Perf: add support for a compile-time logging level environment variable (`TIMBRE_LOG_LEVEL`). See `timbre/compile-time-level` docstring for details.
+
+
## v2.4.1 → v2.5.0
* Added `:file` and `:line` appender args.
* Fixed `make-timestamp-fn` thread safety.
View
@@ -1,7 +1,7 @@
**[API docs](http://ptaoussanis.github.io/timbre/)** | **[CHANGELOG](https://github.com/ptaoussanis/timbre/blob/master/CHANGELOG.md)** | [contact & contributing](#contact--contributing) | [other Clojure libs](https://www.taoensso.com/clojure-libraries) | [Twitter](https://twitter.com/#!/ptaoussanis) | current [semantic](http://semver.org/) version:
```clojure
-[com.taoensso/timbre "2.5.0"] ; See CHANGELOG for breaking changes since 1.x
+[com.taoensso/timbre "2.6.0"] ; See CHANGELOG for breaking changes since 1.x
```
# Timbre, a (sane) Clojure logging & profiling library
@@ -11,7 +11,8 @@ Logging with Java can be maddeningly, unnecessarily hard. Particularly if all yo
## 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).
+ * **Low overhead** with dynamic logging level.
+ * **No overhead** with compile-time logging level. (v2.6+)
* Flexible **fn-centric appender model** with **middleware**.
* Sensible built-in appenders including simple **email appender**.
* Tunable **rate limit** and **asynchronous** logging support.
@@ -26,7 +27,7 @@ Logging with Java can be maddeningly, unnecessarily hard. Particularly if all yo
Add the necessary dependency to your [Leiningen](http://leiningen.org/) `project.clj` and `require` the library in your ns:
```clojure
-[com.taoensso/timbre "2.5.0"] ; project.clj
+[com.taoensso/timbre "2.6.0"] ; project.clj
(ns my-app (:require [taoensso.timbre :as timbre
:refer (trace debug info warn error fatal spy with-log-level)])) ; ns
```
@@ -58,6 +59,16 @@ There's little overhead for checking logging levels:
%> "Elapsed time: 0.051 msecs"
```
+And _no_ overhead when using a compile-time logging level (set `TIMBRE_LOG_LEVEL` environment variable):
+
+```clojure
+(time (dotimes [_ 1000000000] (trace (Thread/sleep 5000))))
+%> "Elapsed time: 387.159 msecs"
+
+(time (dotimes [_ 1000000000] nil))
+%> "Elapsed time: 389.231 msecs"
+```
+
First-argument exceptions generate a stack trace:
```clojure
View
@@ -1,4 +1,4 @@
-(defproject com.taoensso/timbre "2.5.0"
+(defproject com.taoensso/timbre "2.6.0"
:description "Clojure logging & profiling library"
:url "https://github.com/ptaoussanis/timbre"
:license {:name "Eclipse Public License"
View
@@ -45,6 +45,13 @@
;;;; Default configuration and appenders
+(def compile-time-level
+ "Constant, compile-time logging level determined by the `TIMBRE_LOG_LEVEL`
+ environment variable. When set, overrules dynamically-configurable logging
+ level as a performance optimization (e.g. for use in performance sensitive
+ production environments)."
+ (keyword (System/getenv "TIMBRE_LOG_LEVEL")))
+
(def ^:dynamic *current-level* nil)
(defmacro with-log-level
"Allows thread-local config logging level override. Useful for dev & testing."
@@ -136,7 +143,9 @@
(memoize (fn [x y] (- (checked-level-score x) (checked-level-score y)))))
(defn sufficient-level?
- [level] (>= (compare-levels level (or *current-level* (:current-level @config))) 0))
+ [level] (>= (compare-levels level (or compile-time-level
+ *current-level*
+ (:current-level @config))) 0))
;;;; Appender-fn decoration
@@ -305,7 +314,7 @@
(cache-appenders-juxt!)
(cache-ns-filter!))))
-;;;; Define logging macros
+;;;; Logging macros
(defn send-to-appenders! "Implementation detail - subject to change."
[level base-appender-args log-vargs ns throwable message & [juxt-fn file line]]
@@ -323,10 +332,20 @@
:message message}))
nil))
-(defn logging-enabled?
+(defmacro logging-enabled?
"Returns true iff current logging level is sufficient and current namespace
- unfiltered."
- [level] (and (sufficient-level? level) (@ns-filter-cache *ns*)))
+ unfiltered. The namespace test is compile-time, the logging-level test
+ compile-time iff a compile-time logging level was specified."
+ [level & body]
+ (when (@ns-filter-cache *ns*)
+ (if compile-time-level
+ (sufficient-level? level)
+ `(sufficient-level? ~level))))
+
+(comment
+ (def compile-time-level :info)
+ (def compile-time-level nil)
+ (macroexpand-1 '(logging-enabled? :debug)))
(defmacro log* "Implementation detail - subject to change."
[message-fn level base-appender-args & log-args]
@@ -451,4 +470,4 @@
(if (contains? message :password)
(assoc args :message (assoc message :password "*****"))
args)
- :else args))]))
+ :else args))]))
@@ -1,5 +1,6 @@
(ns taoensso.timbre.frequencies
- "Frequency logger for Timbre. ALPHA quality."
+ "DEPRECATED.
+ Frequency logger for Timbre. ALPHA quality."
{:author "Peter Taoussanis"}
(:require [clojure.string :as str]
[taoensso.timbre :as timbre]
@@ -80,4 +81,4 @@
(log-frequencies
:info :my-frequencies
- (vec (repeatedly 20 (fn [] (fspy :rand-nth (rand-nth [:a :b :c])))))))
+ (vec (repeatedly 20 (fn [] (fspy :rand-nth (rand-nth [:a :b :c])))))))
@@ -141,4 +141,4 @@
(profile :info :Arithmetic (dotimes [n 100] (my-fn)))
- (sampling-profile :info 0.2 :Sampling-test (p :string "Hello!")))
+ (sampling-profile :info 0.2 :Sampling-test (p :string "Hello!")))
@@ -21,4 +21,4 @@
(defn use-timbre []
(alter-var-root clojure.tools.logging/*logger-factory*
- (constantly (->LoggerFactory))))
+ (constantly (->LoggerFactory))))

0 comments on commit a1bf286

Please sign in to comment.