[Logging-commits] r33 - www

noreply at r-forge.r-project.org noreply at r-forge.r-project.org
Fri Apr 9 15:35:27 CEST 2010


Author: mariotomo
Date: 2010-04-09 15:35:27 +0200 (Fri, 09 Apr 2010)
New Revision: 33

Added:
   www/formatting_your_log_records.php
   www/formatting_your_log_records.shtml
   www/hierarchical_loggers.php
   www/hierarchical_loggers.shtml
   www/logging_to_file.php
   www/logging_to_file.shtml
   www/sample_session.php
   www/the_basics.php
   www/the_basics.shtml
   www/writing_your_own_handlers.php
   www/writing_your_own_handlers.shtml
Removed:
   www/sample_session.html
Modified:
   www/index.php
Log:
refactoring the documentation.


Added: www/formatting_your_log_records.php
===================================================================
--- www/formatting_your_log_records.php	                        (rev 0)
+++ www/formatting_your_log_records.php	2010-04-09 13:35:27 UTC (rev 33)
@@ -0,0 +1,17 @@
+<html>
+<head>
+<title>tutorial : formatting your log records</title>
+<link href="additions.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+
+<p>
+   <a href="sample_session.php">[back to the tutorial]</a> &nbsp;
+<a href="logging_to_file.php">[previous session]</a> &nbsp;
+<a href="writing_your_own_handlers.php">[next session]</a>
+</p>
+
+<?php include("formatting_your_log_records.shtml"); ?> 
+
+</body>
+</html>
\ No newline at end of file

Added: www/formatting_your_log_records.shtml
===================================================================
--- www/formatting_your_log_records.shtml	                        (rev 0)
+++ www/formatting_your_log_records.shtml	2010-04-09 13:35:27 UTC (rev 33)
@@ -0,0 +1,65 @@
+
+<h4>formatting your log records</h4>
+
+<p>in this session we are going to see how to generate a diagnostics
+file for a system that organizes logrecords in a different way than
+Python.  let's jump into the implementation, if you can write R you
+surely won't need more explaination but will want to tell me how to
+make this function faster, more readable, shorter...</p>
+
+<code>
+<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'</R-string>, level, record$timestamp, record$msg)<br/>
+}
+</code>
+
+<p>notice that the field <tt>$msg</tt> of a record is already
+"formatted", as we have seen with <tt>logwarn('my %s is %d', 'name',
+5)</tt>.  that part can be used but not undone any more.  the
+formatter you can associate to a handler can combine the tags in the
+logrecord to produce a string.</p>
+
+<p>when you add a handler to a logger, you can use
+the <tt>formatter</tt> parameter to associate to the handler a
+function that takes a logrecord and returns a string.  the above
+example function is such a function.  </p>
+
+
+<p>if you don't specify the <tt>formatter</tt> parameter, the default
+formatter is used, which looks like this:</p>
+
+<code>
+<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 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-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'</R-string>,<br/>
+&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  formatter=formatter.fewsdiagnostics)<br/>
+}<br/>
+<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>

Added: www/hierarchical_loggers.php
===================================================================
--- www/hierarchical_loggers.php	                        (rev 0)
+++ www/hierarchical_loggers.php	2010-04-09 13:35:27 UTC (rev 33)
@@ -0,0 +1,17 @@
+<html>
+<head>
+<title>tutorial : hierarchical loggers</title>
+<link href="additions.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+
+<p>
+<a href="sample_session.php">[back to the tutorial]</a>
+<a href="the_basics.php">[previous session]</a>
+<a href="logging_to_file.php">[next session]</a>
+</p>
+
+<?php include("hierarchical_loggers.shtml"); ?> 
+
+</body>
+</html>
\ No newline at end of file

