Skip to content

Commit

Permalink
Moved predefined protocol implementations into impl ns. This allows t…
Browse files Browse the repository at this point in the history
…hose namespaces to be used in the future for implementation-specific functions that depend on the core api (rather than having the core api depending on them, which was the case).
  • Loading branch information
Alexander Taggart committed Sep 27, 2011
1 parent 25b7ec9 commit 0688b1b
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 207 deletions.
30 changes: 11 additions & 19 deletions src/main/clojure/clojure/tools/logging.clj
Expand Up @@ -18,12 +18,7 @@
[:use
[clojure.string :only [trim-newline]]
[clojure.pprint :only [code-dispatch pprint with-pprint-dispatch]]]
[:require [clojure.tools.logging
[commons-logging :as cl]
[impl :as impl]
[java-util-logging :as jul]
[log4j :as log4j]
[slf4j :as slf4j]]])
[:require [clojure.tools.logging.impl :as impl]])

(def ^{:doc
"The default agent used for performing logging when direct logging is
Expand Down Expand Up @@ -54,11 +49,11 @@
One can override the above by setting *force* to :direct or :agent; all
subsequent writes will be direct or via an agent, respectively."
[logger level throwable message]
(if (cond
(nil? *force*) (and (clojure.lang.LockingTransaction/isRunning)
(*tx-agent-levels* level))
(= *force* :agent) true
(= *force* :direct) false)
(if (case *force*
:agent true
:direct false
nil (and (clojure.lang.LockingTransaction/isRunning)
(*tx-agent-levels* level)))
(send-off *logging-agent*
(fn [_#] (impl/write! logger level throwable message)))
(impl/write! logger level throwable message)))
Expand Down Expand Up @@ -273,19 +268,16 @@
`(logf :fatal ~@args))

(defn- find-factory []
(or (slf4j/load-factory)
(cl/load-factory)
(log4j/load-factory)
(jul/load-factory)
(or (impl/slf4j-factory)
(impl/cl-factory)
(impl/log4j-factory)
(impl/jul-factory)
(throw ; this should never happen in 1.5+
(RuntimeException.
"Valid logging implementation could not be found."))))

(def ^{:doc
"An instance satisfying the LoggerFactory protocol. Used internally when
needing to obtain an instance satisfying the Logger protocol. Defaults to the
first LoggerFactory found that is available from slf4j-logging,
commons-logging, log4j-logging, or java-util-logging. Can be rebound to provide
alternate logging implementations" :dynamic true}
needing to obtain an instance satisfying the Logger protocol." :dynamic true}
*logger-factory*
(find-factory))
45 changes: 0 additions & 45 deletions src/main/clojure/clojure/tools/logging/commons_logging.clj

This file was deleted.

150 changes: 146 additions & 4 deletions src/main/clojure/clojure/tools/logging/impl.clj
Expand Up @@ -8,12 +8,13 @@

(ns ^{:author "Alex Taggart"
:doc "Protocols used to allow access to logging implementations.
End-users should not need to use this namespace."}
This namespace only need be used by those providing logging
implementations to be consumed by the core api."}
clojure.tools.logging.impl
(:refer-clojure :exclude [name]))

(defprotocol Logger
"The protocol through which macros will interact with an underlying logging
"The protocol through which the core api will interact with an underlying logging
implementation. Implementations should at least support the six standard
logging levels if they wish to work from the level-specific macros."
(enabled? [logger level]
Expand All @@ -22,11 +23,152 @@
"Writes a log message to the given Logger."))

(defprotocol LoggerFactory
"The protocol through which macros will obtain an instance satisfying Logger as
well as providing information about the particular implementation being used.
"The protocol through which the core api will obtain an instance satisfying Logger
as well as providing information about the particular implementation being used.
Implementations should be bound to *logger-factory* in order to be picked up by
this library."
(name [factory]
"Returns some text identifying the underlying implementation.")
(get-logger [factory logger-ns]
"Returns an implementation-specific Logger by namespace."))

(defn slf4j-factory
"Returns a SLF4J-based implementation of the LoggerFactory protocol, or nil if
not available."
[]
(try
(Class/forName "org.slf4j.Logger")
(eval
`(do
(extend-type org.slf4j.Logger
Logger
(enabled? [logger# level#]
(condp = level#
:trace (.isTraceEnabled logger#)
:debug (.isDebugEnabled logger#)
:info (.isInfoEnabled logger#)
:warn (.isWarnEnabled logger#)
:error (.isErrorEnabled logger#)
:fatal (.isErrorEnabled logger#)
(throw (IllegalArgumentException. (str level#)))))
(write! [^org.slf4j.Logger logger# level# ^Throwable e# msg#]
(let [^String msg# (str msg#)]
(condp = level#
:trace (.trace logger# msg# e#)
:debug (.debug logger# msg# e#)
:info (.info logger# msg# e#)
:warn (.warn logger# msg# e#)
:error (.error logger# msg# e#)
:fatal (.error logger# msg# e#)
(throw (IllegalArgumentException. (str level#)))))))
(reify LoggerFactory
(name [_#]
"org.slf4j")
(get-logger [_# logger-ns#]
(org.slf4j.LoggerFactory/getLogger ^String (str logger-ns#))))))
(catch Exception e nil)))

(defn cl-factory
"Returns a Commons Logging-based implementation of the LoggerFactory protocol, or
nil if not available."
[]
(try
(Class/forName "org.apache.commons.logging.Log")
(eval
`(do
(extend-type org.apache.commons.logging.Log
Logger
(enabled? [logger# level#]
(condp = level#
:trace (.isTraceEnabled logger#)
:debug (.isDebugEnabled logger#)
:info (.isInfoEnabled logger#)
:warn (.isWarnEnabled logger#)
:error (.isErrorEnabled logger#)
:fatal (.isFatalEnabled logger#)
(throw (IllegalArgumentException. (str level#)))))
(write! [logger# level# e# msg#]
(condp = level#
:trace (.trace logger# msg# e#)
:debug (.debug logger# msg# e#)
:info (.info logger# msg# e#)
:warn (.warn logger# msg# e#)
:error (.error logger# msg# e#)
:fatal (.fatal logger# msg# e#)
(throw (IllegalArgumentException. (str level#))))))
(reify LoggerFactory
(name [_#]
"org.apache.commons.logging")
(get-logger [_# logger-ns#]
(org.apache.commons.logging.LogFactory/getLog (str logger-ns#))))))
(catch Exception e nil)))

(defn log4j-factory
"Returns a Log4j-based implementation of the LoggerFactory protocol, or nil if
not available."
[]
(try
(Class/forName "org.apache.log4j.Logger")
(eval
`(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}]
(extend-type org.apache.log4j.Logger
Logger
(enabled? [logger# level#]
(.isEnabledFor logger#
(or
(levels# level#)
(throw (IllegalArgumentException. (str level#))))))
(write! [logger# level# e# msg#]
(let [level# (or
(levels# level#)
(throw (IllegalArgumentException. (str level#))))]
(if-not e#
(.log logger# level# msg#)
(.log logger# level# msg# e#)))))
(reify LoggerFactory
(name [_#]
"org.apache.log4j")
(get-logger [_# logger-ns#]
(org.apache.log4j.Logger/getLogger ^String (str logger-ns#))))))
(catch Exception e nil)))

(defn jul-factory
"Returns a java.util.logging-based implementation of the LoggerFactory protocol,
or nil if not available."
[]
(try
(Class/forName "java.util.logging.Logger")
(eval
`(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}]
(extend-type java.util.logging.Logger
Logger
(enabled? [logger# level#]
(.isLoggable logger#
(or
(levels# level#)
(throw (IllegalArgumentException. (str level#))))))
(write! [logger# level# ^Throwable e# msg#]
(let [^java.util.logging.Level level#
(or
(levels# level#)
(throw (IllegalArgumentException. (str level#))))
^String msg# (str msg#)]
(if e#
(.log logger# level# msg# e#)
(.log logger# level# msg#)))))
(reify LoggerFactory
(name [_#]
"java.util.logging")
(get-logger [_# logger-ns#]
(java.util.logging.Logger/getLogger (str logger-ns#))))))
(catch Exception e nil)))
47 changes: 0 additions & 47 deletions src/main/clojure/clojure/tools/logging/java_util_logging.clj

This file was deleted.

45 changes: 0 additions & 45 deletions src/main/clojure/clojure/tools/logging/log4j.clj

This file was deleted.

0 comments on commit 0688b1b

Please sign in to comment.