[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/>
- <R-reserved>if</>(record$level <= loglevels[[<R-string>'INFO'</>]])<br/>
- level <R-operator><-</> 3<br/>
- <R-reserved>else if</>(record$level <= loglevels[[<R-string>'WARNING'</>]])<br/>
- level <R-operator><-</> 2<br/>
- <R-reserved>else if</>(record$level <= loglevels[[<R-string>'ERROR'</>]])<br/>
- level <R-operator><-</> 1<br/>
- <R-reserved>else</><br/>
- level <R-operator><-</> 0<br/>
+<R-global>formatter.fewsdiagnostics</R-global> <R-operator><-</R-operator> <R-reserved>function</R-reserved>(record) {<br/>
+ <R-reserved>if</R-reserved>(record$level <= loglevels[[<R-string>'INFO'</R-string>]])<br/>
+ level <R-operator><-</R-operator> 3<br/>
+ <R-reserved>else if</R-reserved>(record$level <= loglevels[[<R-string>'WARNING'</R-string>]])<br/>
+ level <R-operator><-</R-operator> 2<br/>
+ <R-reserved>else if</R-reserved>(record$level <= loglevels[[<R-string>'ERROR'</R-string>]])<br/>
+ level <R-operator><-</R-operator> 1<br/>
+ <R-reserved>else</R-reserved><br/>
+ level <R-operator><-</R-operator> 0<br/>
<br/>
- sprintf(<R-string>' <line level="%d" description="LizardScripter :: %s :: %s"/>\n'</>, level, record$timestamp, record$msg)<br/>
+ sprintf(<R-string>' <line level="%d" description="LizardScripter :: %s :: %s"/>\n'</R-string>' <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/>
- 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/>
+ 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/>
- cat(<R-string>'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n'</>, file=filename, append=<R-constant>FALSE</>)<br/>
- cat(<R-string>'<Diag version="1.2" xmlns="..." xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="...">\n'</>, file=filename, append=<R-constant>FALSE</>)<br/>
- addHandler(<R-string>'diagnostics'</>,<br/>
+<R-global>setup.fewsdiagnostics</R-global> <R-operator><-</R-operator> <R-reserved>function</R-reserved>(filename) {<br/>
+ cat(<R-string>'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n'</R-string>, file=filename, append=<R-constant>FALSE</R-constant>)<br/>
+ cat(<R-string>'<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/>
+ addHandler(<R-string>'diagnostics'</R-string>,<br/>
writeToFile, file=filename,<br/>
- logger=<R-string>'fews.diagnostics'</>,<br/>
+ logger=<R-string>'fews.diagnostics'</R-string>,<br/>
formatter=formatter.fewsdiagnostics)<br/>
}<br/>
<br/>
-<R-global>teardown.fewsdiagnostics</> <R-operator><-</> <R-reserved>function</>(filename) {<br/>
- cat(<R-string>'</Diag>\n'</>, file=filename, append=<R-constant>TRUE</>)<br/>
- 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/>
+ cat(<R-string>'</Diag>\n'</R-string>', file=filename, append=<R-constant>TRUE</R-constant>)<br/>
+ 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/>
+ <R-reserved>if</R-reserved> (!exists(<R-string>'file'</R-string>, envir=handler))<br/>
+ <R-reserved>stop</R-reserved>(<R-string>"handler with writeToFile 'action' must have a 'file' element.\n"</R-string>)<br/>
+ 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/>
+ proxy <R-operator><-</R-operator> connectToServer(with(handler, server), with(handler, user), with(handler, passwd))<br/>
+ 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