Added: www/hierarchical_loggers.shtml
===================================================================
--- www/hierarchical_loggers.shtml	                        (rev 0)
+++ www/hierarchical_loggers.shtml	2010-04-09 13:35:27 UTC (rev 33)
@@ -0,0 +1,58 @@
+
+<h4>hierarchical loggers</h4>
+
+<p>in the previous section we have worked -implicitly- with one
+logger, the root logger.  we can refer to it explicitly by specifying
+the 'logger' parameter in our function calls.  the name of the root
+logger is the empty string.  this also explains that "::" in the
+messages sent to the console, between the first and the second ":"
+there's the name of the logger that is associated to the log record
+shown.</p>
+
+<code>
+R> <user>with(getLogger(logger=''), names(handlers))</user><br/>
+[1] "basic.stdout"<br/>
+R> <user>with(getLogger('libro'), names(handlers))</user><br/>
+NULL
+</code>
+
+<p>when issuing a logging record, you can specify to which logger you
+want to send it.  loggers are created when first needed, so we can
+just assume all loggers we need also exist.  the logger will offer it
+to all its attached handlers and then pass it to its parent logger.
+loggers are organized hierarchically, in a way that is similar to the
+way directories are organized.  </p>
+
+<p>just as directories contain files, loggers contain handlers and
+their name is, within the logger, unique.  also similarly than to
+directories, all loggers have one parent, except the root logger that
+has none.  the name of the logger specifies the location of the logger
+in this hierarchy.  an example will hopefully clarify.  </p>
+
+<p>let's start from scratch, either a brand new R session or by
+resetting the logging system.</p>
+
+<code>
+R> <user>logReset()</user><br/>
+R> <user>addHandler(writeToConsole, logger='libro.romanzo')</user><br/>
+R> <user>loginfo('chiarastella', logger='libro.romanzo.campanile')</user><br/>
+2010-04-08 11:18:59 INFO:libro.romanzo.campanile:chiarastella<br/>
+R> <user>loginfo('memories of a survivor', logger='libro.romanzo.lessing')</user><br/>
+2010-04-08 11:22:06 INFO:libro.romanzo.lessing:memories of a survivor<br/>
+R> <user>logwarn('talking to a hierarchically upper logger', logger='libro')</user><br/>
+R> <user>logerror('talking to an unrelated logger', logger='rivista.cucina')</user><br/>
+R> 
+</code>
+
+<p>notice that loggers are automatically defined by the simple action
+of naming them.  what happened above is that the handler we created,
+attached to the 'libro.romanzo' logger, only saw the records going to
+the loggers below its logger.  all records going to hierarchically
+upper loggers or to unrelated loggers are not logged, regardless of
+their severity.</p>
+
+<p>also notice that the text printed doesn't contain any more that
+"::".  between the two ":" there's the name of the logger that
+received the logging record in the first place.</p>
+
+<p><a href="hierarchical_loggers.R">code</a></p>

Modified: www/index.php
===================================================================
--- www/index.php	2010-04-09 12:24:16 UTC (rev 32)
+++ www/index.php	2010-04-09 13:35:27 UTC (rev 33)
@@ -55,7 +55,7 @@
 <li>a simple basicConfig function to quickly put yourself in a usable situation...</li>
 </ul></p>
 
-<p>have a look at a short introductory <a href="sample_session.html">sample session</a>.</p>
+<p>have a look at a short introductory <a href="sample_session.php">sample session</a>.</p>
 
 <p>This package owes a lot to 
 <ul>

Added: www/logging_to_file.php
===================================================================
--- www/logging_to_file.php	                        (rev 0)
+++ www/logging_to_file.php	2010-04-09 13:35:27 UTC (rev 33)
@@ -0,0 +1,17 @@
+<html>
+<head>
+<title>tutorial : logging to file</title>
+<link href="additions.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+
+<p>
+<a href="sample_session.php">[back to the tutorial]</a>
+<a href="hierarchical_loggers.php">[previous session]</a>
+<a href="formatting_your_log_records.php">[next session]</a>
+</p>
+
+<?php include("logging_to_file.shtml"); ?> 
+
+</body>
+</html>
\ No newline at end of file

