[Zope3-checkins] CVS: Zope3/doc - LOGGING.txt:1.11

Guido van Rossum guido@python.org
Thu, 19 Dec 2002 22:18:46 -0500


Update of /cvs-repository/Zope3/doc
In directory cvs.zope.org:/tmp/cvs-serv16489

Modified Files:
	LOGGING.txt 
Log Message:
An introduction to PEP 282 style logging.


=== Zope3/doc/LOGGING.txt 1.10 => 1.11 ===
--- Zope3/doc/LOGGING.txt:1.10	Thu Dec 19 18:15:35 2002
+++ Zope3/doc/LOGGING.txt	Thu Dec 19 22:18:45 2002
@@ -1,5 +1,134 @@
-Zope Logging
+Zope 3 Logging
 
  Logging is done through the logging package (PEP 282-based logging).
+ It is fairly easy to use and to configure.
 
- XXX This description needs to be updated.
+
+ Configuring the logging package for z3.py
+
+  The log file used by z3.py can be configured in the zserver.zcml
+  file with this directive::
+
+    <startup:useLog file="..." level="...">
+
+  The file argument should give the filename where you want the log to
+  go.  If the filename is STDERR or STDOUT, logging goes to the
+  process's standard error or standard output stream, respectively.
+
+  The level argument should give the logging severity level; anything
+  below this level is not logged.  The supported levels are, in
+  increasing severity: DEBUG, INFO, WARN, ERROR, CRITICAL.
+
+
+ Configuring the logging package for running unit tests
+
+  When running unit tests, logging is configured through the file
+  log.ini in the current directory, if it exists.  This file should be
+  self-explanatory, and provides full access to the logging package's
+  advanced features.  If log.ini is not found, critical messages are
+  logged to the process's standard error stream, and other messages
+  are not logged.
+
+
+ Using the logging package
+
+  There are two ways of using the logging package.  You can use
+  functions defined in the logging package directly, or you can use
+  methods on a logger object.  In either case you need a simple import
+  statement::
+
+    import logging
+
+
+ Using the logging functions
+
+  To use the logging functions defined by the package directly, use
+  one of the functions debug(), info(), warn(), error() or critical()
+  from the package.  Each of these takes a message argument.  The
+  message may be a standard Python format string, and then the
+  following arguments are the format arguments.  This allows you to
+  write, for example::
+
+    logging.warn("Cannot open file %r: %s", filename, err)
+
+  instead of::
+
+    logging.warn("Cannot open file %r: %s" % (filename, err))
+
+  Apart from slight savings in typing, the advantage of the former is
+  that if warnings are not logged, the string formatting operation is
+  not carried out, saving some time.
+
+  It is also possible to log a traceback.  This is done by adding a
+  keyword argument exc_info=True.  For example::
+
+    try:
+        ...something...
+    except:
+        logging.error("Unexpected problem", exc_info=True)
+
+  The logging package will call sys.exc_info() and use the traceback
+  module to format the traceback.  When the message is not logged,
+  this is skipped.  In fact, there's a shorthand for this particular
+  case (logging a traceback at the error level)::
+
+    try:
+        ...something...
+    except:
+        logging.exception("Unexpected problem")
+
+  Finally, there is a generic log function; it has a first argument
+  specifying a logging severity level, followed by the standard
+  arguments of all the above functions::
+
+    logging.log(level, message, ..., exc_info=...)
+
+  The predefined logging levels are available as symbolic constants:
+  logging.DEBUG, logging.INFO, logging.WARN, logging.ERROR, and
+  logging.CRITICAL.  (There's no logging.EXCEPTION level, because
+  exception() is not a separate logging level; it's a shorthand for
+  passing exc_info=True to the error() method.)
+
+
+ Using a logger object
+
+  Often you'd like all log messages coming out of a particular class
+  or module to be "tagged" with a label identifying that class or
+  module, regardless of the logging severity of the message.  In some
+  cases, you'd like that label to convey additional run-time
+  information, such as a storage or thread name.
+
+  Rather than prefixing all log messages with an identifying string,
+  you can create a logger object that does this for you.  Logger
+  objects have methods debug(), info(), etc., corresponding to the
+  logging functions described in the previous section, and with
+  exactly the same signature; these are what you use to log a message
+  using a logger object, for example::
+
+    logger.warn("Oil temperature: %g", temp)
+
+  To create a logger object, use the getLogger() function::
+
+    foo_bar_logger = logging.getLogger("foo.bar")
+
+  The string argument to getLogger() is interpreted as a sequence of
+  names separated by dots; this creates a hierarchy that can be used
+  for additional filtering or handling.  Normally, however, a logger
+  object inherits all its properties (except for its name) from its
+  parent logger object.  For the foo_bar_logger above, the parent
+  would be the logger object returned by this call::
+
+    foo_logger = logging.getLogger("foo")
+
+  Its parent in turn is the root logger; the logging functions
+  described in the previous section correspond to methods of the root
+  logger object.  By configuring the root logger you can configure all
+  loggers in the hierarchy, unless some configuration is overridden at
+  a lower level.  This an advanced feature of the logging module that
+  we won't discuss further here.
+
+  Logger objects are lightweight and cached by the logging module;
+  subseqent calls to logging.getLogger() with the same logger name
+  will return the same logger object.  However, there is no way to
+  delete logger objects, so it's not a good idea to make up arbitrary
+  logger names dynamically.