[Logging-commits] r30 - pkg pkg/R www

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Fri Apr 9 13:55:06 CEST 2010


Author: mariotomo
Date: 2010-04-09 13:55:06 +0200 (Fri, 09 Apr 2010)
New Revision: 30

Modified:
   pkg/DESCRIPTION
   pkg/R/logger.R
   www/sample_session.html
Log:
documenting custom handlers.
writeToFile stops if 'file' was not specified.


Modified: pkg/DESCRIPTION
===================================================================
--- pkg/DESCRIPTION	2010-04-09 10:11:36 UTC (rev 29)
+++ pkg/DESCRIPTION	2010-04-09 11:55:06 UTC (rev 30)
@@ -1,5 +1,5 @@
 Package: logging
-Version: 0.4-26
+Version: 0.4-30
 Date: 2010-01-14
 Title: a tentative logging package
 Author: Mario Frasca <mariotomo at gmail.com>

Modified: pkg/R/logger.R
===================================================================
--- pkg/R/logger.R	2010-04-09 10:11:36 UTC (rev 29)
+++ pkg/R/logger.R	2010-04-09 11:55:06 UTC (rev 30)
@@ -213,10 +213,7 @@
 writeToFile <- function(msg, handler)
 {
   if (!exists('file', envir=handler))
-  {
-    cat("handler with writeToFile 'action' must have a 'file' element.\n")
-    return()
-  }
+    stop("handler with writeToFile 'action' must have a 'file' element.\n")
   cat(paste(msg, '\n', sep=''), file=with(handler, file), append=TRUE)
 }
 

Modified: www/sample_session.html
===================================================================
--- www/sample_session.html	2010-04-09 10:11:36 UTC (rev 29)
+++ www/sample_session.html	2010-04-09 11:55:06 UTC (rev 30)
@@ -217,17 +217,17 @@
 make this function faster, more readable, shorter...</p>
 
 <code>