Added: www/logging_to_file.shtml
===================================================================
--- www/logging_to_file.shtml	                        (rev 0)
+++ www/logging_to_file.shtml	2010-04-09 13:35:27 UTC (rev 33)
@@ -0,0 +1,53 @@
+
+<h4>logging to file</h4>
+
+<p>actually the name of this paragraph is misleading.  a more correct
+name would be <em>handling to file</em>, since it's a handler and not
+a logger that is actually writing some representation of your
+logrecords to a file.  </p>
+
+<p>to make sure log records are sent to a file, you choose a logger
+and attach to it a handler with action a function that writes to your
+file.  the logging package exports the commodity
+function <tt>writeToFile</tt> for this purpouse.  the name of the file
+is given as an extra parameter in the call to <tt>addHandler</tt>.</p>
+
+<p>recall that both loggers <em>and</em> handlers have a level.
+records at a specific severity are examined by loggers first; if the
+severity is higher than the level of the logger, they are offered to
+all of the attached handlers.  handlers will again check the level of
+the record before taking action.  in the following example we make
+sure absolutely all logrecords are examined by initializing the root
+logger at the <tt>FINEST</tt> level.  the level of
+the <tt>basic_stdout</tt> console handler is not affected.</p>
+
+<code>
+R> <user>logReset()</user><br/>
+R> <user>basicConfig(level='FINEST')</user><br/>
+R> <user>addHandler(writeToFile, file="~/testing.log", level='DEBUG')</user><br/>
+R> <user>with(getLogger(), names(handlers))</user><br/>
+[1] "basic.stdout"   "writeToFile"<br/>
+R> <user>loginfo('test %d', 1)</user><br/>
+2010-04-07 11:31:06 INFO::test 1<br/>
+R> <user>logdebug('test %d', 2)</user><br/>
+R> <user>logwarn('test %d', 3)</user><br/>
+2010-04-07 11:31:15 WARN::test 3<br/>
+R> <user>logfinest('test %d', 4)</user><br/>
+R> 
+</code>
+
+<p>if the file was not existing or empty, this would be its content after the above steps:</p>
+<code>
+2010-04-07 11:31:06 INFO::test 1<br/>
+2010-04-07 11:31:11 DEBUG::test 2<br/>
+2010-04-07 11:31:15 WARN::test 3<br/>
+</code>
+
+<p>all log records have been passed to both
+handlers <tt>basic.stdout</tt> and <tt>writeToFile</tt>.  the default
+console handler has handled records with severity at or
+above <tt>INFO</tt>, our file handler had threshold <tt>DEBUG</tt> so
+it handled also the second record in the example session.  the fourth
+record was dropped by both handlers.</p>
+
+<p><a href="logging_to_file.R">code</a></p>

