<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -26,11 +26,11 @@
   *allow-direct-logging* boolean ref.  If log is invoked within a transaction it
   will always use an agent.
   
-  The logging macros will not evaluate their 'message' unless the specific 
-  logging level is in effect.
+  The log macro will not evaluate its 'message' unless the specific logging
+  level is in effect.
   
   Alternately, you can use the spy function when you have code that needs to be
-  evaluated, and also want to output its result to the debug log,
+  evaluated, and also want to output its result to the debug log.
   
   Unless otherwise specified, the current namespace (as identified by *ns*) will
   be used as the log-name (similar to how the java class name is usually used).
@@ -40,21 +40,25 @@
   
   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-name (e.g., 'com.example.captured') 
+  invoke with-logs.  In both cases a log-name (e.g., \&quot;com.example.captured\&quot;)
   needs to be specified to namespace the output.&quot;}
   clojure.contrib.logging)
 
 
-(defstruct log-system
-  :name     ; the name of the logging system used
-  :get-log  ; fn [name] to obtain a log by string name
-  :enabled? ; fn [log lvl] to check if a particular level is emabled
-  :write)   ; fn [log lvl msg ex] to a log a message
+(defstruct #^{:doc
+  &quot;A struct to abstract the functionality common to all implementations.
+  The keys are as follows:
+    :name     ; the name of the logging system used
+    :get-log  ; fn [name] to obtain a log by string name
+    :enabled? ; fn [log lvl] to check if a particular level is emabled
+    :write    ; fn [log lvl msg ex] to a log a message&quot;}
+  log-system
+  :name :get-log :enabled? :write)
 
 
 (defmacro commons-logging
   &quot;Creates a log-system struct using the Apache commons-logging API, 
-  if present; otherwise nil.&quot;
+  if present; otherwise nil. End-users should not need to invoke this macro.&quot;
   []
   (try
     (import (org.apache.commons.logging LogFactory Log))
@@ -81,7 +85,8 @@
 
 
 (defmacro log4j-logging
-  &quot;Creates a log-system struct using the log4j API, if present; otherwise nil.&quot;
+  &quot;Creates a log-system struct using the log4j API, if present; otherwise nil.
+   End-users should not need to invoke this macro.&quot;
   []
   (try
     (import (org.apache.log4j Logger Level))
@@ -104,7 +109,8 @@
 
 
 (defmacro java-logging
-  &quot;Creates a log-system struct using the java.util.logging API.&quot;
+  &quot;Creates a log-system struct using the java.util.logging API.  End-users
+  should not need to invoke this macro.&quot;
   []
   (try
     (import (java.util.logging Logger Level))
@@ -126,37 +132,35 @@
     (catch Exception e nil)))
 
 
-(defmacro direct-log
-  &quot;Logs the message immediately if the specific logging level is enabled. Use 
-  the log macro in prefernce to this.&quot;
-  [level message throwable log-name system]
-  `(let [log# ((~system :get-log) ~log-name)]
-    (if ((~system :enabled?) log# ~level)
-      ((~system :write) log# ~level ~message ~throwable))))
+(defn do-log
+  &quot;Logs the message immediately if the specific logging level is enabled. Use
+  the log macro in preference to this function.&quot;
+  [system-ref level message throwable log-name]
+  (let [system @system-ref
+        log ((system :get-log) log-name)]
+    (if ((system :enabled?) log level)
+      (do ((system :write) log level (force message) throwable)
+          system-ref))))
 
 
-(defmacro send-log
-  &quot;Sends the message to a logging agent, which will in turn write to the log if 
-  the specific logging level is enabled. Use the log macro in preference to 
-  this.&quot;
-  [level message throwable log-name system-agent]
-  (defn agent-log [sys# lvl# msg# th# ln#]
-    (let [log# ((sys# :get-log) ln#)]
-      (if ((sys# :enabled?) log# lvl#)
-        ((sys# :write) log# lvl# (force msg#) th#))
-      sys#))
-  `(send-off ~system-agent 
-      agent-log ~level (delay ~message) ~throwable ~log-name))
+(def #^{:doc
+  &quot;The default log-system initialized to the first implementation found from:
+  Apache commons-logging, log4j, java.util.logging.&quot;}
+  *log-system*
+  (atom (some eval ['(commons-logging)
+                    '(log4j-logging)
+                    '(java-logging)])))
 
 
-(def *log-system*
-  (ref (some eval ['(commons-logging)
-                   '(log4j-logging)
-                   '(java-logging)])))
-               
-(def *log-system-agent* (agent *log-system*))
+(def #^{:doc
+  &quot;The default agent referecing *log-system*.&quot;}
+  *log-system-agent* (agent *log-system*))
 
-(def *allow-direct-logging* (ref false))
+
+(def #^{:doc
+  &quot;A flag indicating wether logging can be directly (as opposed to via an agent)
+  when not operating from within a transaction. Defaults to false.&quot;}
+  *allow-direct-logging* (atom false))
 
 
 (defmacro log
@@ -167,9 +171,10 @@
     `(log ~level ~message ~throwable (str *ns*)))
   ([level message throwable log-name]
     `(if (and @*allow-direct-logging*
-                (not (clojure.lang.LockingTransaction/isRunning)))
-        (direct-log ~level ~message ~throwable ~log-name @*log-system*)
-        (send-log ~level ~message ~throwable ~log-name *log-system-agent*))))
+              (not (clojure.lang.LockingTransaction/isRunning)))
+        (do-log *log-system* ~level (delay ~message) ~throwable ~log-name)
+        (send-off *log-system-agent*
+          do-log ~level (delay ~message) ~throwable ~log-name))))
 
 
 (defn enabled?
@@ -191,7 +196,8 @@
 
 
 (defn log-stream
-  &quot;Creates a logging output stream that will output to the log.&quot;
+  &quot;Creates a PrintStream that will output to the log. End-users should not need
+  to invoke this function.&quot;
   [level log-name]
   (java.io.PrintStream.
     (proxy [java.io.ByteArrayOutputStream] []
@@ -204,14 +210,17 @@
     true))
 
 
-(def *old-std-streams* (ref nil))
+(def #^{:doc
+  &quot;Used by log-capture! to maintain a reference to the original System.out and
+  System.err streams.&quot;}
+  *old-std-streams* (ref nil))
 
 
 (defn log-capture!
-  &quot;Captures System/out and System/err, redirecting all writes of those streams 
+  &quot;Captures System.out and System.err, redirecting all writes of those streams
   to :info and :error logging, respectively. The specified log-name value will 
-  be used for all redirected logging. NOTE: this will not redirect output of 
-  *out* or *err*; for that use with-logs&quot; 
+  be used to namespace all redirected logging. NOTE: this will not redirect
+  output of *out* or *err*; for that, use with-logs.&quot;
   [log-name]
   (dosync
     (let [new-out (log-stream :info log-name)
@@ -234,13 +243,13 @@
 
 
 (defmacro with-logs
-  &quot;Evaluates exprs in a context in which *out* and *err* are bound to :info and 
-  :error logging, respectively.&quot;
+  &quot;Evaluates exprs in a context in which *out* and *err* are bound to :info and
+  :error logging, respectively. The specified log-name value will be used to
+  namespace all redirected logging.&quot;
   [log-name &amp; body]
-  `(let [new-out# (java.io.PrintWriter. 
-                    (log-stream :info ~log-name) true)
-         new-err# (java.io.PrintWriter. 
-                    (log-stream :error ~log-name) true)]
-    (binding [*out* new-out# 
-              *err* new-err#]
+  (if (and log-name (seq body))
+    `(binding [*out* (java.io.OutputStreamWriter.
+                       (log-stream :info ~log-name))
+               *err* (java.io.OutputStreamWriter.
+                       (log-stream :error ~log-name))]
       ~@body)))</diff>
      <filename>src/clojure/contrib/logging.clj</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>3ec66e7b4e47c95d4cc27b0c405447117b2d5503</id>
    </parent>
  </parents>
  <author>
    <name>Alexander Taggart</name>
    <email>alex.taggart@gmail.com</email>
  </author>
  <url>http://github.com/digash/clojure-contrib/commit/dcec88467e840c0120e9f27f2020636857692800</url>
  <id>dcec88467e840c0120e9f27f2020636857692800</id>
  <committed-date>2009-08-02T23:50:59-07:00</committed-date>
  <authored-date>2009-08-02T20:19:48-07:00</authored-date>
  <message>Improved the common code shared between direct and agent-based logging. Added docs to structs and special vars.</message>
  <tree>869914cc794a9c21f6bc4c87f714ab05dac2867b</tree>
  <committer>
    <name>Tom Faulhaber</name>
    <email>git_net@infolace.com</email>
  </committer>
</commit>