-<R-global>formatter.fewsdiagnostics</> <R-operator><-</> <R-reserved>function</>(record) {<br/>
-&nbsp; <R-reserved>if</>(record$level <= loglevels[[<R-string>'INFO'</>]])<br/>
-&nbsp; &nbsp; level <R-operator><-</> 3<br/>
-&nbsp; <R-reserved>else if</>(record$level <= loglevels[[<R-string>'WARNING'</>]])<br/>
-&nbsp; &nbsp; level <R-operator><-</> 2<br/>
-&nbsp; <R-reserved>else if</>(record$level <= loglevels[[<R-string>'ERROR'</>]])<br/>
-&nbsp; &nbsp; level <R-operator><-</> 1<br/>
-&nbsp; <R-reserved>else</><br/>
-&nbsp; &nbsp; level <R-operator><-</> 0<br/>
+<R-global>formatter.fewsdiagnostics</R-global> <R-operator><-</R-operator> <R-reserved>function</R-reserved>(record) {<br/>
+&nbsp; <R-reserved>if</R-reserved>(record$level <= loglevels[[<R-string>'INFO'</R-string>]])<br/>
+&nbsp; &nbsp; level <R-operator><-</R-operator> 3<br/>
+&nbsp; <R-reserved>else if</R-reserved>(record$level <= loglevels[[<R-string>'WARNING'</R-string>]])<br/>
+&nbsp; &nbsp; level <R-operator><-</R-operator> 2<br/>
+&nbsp; <R-reserved>else if</R-reserved>(record$level <= loglevels[[<R-string>'ERROR'</R-string>]])<br/>
+&nbsp; &nbsp; level <R-operator><-</R-operator> 1<br/>
+&nbsp; <R-reserved>else</R-reserved><br/>
+&nbsp; &nbsp; level <R-operator><-</R-operator> 0<br/>
 <br/>
-&nbsp; sprintf(<R-string>'&nbsp; &lt;line level="%d" description="LizardScripter :: %s :: %s"/>\n'</>, level, record$timestamp, record$msg)<br/>
+&nbsp; sprintf(<R-string>'&nbsp; &lt;line level="%d" description="LizardScripter :: %s :: %s"/>\n'</R-string>'&nbsp; &lt;line level="%d" description="LizardScripter :: %s :: %s"/>, level, record$timestamp, record$msg)<br/>
 }
 </code>
 
@@ -247,33 +247,82 @@
 formatter is used, which looks like this:</p>
 
 <code>
-<R-global>defaultFormat</> <R-operator><-</> <R-reserved>function</>(record) {<br/>
-&nbsp; text <R-operator><-</> paste(record$timestamp, paste(record$levelname, record$logger, record$msg, sep=<R-string>':'</>))<br/>
+<R-global>defaultFormat</R-global> <R-operator><-</R-operator> <R-reserved>function</R-reserved>(record) {<br/>
+&nbsp; text <R-operator><-</R-operator> paste(record$timestamp, paste(record$levelname, record$logger, record$msg, sep=<R-string>':'</R-string>))<br/>
 }
 </code>
 
 <p>the rest of the code, just slightly simplified, showing how we (me
-at my company) actually use this capability is this:</p>
+at my company) actually use this capability is given here.  </p><p>notice
+that the 'diagnostics' handler we add will not handle <tt>DEBUG</tt>
+logrecords.</p>
 
 <code>
-<R-global>setup.fewsdiagnostics</> <R-operator><-</> <R-reserved>function</>(filename) {<br/>
-&nbsp; cat(<R-string>'&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n'</>, file=filename, append=<R-constant>FALSE</>)<br/>
-&nbsp; cat(<R-string>'&lt;Diag version="1.2" xmlns="..." xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="...">\n'</>, file=filename, append=<R-constant>FALSE</>)<br/>
-&nbsp; addHandler(<R-string>'diagnostics'</>,<br/>
+<R-global>setup.fewsdiagnostics</R-global> <R-operator><-</R-operator> <R-reserved>function</R-reserved>(filename) {<br/>
+&nbsp; cat(<R-string>'&lt;?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n'</R-string>, file=filename, append=<R-constant>FALSE</R-constant>)<br/>
+&nbsp; cat(<R-string>'&lt;Diag version="1.2" xmlns="..." xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="...">\n'</R-string>, file=filename, append=<R-constant>FALSE</R-constant>)<br/>
+&nbsp; addHandler(<R-string>'diagnostics'</R-string>,<br/>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  writeToFile, file=filename,<br/>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  logger=<R-string>'fews.diagnostics'</>,<br/>
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  logger=<R-string>'fews.diagnostics'</R-string>,<br/>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  formatter=formatter.fewsdiagnostics)<br/>
 }<br/>
 <br/>
-<R-global>teardown.fewsdiagnostics</> <R-operator><-</> <R-reserved>function</>(filename) {<br/>
-&nbsp; cat(<R-string>'&lt;/Diag>\n'</>, file=filename, append=<R-constant>TRUE</>)<br/>
-&nbsp; removeHandler(<R-string>'diagnostics'</>, logger=<R-string>'fews.diagnostics'</>)<br/>
+<R-global>teardown.fewsdiagnostics</R-global> <R-operator><-</R-operator> <R-reserved>function</R-reserved>(filename) {<br/>
+&nbsp; cat(<R-string>'&lt;/Diag>\n'</R-string>', file=filename, append=<R-constant>TRUE</R-constant>)<br/>
+&nbsp; removeHandler(<R-string>'diagnostics'</R-string>, logger=<R-string>'fews.diagnostics'</R-string>)<br/>
 }
 </code>
 
-<p></p>
-<p></p>
-<p></p>
+<h4>writing your own handlers</h4>
 
+<p>differently than in the logging library in Python and in Java,
+handlers in this logging library aren't objects: they are environments
+stored in one of the loggers.  the principal characteristic property
+of a handler is its <tt>action</tt>.  a action is a function that
+specifies what the handler should do with a logrecord that, based on
+all that we have seen above, must be handled.  the two commodity
+functions we have seen in the first two
+sessions, <tt>writeToConsole</tt> and <tt>writeToFile</tt> are action
+functions.</p>
+
+<p>a look at <tt>writeToFile</tt> will help understand the idea
+implemented in this library.</p>
+
+<code>
+<R-global>writeToFile</R-global> <R-operator><-</R-operator> <R-reserved>function</R-reserved>(msg, handler)<br/>
+{<br/>
+&nbsp; <R-reserved>if</R-reserved> (!exists(<R-string>'file'</R-string>, envir=handler))<br/>
+&nbsp; &nbsp; <R-reserved>stop</R-reserved>(<R-string>"handler with writeToFile 'action' must have a 'file' element.\n"</R-string>)<br/>
+&nbsp; cat(paste(msg, <R-string>'\n'</R-string>, sep=<R-string>''</R-string>), file=with(handler, file), append=<R-constant>TRUE</R-constant>)<br/>
+}
+</code>
+
+<p>an action is invoked if a record must be handled.  its result code
+is ignored and all its output goes to the console.  it receives
+exactly two arguments, the formatted message that must be output (the
+string returned by the formatter of the handler) and the handler
+owning the action.  recall that a handler is an environment: in the
+action you can inspect the <tt>handler</tt> environment to perform the
+desired behaviour.</p>
+
+<p>imagine you want a handler to send its messages to a xmlrpc server
+or to a password protected ftp server, you would add these properties
+in the call to addHandler.  addHandler would store them in the new
+handler environment.  your action function would retrieve the values
+from the handler and use them to connect to your hypothetical external
+server.</p>
+
+<p>the structure of your solution might be something like this:</p>
+
+<code>
+<R-global>sendToFtpServer</R-global> <R-operator><-</R-operator> <R-reserved>function</R-reserved>(msg, handler)<br/>
+{<br/>
+&nbsp; proxy <R-operator><-</R-operator> connectToServer(with(handler, server), with(handler, user), with(handler, passwd))<br/>
+&nbsp; do_the_rest()<br/>
+}<br/>
+<br/>
+addHandler(sendToFptServer, user=<R-string>''</R-string>, server=<R-string>''</R-string>, passwd=<R-string>''</R-string>, logger=<R-string>"deep.deeper.deepest"</R-string>)<br/>
+</code>
+
 </body>
 </html>



More information about the Logging-commits mailing list