Deleted: www/sample_session.html
===================================================================
--- www/sample_session.html	2010-04-09 12:24:16 UTC (rev 32)
+++ www/sample_session.html	2010-04-09 13:35:27 UTC (rev 33)
@@ -1,328 +0,0 @@
-<html>
-<head>
-  <title>sample sessions</title>
-  <link href="additions.css" rel="stylesheet" type="text/css" />
-</head>
-<body>
-<h3>annotated sample sessions</h3>
-
-<p>this is a minimal tutorial, showing by example what you can do with
-and expect from this library.  this text is directed to scripts
-authors who want to be able to log the activity of their programs.</p>
-
-<p>this page is organized in sections.  each section can be seen and
-tried out as a separate R session.  at the end of the section there's
-a link to a R script with the R instructions tried in the section.</p>
-
-<p>this logging library attempts to be as compatible as possible (that
-is: as it was conceivable to the author) to the
-standard <a href="http://docs.python.org/library/logging.html">Python
-logging</a> library.  if you are accustomed to that logging library,
-this one will look familiar to you.</p>
-
-<h4>the basics</h4>
-
-<p>in this session we work with one single logger, the root logger, and we use only console handlers.</p>
-
-<p>start up R, load the library, use the basic configuration.</p>
-<code>
-R> <user>library(logging)</user><br/>
-R> <user>basicConfig()</user><br/>
-R>
-</code>
-
-<p>let's check the effect of the above actions.  our loggers are
-environments, so we can use for example <tt>ls</tt> and <tt>with</tt>
-to inspect them.  after this basic configuration, our logger has
-handlers and a level and it contains one handler.  this is enough for
-some simple logging to the console.  the default logging level of the
-root logger is <tt>INFO</tt> (20).  anything at severity lower
-than <tt>INFO</tt> will not be logged.</p>
-
-<code>
-R> <user>ls(getLogger())</user><br/>
-[1] "handlers" "level"<br/>
-R> <user>with(getLogger(), level)</user><br/>
-INFO <br/>
-&nbsp; 20 <br/>
-R> <user>with(getLogger(), names(handlers))</user><br/>
-[1] "basic.stdout"<br/>
-R> <user>loginfo('does it work?')</user><br/>
-2010-04-08 11:28:35 INFO::does it work?<br/>
-R> <user>logwarn('my %s is %d', 'name', 5)</user><br/>
-2010-04-08 11:28:48 WARN::my name is 5<br/>
-R> <user>logdebug('I am a silent child')</user><br/>
-R>
-</code>
-
-<p>we add an other handler to the console, without specifying its
-name.  it gets one automatically from the name of the function.  you
-can add and remove handlers using their names.  you can also refer to
-them by function, if that is the way you defined it.</p>
-
-<code>
-R> <user>addHandler(writeToConsole)</user><br/>
-R> <user>with(getLogger(), names(handlers))</user><br/>
-[1] "basic.stdout"   "writeToConsole"<br/>
-R> <user>loginfo('test')</user><br/>
-2010-04-07 11:31:06 INFO::test<br/>
-2010-04-07 11:31:06 INFO::test<br/>
-R> <user>logwarn('test')</user><br/>
-2010-04-07 11:31:15 WARN::test<br/>
-2010-04-07 11:31:15 WARN::test<br/>
-R> <user>removeHandler('writeToConsole')</user><br/>
-R> <user>logwarn('test')</user><br/>
-2010-04-07 11:32:37 WARN::test<br/>
-R>
-</code>
-
-<p>handlers have a level associated to them.  any logging record
-passing through a handler and having a severity lower than the level
-of the handler is ignored.  you can alter the level of a handler.
-this is what we do in the following lines: we alter the level of the
-default console handler 'basic.stdout' to 30 (<tt>WARN</tt>).  by the
-way, also handlers are environments.</p>
-
-<code>
-R> <user>addHandler(writeToConsole)</user><br/>
-R> <user>setLevel(30, getHandler('basic.stdout'))</user><br/>
-R> <user>loginfo('test')</user><br/>
-R> <user>logwarn('test')</user><br/>
-2010-04-07 15:17:40 WARN::test <br/>
-R> <user>with(getHandler('basic.stdout'), level)</user><br/>
-WARN <br/>
-&nbsp; 30 <br/>
-R> 
-</code>
-
-<p><a href="the_basics.R">code</a></p>
-
-<h4>hierarchical loggers</h4>
-
-<p>in the previous section we have worked -implicitly- with one
-logger, the root logger.  we can refer to it explicitly by specifying
-the 'logger' parameter in our function calls.  the name of the root
-logger is the empty string.  this also explains that "::" in the
-messages sent to the console, between the first and the second ":"
-there's the name of the logger that is associated to the log record
-shown.</p>
-
-<code>
-R> <user>with(getLogger(logger=''), names(handlers))</user><br/>
-[1] "basic.stdout"<br/>
-R> <user>with(getLogger('libro'), names(handlers))</user><br/>
-NULL
-</code>
-
-<p>when issuing a logging record, you can specify to which logger you
-want to send it.  loggers are created when first needed, so we can
-just assume all loggers we need also exist.  the logger will offer it
-to all its attached handlers and then pass it to its parent logger.
-loggers are organized hierarchically, in a way that is similar to the
-way directories are organized.  </p>
-
-<p>just as directories contain files, loggers contain handlers and
-their name is, within the logger, unique.  also similarly than to
-directories, all loggers have one parent, except the root logger that
-has none.  the name of the logger specifies the location of the logger
-in this hierarchy.  an example will hopefully clarify.  </p>
-
-<p>let's start from scratch, either a brand new R session or by
-resetting the logging system.</p>
-
-<code>
-R> <user>logReset()</user><br/>
-R> <user>addHandler(writeToConsole, logger='libro.romanzo')</user><br/>
-R> <user>loginfo('chiarastella', logger='libro.romanzo.campanile')</user><br/>
-2010-04-08 11:18:59 INFO:libro.romanzo.campanile:chiarastella<br/>
-R> <user>loginfo('memories of a survivor', logger='libro.romanzo.lessing')</user><br/>
-2010-04-08 11:22:06 INFO:libro.romanzo.lessing:memories of a survivor<br/>
-R> <user>logwarn('talking to a hierarchically upper logger', logger='libro')</user><br/>
-R> <user>logerror('talking to an unrelated logger', logger='rivista.cucina')</user><br/>
-R> 
-</code>
-
-<p>notice that loggers are automatically defined by the simple action
-of naming them.  what happened above is that the handler we created,
-attached to the 'libro.romanzo' logger, only saw the records going to
-the loggers below its logger.  all records going to hierarchically
-upper loggers or to unrelated loggers are not logged, regardless of
-their severity.</p>
-
-<p>also notice that the text printed doesn't contain any more that
-"::".  between the two ":" there's the name of the logger that
-received the logging record in the first place.</p>
-
-<p><a href="hierarchical_loggers.R">code</a></p>
-
-<h4>logging to file</h4>
-
-<p>actually the name of this paragraph is misleading.  a more correct
-name would be <em>handling to file</em>, since it's a handler and not
-a logger that is actually writing some representation of your
-logrecords to a file.  </p>
-
-<p>to make sure log records are sent to a file, you choose a logger
-and attach to it a handler with action a function that writes to your
-file.  the logging package exports the commodity
-function <tt>writeToFile</tt> for this purpouse.  the name of the file
-is given as an extra parameter in the call to <tt>addHandler</tt>.</p>
-
-<p>recall that both loggers <em>and</em> handlers have a level.
-records at a specific severity are examined by loggers first; if the
-severity is higher than the level of the logger, they are offered to
-all of the attached handlers.  handlers will again check the level of
-the record before taking action.  in the following example we make
-sure absolutely all logrecords are examined by initializing the root
-logger at the <tt>FINEST</tt> level.  the level of
-the <tt>basic_stdout</tt> console handler is not affected.</p>
-
-<code>
-R> <user>logReset()</user><br/>
-R> <user>basicConfig(level='FINEST')</user><br/>
-R> <user>addHandler(writeToFile, file="~/testing.log", level='DEBUG')</user><br/>
-R> <user>with(getLogger(), names(handlers))</user><br/>
-[1] "basic.stdout"   "writeToFile"<br/>
-R> <user>loginfo('test %d', 1)</user><br/>
-2010-04-07 11:31:06 INFO::test 1<br/>
-R> <user>logdebug('test %d', 2)</user><br/>
-R> <user>logwarn('test %d', 3)</user><br/>
-2010-04-07 11:31:15 WARN::test 3<br/>
-R> <user>logfinest('test %d', 4)</user><br/>
-R> 
-</code>
-
-<p>if the file was not existing or empty, this would be its content after the above steps:</p>
-<code>
-2010-04-07 11:31:06 INFO::test 1<br/>
-2010-04-07 11:31:11 DEBUG::test 2<br/>
-2010-04-07 11:31:15 WARN::test 3<br/>
-</code>
-
-<p>all log records have been passed to both
-handlers <tt>basic.stdout</tt> and <tt>writeToFile</tt>.  the default
-console handler has handled records with severity at or
-above <tt>INFO</tt>, our file handler had threshold <tt>DEBUG</tt> so
-it handled also the second record in the example session.  the fourth
-record was dropped by both handlers.</p>
-
-<p><a href="logging_to_file.R">code</a></p>
-
-<h4>formatting your log records</h4>
-
-<p>in this session we are going to see how to generate a diagnostics
-file for a system that organizes logrecords in a different way than
-Python.  let's jump into the implementation, if you can write R you
-surely won't need more explaination but will want to tell me how to
-make this function faster, more readable, shorter...</p>
-
-<code>
-<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'</R-string>, level, record$timestamp, record$msg)<br/>
-}
-</code>
-
-<p>notice that the field <tt>$msg</tt> of a record is already
-"formatted", as we have seen with <tt>logwarn('my %s is %d', 'name',
-5)</tt>.  that part can be used but not undone any more.  the
-formatter you can associate to a handler can combine the tags in the
-logrecord to produce a string.</p>
-
-<p>when you add a handler to a logger, you can use
-the <tt>formatter</tt> parameter to associate to the handler a
-function that takes a logrecord and returns a string.  the above
-example function is such a function.  </p>
-
-
-<p>if you don't specify the <tt>formatter</tt> parameter, the default
-formatter is used, which looks like this:</p>
-
-<code>
-<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 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-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'</R-string>,<br/>
-&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  formatter=formatter.fewsdiagnostics)<br/>
-}<br/>
-<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>
-
-<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>

