aboutsummaryrefslogtreecommitdiff
path: root/src/clojure/contrib/logging.clj
diff options
context:
space:
mode:
authorStuart Sierra <mail@stuartsierra.com>2010-01-20 15:39:56 -0500
committerStuart Sierra <mail@stuartsierra.com>2010-01-20 15:39:56 -0500
commit2ede388a9267d175bfaa7781ee9d57532eb4f20f (patch)
treebb42002af196405d7e25cc4e30b4c1c9de5c06d5 /src/clojure/contrib/logging.clj
parent1bc820d96048a6536706ff999e9892649b53c700 (diff)
Move source files into Maven-style directory structure.
Diffstat (limited to 'src/clojure/contrib/logging.clj')
-rw-r--r--src/clojure/contrib/logging.clj349
1 files changed, 0 insertions, 349 deletions
diff --git a/src/clojure/contrib/logging.clj b/src/clojure/contrib/logging.clj
deleted file mode 100644
index 97bbfcfe..00000000
--- a/src/clojure/contrib/logging.clj
+++ /dev/null
@@ -1,349 +0,0 @@
-;;; logging.clj -- delegated logging for Clojure
-
-;; by Alex Taggart
-;; July 27, 2009
-
-;; Copyright (c) Alex Taggart, July 2009. All rights reserved. The use
-;; and distribution terms for this software are covered by the Eclipse
-;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
-;; which can be found in the file epl-v10.html at the root of this
-;; distribution. By using this software in any fashion, you are
-;; agreeing to be bound by the terms of this license. You must not
-;; remove this notice, or any other, from this software.
-(ns
- #^{:author "Alex Taggart, Timothy Pratley",
- :doc
- "Logging macros which delegate to a specific logging implementation. At
- macro-expansion-time a specific implementation is selected from, in order,
- Apache commons-logging, log4j, and finally java.util.logging.
-
- Logging levels are specified by clojure keywords corresponding to the
- values used in log4j and commons-logging:
- :trace, :debug, :info, :warn, :error, :fatal
-
- Logging occurs with the log macro, or the level-specific convenience macros,
- which write either directly or via an agent. For performance reasons, direct
- logging is enabled by default, but setting the *allow-direct-logging* boolean
- atom to false will disable it. If logging is invoked within a transaction it
- will always use an agent.
-
- The log macros will not evaluate their 'message' unless the specific logging
- level is in effect. Alternately, you can use the spy macro when you have code
- that needs to be evaluated, and also want to output the code and its result to
- the debug log.
-
- Unless otherwise specified, the current namespace (as identified by *ns*) will
- be used as the log-ns (similar to how the java class name is usually used).
- Note: your log configuration should display the name that was passed to the
- logging implementation, and not perform stack-inspection, otherwise you'll see
- something like \"fn__72$impl_write_BANG__39__auto____81\" in your logs.
-
- Use the enabled? macro to write conditional code against the logging level
- (beyond simply whether or not to call log, which is handled automatically).
-
- You can redirect all java writes of System.out and System.err to the log
- system by calling log-capture!. To rebind *out* and *err* to the log system
- invoke with-logs. In both cases a log-ns (e.g., \"com.example.captured\")
- needs to be specified to namespace the output."}
- clojure.contrib.logging)
-
-(declare *impl-name* impl-get-log impl-enabled? impl-write!)
-
-;; Macros used so that implementation-specific functions all have the same meta.
-
-(defmacro def-impl-name
- {:private true} [& body]
- `(def
- #^{:doc "The name of the logging implementation used."}
- *impl-name*
- ~@body))
-
-(defmacro def-impl-get-log
- {:private true} [& body]
- `(def
- #^{:doc
- "Returns an implementation-specific log by string namespace. End-users should
- not need to call this function."
- :arglist '([~'log-ns])}
- impl-get-log
- (memoize ~@body)))
-
-(defmacro def-impl-enabled?
- {:private true} [& body]
- `(def
- #^{:doc
- "Implementation-specific check if a particular level is enabled. End-users
- should not need to call this function."
- :arglist '([~'log ~'level])}
- impl-enabled?
- ~@body))
-
-(defmacro def-impl-write!
- {:private true} [& body]
- `(def
- #^{:doc
- "Implementation-specific write of a log message. End-users should not need to
- call this function."
- :arglist '([~'log ~'level ~'message ~'throwable])}
- impl-write!
- ~@body))
-
-(defmacro commons-logging
- "Defines the commons-logging-based implementations of the core logging
- functions. End-users should never need to call this macro."
- {:private true}
- []
- (try
- (import (org.apache.commons.logging LogFactory Log))
- `(do
- (def-impl-name "org.apache.commons.logging")
- (def-impl-get-log
- (fn [log-ns#]
- (org.apache.commons.logging.LogFactory/getLog #^String log-ns#)))
- (def-impl-enabled?
- (fn [#^org.apache.commons.logging.Log log# level#]
- (condp = level#
- :trace (.isTraceEnabled log#)
- :debug (.isDebugEnabled log#)
- :info (.isInfoEnabled log#)
- :warn (.isWarnEnabled log#)
- :error (.isErrorEnabled log#)
- :fatal (.isFatalEnabled log#))))
- (def-impl-write!
- (fn [#^org.apache.commons.logging.Log log# level# msg# e#]
- (condp = level#
- :trace (.trace log# msg# e#)
- :debug (.debug log# msg# e#)
- :info (.info log# msg# e#)
- :warn (.warn log# msg# e#)
- :error (.error log# msg# e#)
- :fatal (.fatal log# msg# e#))))
- true)
- (catch Exception e nil)))
-
-
-(defmacro log4j-logging
- "Defines the log4j-based implementations of the core logging functions.
- End-users should never need to call this macro."
- {:private true}
- []
- (try
- (import (org.apache.log4j Logger Level))
- `(do
- (def-impl-name "org.apache.log4j")
- (def-impl-get-log
- (fn [log-ns#]
- (org.apache.log4j.Logger/getLogger #^String log-ns#)))
- (let [levels# {:trace org.apache.log4j.Level/TRACE
- :debug org.apache.log4j.Level/DEBUG
- :info org.apache.log4j.Level/INFO
- :warn org.apache.log4j.Level/WARN
- :error org.apache.log4j.Level/ERROR
- :fatal org.apache.log4j.Level/FATAL}]
- (def-impl-enabled?
- (fn [#^org.apache.log4j.Logger log# level#]
- (.isEnabledFor log# (levels# level#))))
- (def-impl-write!
- (fn [#^org.apache.log4j.Logger log# level# msg# e#]
- (if-not e#
- (.log log# (levels# level#) msg#)
- (.log log# (levels# level#) msg# e#)))))
- true)
- (catch Exception e nil)))
-
-
-(defmacro java-logging
- "Defines the java-logging-based implementations of the core logging
- functions. End-users should never need to call this macro."
- {:private true}
- []
- (try
- (import (java.util.logging Logger Level))
- `(do
- (def-impl-name "java.util.logging")
- (def-impl-get-log
- (fn [log-ns#]
- (java.util.logging.Logger/getLogger log-ns#)))
- (let [levels# {:trace java.util.logging.Level/FINEST
- :debug java.util.logging.Level/FINE
- :info java.util.logging.Level/INFO
- :warn java.util.logging.Level/WARNING
- :error java.util.logging.Level/SEVERE
- :fatal java.util.logging.Level/SEVERE}]
- (def-impl-enabled?
- (fn [#^java.util.logging.Logger log# level#]
- (.isLoggable log# (levels# level#))))
- (def-impl-write!
- (fn [#^java.util.logging.Logger log# level# msg# e#]
- (if-not e#
- (.log log# #^java.util.logging.Level (levels# level#)
- #^String (str msg#))
- (.log log# #^java.util.logging.Level (levels# level#)
- #^String (str msg#) #^Throwable e#)))))
- true)
- (catch Exception e nil)))
-
-
-;; Initialize implementation-specific functions
-(or (commons-logging)
- (log4j-logging)
- (java-logging)
- (throw ; this should never happen in 1.5+
- (RuntimeException.
- "Valid logging implementation could not be found.")))
-
-
-(def #^{:doc
- "The default agent used for performing logging durng a transaction or when
- direct logging is disabled."}
- *logging-agent* (agent nil))
-
-
-(def #^{:doc
- "A boolean indicating whether direct logging (as opposed to via an agent) is
- allowed when not operating from within a transaction. Defaults to true."}
- *allow-direct-logging* (atom true))
-
-
-(defn agent-write!
- "Writes the message immediately, and ignores the first argument. Used by the
- logging agent. End-users should never need to call this function."
- [_ log level message throwable]
- (impl-write! log level message throwable))
-
-
-(defmacro log
- "Logs a message, either directly or via an agent. Also see the level-specific
- convenience macros."
- ([level message]
- `(log ~level ~message nil))
- ([level message throwable]
- `(log ~level ~message ~throwable ~(str *ns*)))
- ([level message throwable log-ns]
- `(let [log# (impl-get-log ~log-ns)]
- (if (impl-enabled? log# ~level)
- (if (and @*allow-direct-logging*
- (not (clojure.lang.LockingTransaction/isRunning)))
- (impl-write! log# ~level ~message ~throwable)
- (send-off *logging-agent*
- agent-write! log# ~level ~message ~throwable))))))
-
-
-(defmacro enabled?
- "Returns true if the specific logging level is enabled. Use of this function
- should only be necessary if one needs to execute alternate code paths beyond
- whether the log should be written to."
- ([level]
- `(enabled? ~level ~(str *ns*)))
- ([level log-ns]
- `(impl-enabled? (impl-get-log ~log-ns) ~level)))
-
-
-(defmacro spy
- "Evaluates expr and outputs the form and its result to the debug log; returns
- the result of expr."
- [expr]
- `(let [a# ~expr] (log :debug (str '~expr " => " a#)) a#))
-
-
-(defn log-stream
- "Creates a PrintStream that will output to the log. End-users should not need
- to invoke this function."
- [level log-ns]
- (java.io.PrintStream.
- (proxy [java.io.ByteArrayOutputStream] []
- (flush []
- (proxy-super flush)
- (let [s (.trim (.toString #^java.io.ByteArrayOutputStream this))]
- (proxy-super reset)
- (if (> (.length s) 0)
- (log level s nil log-ns)))))
- true))
-
-
-(def #^{:doc
- "A ref used by log-capture! to maintain a reference to the original System.out
- and System.err streams."
- :private true}
- *old-std-streams* (ref nil))
-
-
-(defn log-capture!
- "Captures System.out and System.err, redirecting all writes of those streams
- to :info and :error logging, respectively. The specified log-ns value will
- be used to namespace all redirected logging. NOTE: this will not redirect
- output of *out* or *err*; for that, use with-logs."
- [log-ns]
- (dosync
- (let [new-out (log-stream :info log-ns)
- new-err (log-stream :error log-ns)]
- ; don't overwrite the original values
- (if (nil? @*old-std-streams*)
- (ref-set *old-std-streams* {:out System/out :err System/err}))
- (System/setOut new-out)
- (System/setErr new-err))))
-
-
-(defn log-uncapture!
- "Restores System.out and System.err to their original values."
- []
- (dosync
- (when-let [{old-out :out old-err :err} @*old-std-streams*]
- (ref-set *old-std-streams* nil)
- (System/setOut old-out)
- (System/setErr old-err))))
-
-
-(defmacro with-logs
- "Evaluates exprs in a context in which *out* and *err* are bound to :info and
- :error logging, respectively. The specified log-ns value will be used to
- namespace all redirected logging."
- [log-ns & body]
- (if (and log-ns (seq body))
- `(binding [*out* (java.io.OutputStreamWriter.
- (log-stream :info ~log-ns))
- *err* (java.io.OutputStreamWriter.
- (log-stream :error ~log-ns))]
- ~@body)))
-
-(defmacro trace
- "Logs a message at the trace level."
- ([message]
- `(log :trace ~message))
- ([message throwable]
- `(log :trace ~message ~throwable)))
-
-(defmacro debug
- "Logs a message at the debug level."
- ([message]
- `(log :debug ~message))
- ([message throwable]
- `(log :debug ~message ~throwable)))
-
-(defmacro info
- "Logs a message at the info level."
- ([message]
- `(log :info ~message))
- ([message throwable]
- `(log :info ~message ~throwable)))
-
-(defmacro warn
- "Logs a message at the warn level."
- ([message]
- `(log :warn ~message))
- ([message throwable]
- `(log :warn ~message ~throwable)))
-
-(defmacro error
- "Logs a message at the error level."
- ([message]
- `(log :error ~message))
- ([message throwable]
- `(log :error ~message ~throwable)))
-
-(defmacro fatal
- "Logs a message at the fatal level."
- ([message]
- `(log :fatal ~message))
- ([message throwable]
- `(log :fatal ~message ~throwable)))