Copied: www/sample_session.php (from rev 32, www/sample_session.html)
===================================================================
--- www/sample_session.php	                        (rev 0)
+++ www/sample_session.php	2010-04-09 13:35:27 UTC (rev 33)
@@ -0,0 +1,32 @@
+<html>
+<head>
+  <title>sample sessions</title>
+  <link href="additions.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<h3>annotated sample sessions</h3>
+
+<p>this is a minimal tutorial, showing by example what you can do with
+and expect from this library.  this text is directed to scripts
+authors who want to be able to log the activity of their programs.</p>
+
+<p>this page is organized in sections.  each section can be seen and
+tried out as a separate R session.  at the end of the section there's
+a link to a R script with the R instructions tried in the section.</p>
+
+<p>the same information, one page at a time:
+<a href="the_basics.php">[the basics]</a>
+<a href="hierarchical_loggers.php">[hierarchical loggers]</a>
+<a href="logging_to_file.php">[logging to file]</a>
+<a href="formatting_your_log_records.php">[formatting your log records]</a>
+<a href="writing_your_own_handlers.php">[writing your own handlers]</a>
+</p>
+
+<?php include("the_basics.shtml"); ?> 
+<?php include("hierarchical_loggers.shtml"); ?> 
+<?php include("logging_to_file.shtml"); ?> 
+<?php include("formatting_your_log_records.shtml"); ?> 
+<?php include("writing_your_own_handlers.shtml"); ?> 
+
+</body>
+</html>

Added: www/the_basics.php
===================================================================
--- www/the_basics.php	                        (rev 0)
+++ www/the_basics.php	2010-04-09 13:35:27 UTC (rev 33)
@@ -0,0 +1,17 @@
+<html>
+<head>
+<title>tutorial : the basics</title>
+<link href="additions.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+
+<p>
+<a href="sample_session.php">[back to the tutorial]</a>
+[previous session]
+<a href="hierarchical_loggers.php">[next session]</a>
+</p>
+
+<?php include("the_basics.shtml"); ?> 
+
+</body>
+</html>
\ No newline at end of file

Added: www/the_basics.shtml
===================================================================
--- www/the_basics.shtml	                        (rev 0)
+++ www/the_basics.shtml	2010-04-09 13:35:27 UTC (rev 33)
@@ -0,0 +1,83 @@
+<h4>the basics</h4>
+
+<p>this logging library attempts to be as compatible as possible (that
+is: as it was conceivable to the author) to the
+standard <a href="http://docs.python.org/library/logging.html">Python
+logging</a> library.  if you are accustomed to that logging library,
+this one will look familiar to you.</p>
+
+<p>in this session we work with one single logger, the root logger, and we use only console handlers.</p>
+
+<p>start up R, load the library, use the basic configuration.</p>
+
+<code>
+R> <user>library(logging)</user><br/>
+R> <user>basicConfig()</user><br/>
+R>
+</code>
+
+<p>let's check the effect of the above actions.  our loggers are
+environments, so we can use for example <tt>ls</tt> and <tt>with</tt>
+to inspect them.  after this basic configuration, our logger has
+handlers and a level and it contains one handler.  this is enough for
+some simple logging to the console.  the default logging level of the
+root logger is <tt>INFO</tt> (20).  anything at severity lower
+than <tt>INFO</tt> will not be logged.</p>
+
+<code>
+R> <user>ls(getLogger())</user><br/>
+[1] "handlers" "level"<br/>
+R> <user>with(getLogger(), level)</user><br/>
+INFO <br/>
+&nbsp; 20 <br/>
+R> <user>with(getLogger(), names(handlers))</user><br/>
+[1] "basic.stdout"<br/>
+R> <user>loginfo('does it work?')</user><br/>
+2010-04-08 11:28:35 INFO::does it work?<br/>
+R> <user>logwarn('my %s is %d', 'name', 5)</user><br/>
+2010-04-08 11:28:48 WARN::my name is 5<br/>
+R> <user>logdebug('I am a silent child')</user><br/>
+R>
+</code>
+
+<p>we add an other handler to the console, without specifying its
+name.  it gets one automatically from the name of the function.  you
+can add and remove handlers using their names.  you can also refer to
+them by function, if that is the way you defined it.</p>
+
+<code>
+R> <user>addHandler(writeToConsole)</user><br/>
+R> <user>with(getLogger(), names(handlers))</user><br/>
+[1] "basic.stdout"   "writeToConsole"<br/>
+R> <user>loginfo('test')</user><br/>
+2010-04-07 11:31:06 INFO::test<br/>
+2010-04-07 11:31:06 INFO::test<br/>
+R> <user>logwarn('test')</user><br/>
+2010-04-07 11:31:15 WARN::test<br/>
+2010-04-07 11:31:15 WARN::test<br/>
+R> <user>removeHandler('writeToConsole')</user><br/>
+R> <user>logwarn('test')</user><br/>
+2010-04-07 11:32:37 WARN::test<br/>
+R>
+</code>
+
+<p>handlers have a level associated to them.  any logging record
+passing through a handler and having a severity lower than the level
+of the handler is ignored.  you can alter the level of a handler.
+this is what we do in the following lines: we alter the level of the
+default console handler 'basic.stdout' to 30 (<tt>WARN</tt>).  by the
+way, also handlers are environments.</p>
+
+<code>
+R> <user>addHandler(writeToConsole)</user><br/>
+R> <user>setLevel(30, getHandler('basic.stdout'))</user><br/>
+R> <user>loginfo('test')</user><br/>
+R> <user>logwarn('test')</user><br/>
+2010-04-07 15:17:40 WARN::test <br/>
+R> <user>with(getHandler('basic.stdout'), level)</user><br/>
+WARN <br/>
+&nbsp; 30 <br/>
+R> 
+</code>
+
+<p><a href="the_basics.R">code</a></p>

Added: www/writing_your_own_handlers.php
===================================================================
--- www/writing_your_own_handlers.php	                        (rev 0)
+++ www/writing_your_own_handlers.php	2010-04-09 13:35:27 UTC (rev 33)
@@ -0,0 +1,17 @@
+<html>
+<head>
+<title>tutorial : writing your own handlers</title>
+<link href="additions.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+
+<p>
+<a href="sample_session.php">[back to the tutorial]</a> &nbsp;
+<a href="formatting_your_log_records.php">[previous session]</a> &nbsp;
+[next session]
+</p>
+
+<?php include("writing_your_own_handlers.shtml"); ?> 
+
+</body>
+</html>
\ No newline at end of file

Added: www/writing_your_own_handlers.shtml
===================================================================
[TRUNCATED]

To get the complete diff run:
    svnlook diff /svnroot/logging -r 33


More information about the Logging-commits mailing list