mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
bitkeeper revision 1.1108.1.8 (40ffc44fV2fs0W-8bRw5B0XcBdmAsw)
Add python 2.3 logging to the tree. Only install if not present. Convert xend to use logging.
This commit is contained in:
1 parent
6d88c800d3
commit
5b14d2aca3
63 files changed
+10896
-63
No files matched your search
@@ -311,6 +311,57 @@
|
||||
4056f5155QYZdsk-1fLdjsZPFTnlhg tools/misc/xensymoops.py
|
||||
40cf2937dqM1jWW87O5OoOYND8leuA tools/misc/xm
|
||||
40c9c468icGyC5RAF1bRKsCXPDCvsA tools/python/Makefile
|
||||
40ffc44dOwe1CcYXGCkYHdG_NxcccA tools/python/logging/logging-0.4.9.2/PKG-INFO
|
||||
40ffc44dpqpgqgrnLfR70PsiBc3liA tools/python/logging/logging-0.4.9.2/README.txt
|
||||
40ffc44ddfLckno4Gvzi3vZxwelZHQ tools/python/logging/logging-0.4.9.2/default.css
|
||||
40ffc44dKSkczdvpd_x7rWGH4_BRIQ tools/python/logging/logging-0.4.9.2/liblogging.tex
|
||||
40ffc44d2O51abh5t-1VTZfqhbS1ZQ tools/python/logging/logging-0.4.9.2/logging/__init__.py
|
||||
40ffc44dT8ustodG0hDjYMCzQ8UCbA tools/python/logging/logging-0.4.9.2/logging/config.py
|
||||
40ffc44dqbwdCcq6XgwpTvrUrABhhw tools/python/logging/logging-0.4.9.2/logging/handlers.py
|
||||
40ffc44dVEL3QwvZx_Rcl3d41WxMRQ tools/python/logging/logging-0.4.9.2/python_logging.html
|
||||
40ffc44dXypIfRTyuTD48cN0o-gAXg tools/python/logging/logging-0.4.9.2/setup.py
|
||||
40ffc44dqqdkY-Ox_eoPuNmQR0_ebw tools/python/logging/logging-0.4.9.2/test/app.py
|
||||
40ffc44d9vEJEV_44B-23sJHkT1-gA tools/python/logging/logging-0.4.9.2/test/critical.ini
|
||||
40ffc44dA5BiSVip8DlCh0DfAaQzbg tools/python/logging/logging-0.4.9.2/test/debug.ini
|
||||
40ffc44dAuxUnJx7Fu2puaiNheBRkg tools/python/logging/logging-0.4.9.2/test/error.ini
|
||||
40ffc44dkAIw1gbAzj_XiQyoru93_Q tools/python/logging/logging-0.4.9.2/test/events.xml
|
||||
40ffc44eZwnQ4wGs1zVaAGsnEoyz6Q tools/python/logging/logging-0.4.9.2/test/log_test.py
|
||||
40ffc44epbz06Y2nCkuYotfQFY4bJQ tools/python/logging/logging-0.4.9.2/test/log_test0.py
|
||||
40ffc44eVNdi9lXQOZ2n7yT1DXVQRQ tools/python/logging/logging-0.4.9.2/test/log_test1.py
|
||||
40ffc44eeqydHPpipbO4oVhRt90v0A tools/python/logging/logging-0.4.9.2/test/log_test10.py
|
||||
40ffc44eSum6e6Y_sh7hRBHnnRurfw tools/python/logging/logging-0.4.9.2/test/log_test11.py
|
||||
40ffc44euWPhfnbZw64ShBIrZot84A tools/python/logging/logging-0.4.9.2/test/log_test12.py
|
||||
40ffc44ekj8Hdg-2SLb0qdqJzGkXdA tools/python/logging/logging-0.4.9.2/test/log_test13.py
|
||||
40ffc44e5DnmO4OEa54mS8Q9AgP3rg tools/python/logging/logging-0.4.9.2/test/log_test14.py
|
||||
40ffc44e6uWMQdikNEzYeNeFewGQew tools/python/logging/logging-0.4.9.2/test/log_test15.py
|
||||
40ffc44eHJ_XsDp2Le-qc96G2n7GdQ tools/python/logging/logging-0.4.9.2/test/log_test16.py
|
||||
40ffc44eCIq8wSc2UI16VfkLPlW-SQ tools/python/logging/logging-0.4.9.2/test/log_test17.py
|
||||
40ffc44eHWycPlgiEpt8pE8xYTbUkg tools/python/logging/logging-0.4.9.2/test/log_test18.py
|
||||
40ffc44eeRuZcrB3tQzfrQnh22NBow tools/python/logging/logging-0.4.9.2/test/log_test19.py
|
||||
40ffc44e6jQPP-ASsVux4-ERGuDrmQ tools/python/logging/logging-0.4.9.2/test/log_test2.py
|
||||
40ffc44eNHf6r77J1VCNedKPTufY8Q tools/python/logging/logging-0.4.9.2/test/log_test20.py
|
||||
40ffc44emS2gplqyEwbcLS43QNrnyA tools/python/logging/logging-0.4.9.2/test/log_test21.py
|
||||
40ffc44e1Ojd79zACM2KAnXZyO3Nuw tools/python/logging/logging-0.4.9.2/test/log_test22.py
|
||||
40ffc44ektXcwDnK4h4HqMHFSTA3BA tools/python/logging/logging-0.4.9.2/test/log_test3.ini
|
||||
40ffc44e8ka-b5_nPYzWn0hXDSagMw tools/python/logging/logging-0.4.9.2/test/log_test3.py
|
||||
40ffc44eVmFkQt7FaHxspmMV7IZLxw tools/python/logging/logging-0.4.9.2/test/log_test4.py
|
||||
40ffc44eYJ7tjlUpS5bIF9I8YKK39g tools/python/logging/logging-0.4.9.2/test/log_test5.py
|
||||
40ffc44eo9GvB3GvC2Aoaxu74ffS4A tools/python/logging/logging-0.4.9.2/test/log_test6.py
|
||||
40ffc44eajjKGx6tj2nOVuYCfy-PoA tools/python/logging/logging-0.4.9.2/test/log_test7.py
|
||||
40ffc44eEM_uMfIGRNoxRSP7_jpc7w tools/python/logging/logging-0.4.9.2/test/log_test8.py
|
||||
40ffc44e4NBnAweOds3owURsSHZKyQ tools/python/logging/logging-0.4.9.2/test/log_test9.py
|
||||
40ffc44eu_SYlzJ464qUFb8fdSGHsg tools/python/logging/logging-0.4.9.2/test/logconf.ini
|
||||
40ffc44eTnvlvCSmjgGgfcOBm6SSAw tools/python/logging/logging-0.4.9.2/test/logconf.py
|
||||
40ffc44egchRehfcmsPX0WdV06yp_w tools/python/logging/logging-0.4.9.2/test/logging.dtd
|
||||
40ffc44ee9peTFswy96mwgBslmqEvQ tools/python/logging/logging-0.4.9.2/test/logging.xml
|
||||
40ffc44ekRTWScJDGTe7k2aAp_ltRg tools/python/logging/logging-0.4.9.2/test/logrecv.ini
|
||||
40ffc44eeQBA_QbbwrucZfYtksuEMA tools/python/logging/logging-0.4.9.2/test/logrecv.py
|
||||
40ffc44eECASCQD_QL3wJd4dyK2KVg tools/python/logging/logging-0.4.9.2/test/myapp.py
|
||||
40ffc44eUwKMOAwPTIBq0A8N8b56HQ tools/python/logging/logging-0.4.9.2/test/mymodule.py
|
||||
40ffc44evyvayldKLSsizMmsDpBtkQ tools/python/logging/logging-0.4.9.2/test/stderr.exp
|
||||
40ffc44eb-39RIR551oZoTiK11amSw tools/python/logging/logging-0.4.9.2/test/stdout.exp
|
||||
40ffc44eGvzBilqBZEozKaMHz-HdxA tools/python/logging/logging-0.4.9.2/test/warn.ini
|
||||
40ffc44eLXLuINsYi8eG0oJ6a2dSRA tools/python/logging/setup.py
|
||||
40c9c469n2RRwCmjWdjdyyVRWKmgWg tools/python/setup.py
|
||||
40dc4076hGpwa8-sWRN0jtXZeQJuKg tools/python/xen/__init__.py
|
||||
40dfd40aMOhnw_cQLve9462UR5yYxQ tools/python/xen/lowlevel/__init__.py
|
||||
@@ -336,6 +387,7 @@
|
||||
40c9c468bbKq3uC7_fuNUkiMMjArdw tools/python/xen/xend/XendDomainConfig.py
|
||||
40c9c4685ykq87_n1kVUbMr9flx9fg tools/python/xen/xend/XendDomainInfo.py
|
||||
40f50d99YiiaMI1fZBh1VCDFLD57qg tools/python/xen/xend/XendError.py
|
||||
40ffc44eGsgTEY355E3nN4mPLZHhMQ tools/python/xen/xend/XendLogging.py
|
||||
40c9c46854nsHmuxHQHncKk5rAs5NA tools/python/xen/xend/XendMigrate.py
|
||||
40c9c468M96gA1EYDvNa5w5kQNYLFA tools/python/xen/xend/XendNode.py
|
||||
40c9c4686jruMyZIqiaZRMiMoqMJtg tools/python/xen/xend/XendRoot.py
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
Metadata-Version: 1.0
|
||||
Name: logging
|
||||
Version: 0.4.9.2
|
||||
Summary: A logging module for Python
|
||||
Home-page: http://www.red-dove.com/python_logging.html
|
||||
Author: Vinay Sajip
|
||||
Author-email: vinay_sajip@red-dove.com
|
||||
License: Copyright (C) 2001-2004 by Vinay Sajip. All Rights Reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Vinay Sajip
|
||||
not be used in advertising or publicity pertaining to distribution
|
||||
of the software without specific, written prior permission.
|
||||
|
||||
VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
Description: This module is intended to provide a standard error logging mechanism in Python as per PEP 282.
|
||||
Platform: UNKNOWN
|
||||
@@ -0,0 +1,311 @@
|
||||
This module is intended to provide error logging functionality for Python
|
||||
programs. It aims to be aligned with Python Enhancement Proposal (PEP) 282.
|
||||
|
||||
For more information on the package itself, see python_logging.html. In it,
|
||||
there is a description of each file in the distribution.
|
||||
You can also use pydoc to browse the interfaces.
|
||||
|
||||
Change History
|
||||
--------------
|
||||
|
||||
Version Date Description
|
||||
=============================================================================
|
||||
0.4.9.2 28 Feb 2004 Traceback text is now cached.
|
||||
Tracebacks can be propagated across sockets as text.
|
||||
Added makeLogRecord() to allow a LogRecord to be
|
||||
created from a dictionary.
|
||||
Closing a handler now removes it from the internal list
|
||||
used by shutdown().
|
||||
Made close() call flush() for handlers where this makes
|
||||
sense (thanks to Jim Jewett).
|
||||
The exc_info keyword parameter can be used to pass an
|
||||
exception tuple as well as a flag indicating that the
|
||||
current exception should be logged.
|
||||
A shutdown hook is registered to call shutdown() on
|
||||
application (Python) exit (thanks to Jim Jewett).
|
||||
Removed redundant error check in setLoggerClass().
|
||||
Added RESET_ERROR to logging.config.
|
||||
SocketHandler now uses an exponential backoff strategy
|
||||
(thanks to Robert Olson).
|
||||
Minor documentation corrections.
|
||||
-----------------------------------------------------------------------------
|
||||
0.4.8 22 Apr 2003 Made _listener global in stopListening().
|
||||
Made listen() correctly pass the specified port.
|
||||
Removed some redundant imports in __init__.py.
|
||||
Added the record being processed as a parameter to
|
||||
handleError (thanks to Gordon den Otter for the idea).
|
||||
Handler.handle returns the result of applying the
|
||||
filter to the record (thanks to Gordon den Otter for
|
||||
the idea).
|
||||
Added a seek(0, 2) in RotatingFileHandler before the
|
||||
tell() call. This is because under Windows, tell()
|
||||
returns 0 until the first actual write (thanks to
|
||||
Gordon den Otter for the patch).
|
||||
Altered findCaller to not use inspect (thanks to
|
||||
Jeremy Hylton for the patch).
|
||||
Renamed warn and WARN to warning and WARNING. This may
|
||||
break existing code, but the standard Python module
|
||||
will use warning/WARNING rather than warn/WARN. The
|
||||
fatal and FATAL synonyms for critical and CRITICAL
|
||||
have also been removed.
|
||||
Added defaultEncoding and some support for encoding
|
||||
Unicode messages (thanks to Stéphane Bidoul for the
|
||||
suggestion).
|
||||
Added process ID to the list of LogRecord attributes.
|
||||
Modified Logger.removeHandler so that it does not
|
||||
close the handler on removal.
|
||||
Modified SMTPHandler to treat a single "to address"
|
||||
correctly (thanks to Anthony Baxter).
|
||||
Modified SMTPHandler to add a date header to the SMTP
|
||||
message (thanks to David Driver for the suggestion).
|
||||
Modified HTTPHandler to factor out the mapping of
|
||||
a LogRecord to a dictionary (thanks to Franz Glasner
|
||||
for the patch).
|
||||
-----------------------------------------------------------------------------
|
||||
0.4.7 15 Nov 2002 Made into a package with three modules: __init__ (the
|
||||
core code), handlers (all handlers other than
|
||||
FileHandler and its bases) and config (all the config
|
||||
stuff). Before doing this:
|
||||
Updated docstrings to include a short line, then a
|
||||
blank line, then more descriptive text.
|
||||
Renamed 'lvl' to 'level' in various functions.
|
||||
Changed FileHandler to use "a" and "w" instead of "a+"
|
||||
and "w+".
|
||||
Moved log file rotation functionality from FileHandler
|
||||
to a new class RotatingFileHandler.
|
||||
Improved docstring describing rollover.
|
||||
Updated makePickle to use 4-byte length and struct
|
||||
module, likewise logrecv.py. Also updated on-the-fly
|
||||
config reader to use 4-byte length/struct module.
|
||||
Altered ConfigParser test to look at 'readline' rather
|
||||
than 'read'.
|
||||
Added optional "defaults" argument to fileConfig, to
|
||||
be passed to ConfigParser.
|
||||
Renamed ALL to NOTSET to avoid confusion.
|
||||
Commented out getRootLogger(), as obsolete.
|
||||
To do regression testing, run log_test.py and compare
|
||||
the created files stdout.log and stderr.log against
|
||||
the files stdout.exp and stderr.exp. They should match
|
||||
except fir a couple of exception messages which give
|
||||
absolute file paths.
|
||||
Updated python_logging.html to remove links to
|
||||
logging_pydoc.html, which has been removed from the
|
||||
distribution.
|
||||
Changed default for raiseExceptions to 1.
|
||||
-----------------------------------------------------------------------------
|
||||
0.4.6 08 Jul 2002 Added raiseExceptions to allow conditional propagation
|
||||
of exceptions which occur during handling.
|
||||
Added converter to Formatter to allow use of any
|
||||
function to convert time from seconds to a tuple. It
|
||||
still defaults to time.localtime but now you can also
|
||||
use time.gmtime.
|
||||
Added log_test22.py to test the conversion feature.
|
||||
Changed rootlogger default level to WARN - was DEBUG.
|
||||
Updated some docstrings.
|
||||
Moved import of threading to where thread is imported.
|
||||
If either is unavailable, threading support is off.
|
||||
Updated minor defects in python_logging.html.
|
||||
Check to see if ConfigParser has readfp method; if it
|
||||
does and an object with a 'read' method is passed in,
|
||||
assumes a file-like object and uses readfp to read it
|
||||
in.
|
||||
-----------------------------------------------------------------------------
|
||||
0.4.5 04 Jun 2002 Fixed bug which caused problem if no args to message
|
||||
(suggested by Hye-Shik Chang).
|
||||
Fixed bug in _fixupParents (thanks to Nicholas Veeser)
|
||||
and added log_test19.py as a test case for this bug.
|
||||
Added getMessage to LogRecord (code was moved here from
|
||||
Formatter.format)
|
||||
Applied str() to record.msg to allow arbitrary classes
|
||||
to determine the formatting (as msg can now be a class
|
||||
instance).
|
||||
Table of Contents added to python_logging.html, the
|
||||
section on Loggers updated, and the logconf.ini file
|
||||
section annotated.
|
||||
Added log_test20.py which demonstrates how to use
|
||||
class instances to provide alternatives to numeric
|
||||
severities as mechanisms for control of logging.
|
||||
Added log_test21.py which builds on log_test20.py to
|
||||
show how you can use a regular expression-based Filter
|
||||
for flexible matching similar to e.g. Protomatter
|
||||
Syslog, where you can filter on e.g. "a.*" or "*.b" or
|
||||
"a.*.c".
|
||||
_levelNames changed to contain reverse mappings as well
|
||||
as forward mappings (leveltext->level as well as level
|
||||
-> leveltext). The reverse mappings are used by
|
||||
fileConfig().
|
||||
fileConfig() now more forgiving of missing options in
|
||||
.ini file - sensible defaults now used when some
|
||||
options are absent. Also, eval() is used less when
|
||||
interpreting .ini file contents - int() and dict lookup
|
||||
are used in more places.
|
||||
-----------------------------------------------------------------------------
|
||||
0.4.4 02 May 2002 getEffectiveLevel() returns ALL instead of None when
|
||||
nothing found. Modified references to level=0 to
|
||||
level=ALL in a couple of places.
|
||||
SocketHandler now inherits from Handler (it used to
|
||||
inherit from StreamHandler, for no good reason).
|
||||
getLock() renamed to createLock().
|
||||
Docstring tidy-ups, and some tidying up of
|
||||
DatagramHandler.
|
||||
Factored out unpickling in logrecv.py.
|
||||
Added log_test18.py to illustrate MatchFilter, which is
|
||||
a general matching filter.
|
||||
Improved FileHandler.doRollover() so that the base
|
||||
file name is always the most recent, then .1, then .2
|
||||
etc. up to the maximum backup count. Renamed formal
|
||||
args and attributes used in rollover.
|
||||
Changed LogRecord attributes lvl -> levelno, level ->
|
||||
levelname (less ambiguity)
|
||||
Formatter.format searches for "%(asctime)" rather than
|
||||
"(asctime)"
|
||||
Renamed _start_time to _startTime
|
||||
Formatter.formatTime now returns the time
|
||||
Altered logrecv.py to support stopping servers
|
||||
programmatically
|
||||
Added log_test.py as overall test harness
|
||||
basicConfig() can now be safely called more than once
|
||||
Modified test scripts to make it easier to call them
|
||||
from log_test.py
|
||||
Moved SOAPHandler from core to log_test13.py. It's not
|
||||
general enough to be in the core; most production use
|
||||
will have differing RPC signatures.
|
||||
-----------------------------------------------------------------------------
|
||||
0.4.3 14 Apr 2002 Bug fix one-off error message to go to sys.stderr
|
||||
rather than sys.stdout.
|
||||
logrecv.py fix TCP for busy network.
|
||||
Thread safety - added locking to Handler and for shared
|
||||
data in module, and log_test16.py to test it.
|
||||
Added socket listener to allow on-the-fly configuration
|
||||
and added log_test17.py to test it.
|
||||
-----------------------------------------------------------------------------
|
||||
0.4.2 11 Apr 2002 Bug fix fileConfig() - setup of MemoryHandler target
|
||||
and errors when loggers have no handlers set or
|
||||
handlers have no formatters set
|
||||
logconf.py - seems to hang if window closed when combo
|
||||
dropdown is showing - added code to close popup on exit
|
||||
Some tweaks to _srcfile computation (normpath added)
|
||||
findCaller() optimized, now a lot faster!
|
||||
Logger.removeHandler now closes the handler before
|
||||
removing it
|
||||
fileConfig() removes existing handlers before adding
|
||||
the new set, to avoid memory leakage when repeated
|
||||
calls are made
|
||||
Fixed logrecv.py bug which hogged CPU time when TCP
|
||||
connection was closed from the client
|
||||
Added log_test14.py to demonstrate/test a DBHandler
|
||||
which writes logging records into an RDBMS using the
|
||||
Python Database API 2.0 (to run, you need something
|
||||
which supports this already installed - I tested with
|
||||
mxODBC)
|
||||
Made getLogger name argument optional - returns root
|
||||
logger if omitted
|
||||
Altered Filter to take a string initializer, filtering
|
||||
a sub-hierarchy rooted at a particular point (idea from
|
||||
Denis S. Otkidach).
|
||||
Added log_test15.py to test Filter initializer
|
||||
Minor docstring changes
|
||||
-----------------------------------------------------------------------------
|
||||
0.4.1 03 Apr 2002 Bug fix SMTPHandler - extra \r\n needed (Oleg Orlov)
|
||||
Added BufferingHandler, BufferingFormatter
|
||||
Renamed getChainedPriority to getEffectiveLevel
|
||||
Removed Logger.getRoot as it is redundant
|
||||
Added log_test9.py to test Buffering classes and
|
||||
to show an XMLFormatter example.
|
||||
Added setLoggerClass.
|
||||
Added log_test10.py to test setLoggerClass, using an
|
||||
example Logger-derived class which outputs exception
|
||||
info even for DEBUG level logging calls
|
||||
Added log_test11.py to test a buffering implementation
|
||||
of SMTPHandler
|
||||
Changed logging call implementation to allow keyword
|
||||
arguments (Kevin Butler and others)
|
||||
Changed default SysLogHandler implementation.
|
||||
Renamed "additive" to "propagate" as it better
|
||||
describes the attribute.
|
||||
Added HTTPHandler.
|
||||
Modified logrecv.py to remove "both" option and to add
|
||||
"HTTP" and "SOAP" options (SOAP option needs you to
|
||||
have PyXML-0.6.6 and ZSI installed - for logrecv.py
|
||||
only, and not for the core logging module itself).
|
||||
Added log_test12.py to test HTTPHandler.
|
||||
Added log_test13.py to test SOAPHandler.
|
||||
Formatted to Python source guidelines (spaces, indent
|
||||
of 4, within 80 columns).
|
||||
More method renamings (result of feedback) - _handle()
|
||||
renamed to emit(), _logRecord() renamed to handle().
|
||||
Renamed FATAL to CRITICAL (David Goodger), but left
|
||||
fatal() and FATAL in (until PEP is changed)
|
||||
Changed configuration file format to ConfigParser
|
||||
format.
|
||||
Factored filter application functionality out to a new
|
||||
Filterer class. The isLoggable() method is renamed to
|
||||
filter() in both Filter and Filterer classes.
|
||||
Altered SMTPHandler __init__ to accept (host, port)
|
||||
for the mail internet address.
|
||||
Added GUI configurator which uses Tkinter and the new
|
||||
configuration file format. (See logconf.py and an
|
||||
example configuration file in logconf.ini)
|
||||
Altered log_test3.py to test with the new file format.
|
||||
-----------------------------------------------------------------------------
|
||||
0.4 21 Mar 2002 Incorporated comments/patches from Ollie Rutherfurd:
|
||||
-Added level filtering for handlers.
|
||||
-Return root logger if no name specified in getLogger.
|
||||
Incorporated comments from Greg Ward:
|
||||
-Added distutils setup.py script.
|
||||
Added formatter initialization in Handler.__init__.
|
||||
Tidied up docstrings.
|
||||
Added removeHandler to Logger.
|
||||
Added removeFilter to Logger and Handler.
|
||||
logrecv.py modified to keep connection alive until
|
||||
client closes it.
|
||||
SocketHandler modified to not reset connection after
|
||||
each logging event.
|
||||
Added shutdown function which closes open sockets
|
||||
Renamed DEFAULT_LOGGING_PORT->DEFAULT_TCP_LOGGING_PORT
|
||||
Added DEFAULT_UDP_LOGGING_PORT
|
||||
Added log_test4.py (example of arbitrary levels)
|
||||
Added addLevelName, changed behaviour of getLevelName
|
||||
Fixed bugs in DatagramHandler
|
||||
Added SMTPHandler implementation
|
||||
Added log_test5.py to test SMTPHandler
|
||||
Added SysLogHandler (contribution from Nicolas Untz
|
||||
based on Sam Rushing's syslog.py)
|
||||
Modified log_test1.py to add a SysLogHandler
|
||||
Added rollover functionality to FileHandler
|
||||
Added NTEventLogHandler (based on Win32 extensions)
|
||||
Added MemoryHandler implementation
|
||||
Added log_test7.py to test MemoryHandler
|
||||
Added log_test8.py to test FileHandler rollover
|
||||
Added logException method to Logger
|
||||
Added formatException method to Formatter
|
||||
Added log_test6.py to test NTEventHandler and
|
||||
logException
|
||||
Numerous internal method renamings (sorry - but better
|
||||
to do this now, rather than when we enter beta status).
|
||||
-----------------------------------------------------------------------------
|
||||
0.3 14 Mar 2002 First public release, for early feedback
|
||||
-----------------------------------------------------------------------------
|
||||
0.2 Consolidated into single file (for internal use only)
|
||||
-----------------------------------------------------------------------------
|
||||
0.1 Initial implementation (for internal use only)
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
COPYRIGHT
|
||||
-----------------------------------------------------------------------------
|
||||
Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Vinay Sajip
|
||||
not be used in advertising or publicity pertaining to distribution
|
||||
of the software without specific, written prior permission.
|
||||
VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
@@ -0,0 +1,32 @@
|
||||
BODY, P, UL, OL {font-family: Verdana, Arial, Helvetica, Geneva, sans-serif ; background: white; color: black; font-size: 10pt; }
|
||||
CODE {font-family: "Courier New", Courier, Monaco, monospace ; }
|
||||
PRE {font-family: "Courier New", Courier, Monaco, monospace ; }
|
||||
.program { color: navy; font-family: "Courier New", Courier, Monaco, monospace }
|
||||
.output { color: maroon }
|
||||
HR {color: gray ; }
|
||||
.navbar { font-family: Verdana, Arial, Helvetica, Geneva, sans-serif; background: #FFFF66 ; border-style: none none solid none; border-width: thin; padding: 2px;}
|
||||
.navarea { background: #FFFF66 ; }
|
||||
TR { font-size: 10pt }
|
||||
.red { color: #FF0000 }
|
||||
.maroon { color: #800000 }
|
||||
.comment { color: green }
|
||||
.optional { color: silver }
|
||||
.strong { font-weight: bold }
|
||||
TR.tblheading { background: silver ; }
|
||||
.notrecommended {color: #666666 ; }
|
||||
.deemphasized {color: #666666 ; }
|
||||
TABLE.densetable {font-size: 80% ; }
|
||||
TH { text-align: left; background: silver }
|
||||
TR.summaryrow { font-size: 90%; background: #00FFFF ; }
|
||||
CAPTION {font-size: 100% ; }
|
||||
.embeddedfloat {float: right; margin-left: 3em}
|
||||
.bigtd { font-size: 18pt }
|
||||
TD, .normaltd { vertical-align: top; background: #EEEEEE; font-family: Verdana, Arial, Helvetica, Geneva, sans-serif; font-size: 10pt }
|
||||
H1, H2, H3, H4, H5, H6 {font-family: Verdana, Arial, Helvetica, Geneva, sans-serif ; }
|
||||
H4 {margin-bottom: 0.5em }
|
||||
H5, H6 {margin-bottom: 0.1em }
|
||||
A:link {color: blue ; }
|
||||
A:visited {color: purple ; }
|
||||
A:active {color: red ; }
|
||||
A { font-family: Verdana, Arial, Helvetica, Geneva, sans-serif; font-size: 10pt }
|
||||
.warning { color: red }
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,301 @@
|
||||
# Copyright 2001-2004 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
"""
|
||||
Configuration functions for the logging package for Python. The core package
|
||||
is based on PEP 282 and comments thereto in comp.lang.python, and influenced
|
||||
by Apache's log4j system.
|
||||
|
||||
Should work under Python versions >= 1.5.2, except that source line
|
||||
information is not available unless 'sys._getframe()' is.
|
||||
|
||||
Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved.
|
||||
|
||||
To use, simply 'import logging' and log away!
|
||||
"""
|
||||
|
||||
import sys, logging, logging.handlers, string, thread, threading, socket, struct, os
|
||||
|
||||
from SocketServer import ThreadingTCPServer, StreamRequestHandler
|
||||
|
||||
|
||||
DEFAULT_LOGGING_CONFIG_PORT = 9030
|
||||
|
||||
if sys.platform == "win32":
|
||||
RESET_ERROR = 10054 #WSAECONNRESET
|
||||
else:
|
||||
RESET_ERROR = 104 #ECONNRESET
|
||||
|
||||
#
|
||||
# The following code implements a socket listener for on-the-fly
|
||||
# reconfiguration of logging.
|
||||
#
|
||||
# _listener holds the server object doing the listening
|
||||
_listener = None
|
||||
|
||||
def fileConfig(fname, defaults=None):
|
||||
"""
|
||||
Read the logging configuration from a ConfigParser-format file.
|
||||
|
||||
This can be called several times from an application, allowing an end user
|
||||
the ability to select from various pre-canned configurations (if the
|
||||
developer provides a mechanism to present the choices and load the chosen
|
||||
configuration).
|
||||
In versions of ConfigParser which have the readfp method [typically
|
||||
shipped in 2.x versions of Python], you can pass in a file-like object
|
||||
rather than a filename, in which case the file-like object will be read
|
||||
using readfp.
|
||||
"""
|
||||
import ConfigParser
|
||||
|
||||
cp = ConfigParser.ConfigParser(defaults)
|
||||
if hasattr(cp, 'readfp') and hasattr(fname, 'readline'):
|
||||
cp.readfp(fname)
|
||||
else:
|
||||
cp.read(fname)
|
||||
#first, do the formatters...
|
||||
flist = cp.get("formatters", "keys")
|
||||
if len(flist):
|
||||
flist = string.split(flist, ",")
|
||||
formatters = {}
|
||||
for form in flist:
|
||||
sectname = "formatter_%s" % form
|
||||
opts = cp.options(sectname)
|
||||
if "format" in opts:
|
||||
fs = cp.get(sectname, "format", 1)
|
||||
else:
|
||||
fs = None
|
||||
if "datefmt" in opts:
|
||||
dfs = cp.get(sectname, "datefmt", 1)
|
||||
else:
|
||||
dfs = None
|
||||
f = logging.Formatter(fs, dfs)
|
||||
formatters[form] = f
|
||||
#next, do the handlers...
|
||||
#critical section...
|
||||
logging._acquireLock()
|
||||
try:
|
||||
try:
|
||||
#first, lose the existing handlers...
|
||||
logging._handlers.clear()
|
||||
#now set up the new ones...
|
||||
hlist = cp.get("handlers", "keys")
|
||||
if len(hlist):
|
||||
hlist = string.split(hlist, ",")
|
||||
handlers = {}
|
||||
fixups = [] #for inter-handler references
|
||||
for hand in hlist:
|
||||
sectname = "handler_%s" % hand
|
||||
klass = cp.get(sectname, "class")
|
||||
opts = cp.options(sectname)
|
||||
if "formatter" in opts:
|
||||
fmt = cp.get(sectname, "formatter")
|
||||
else:
|
||||
fmt = ""
|
||||
klass = eval(klass, vars(logging))
|
||||
args = cp.get(sectname, "args")
|
||||
args = eval(args, vars(logging))
|
||||
h = apply(klass, args)
|
||||
if "level" in opts:
|
||||
level = cp.get(sectname, "level")
|
||||
h.setLevel(logging._levelNames[level])
|
||||
if len(fmt):
|
||||
h.setFormatter(formatters[fmt])
|
||||
#temporary hack for FileHandler and MemoryHandler.
|
||||
if klass == logging.handlers.MemoryHandler:
|
||||
if "target" in opts:
|
||||
target = cp.get(sectname,"target")
|
||||
else:
|
||||
target = ""
|
||||
if len(target): #the target handler may not be loaded yet, so keep for later...
|
||||
fixups.append((h, target))
|
||||
handlers[hand] = h
|
||||
#now all handlers are loaded, fixup inter-handler references...
|
||||
for fixup in fixups:
|
||||
h = fixup[0]
|
||||
t = fixup[1]
|
||||
h.setTarget(handlers[t])
|
||||
#at last, the loggers...first the root...
|
||||
llist = cp.get("loggers", "keys")
|
||||
llist = string.split(llist, ",")
|
||||
llist.remove("root")
|
||||
sectname = "logger_root"
|
||||
root = logging.root
|
||||
log = root
|
||||
opts = cp.options(sectname)
|
||||
if "level" in opts:
|
||||
level = cp.get(sectname, "level")
|
||||
log.setLevel(logging._levelNames[level])
|
||||
for h in root.handlers[:]:
|
||||
root.removeHandler(h)
|
||||
hlist = cp.get(sectname, "handlers")
|
||||
if len(hlist):
|
||||
hlist = string.split(hlist, ",")
|
||||
for hand in hlist:
|
||||
log.addHandler(handlers[hand])
|
||||
#and now the others...
|
||||
#we don't want to lose the existing loggers,
|
||||
#since other threads may have pointers to them.
|
||||
#existing is set to contain all existing loggers,
|
||||
#and as we go through the new configuration we
|
||||
#remove any which are configured. At the end,
|
||||
#what's left in existing is the set of loggers
|
||||
#which were in the previous configuration but
|
||||
#which are not in the new configuration.
|
||||
existing = root.manager.loggerDict.keys()
|
||||
#now set up the new ones...
|
||||
for log in llist:
|
||||
sectname = "logger_%s" % log
|
||||
qn = cp.get(sectname, "qualname")
|
||||
opts = cp.options(sectname)
|
||||
if "propagate" in opts:
|
||||
propagate = cp.getint(sectname, "propagate")
|
||||
else:
|
||||
propagate = 1
|
||||
logger = logging.getLogger(qn)
|
||||
if qn in existing:
|
||||
existing.remove(qn)
|
||||
if "level" in opts:
|
||||
level = cp.get(sectname, "level")
|
||||
logger.setLevel(logging._levelNames[level])
|
||||
for h in logger.handlers[:]:
|
||||
logger.removeHandler(h)
|
||||
logger.propagate = propagate
|
||||
logger.disabled = 0
|
||||
hlist = cp.get(sectname, "handlers")
|
||||
if len(hlist):
|
||||
hlist = string.split(hlist, ",")
|
||||
for hand in hlist:
|
||||
logger.addHandler(handlers[hand])
|
||||
#Disable any old loggers. There's no point deleting
|
||||
#them as other threads may continue to hold references
|
||||
#and by disabling them, you stop them doing any logging.
|
||||
for log in existing:
|
||||
root.manager.loggerDict[log].disabled = 1
|
||||
except:
|
||||
import traceback
|
||||
ei = sys.exc_info()
|
||||
traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
|
||||
del ei
|
||||
finally:
|
||||
logging._releaseLock()
|
||||
|
||||
def listen(port=DEFAULT_LOGGING_CONFIG_PORT):
|
||||
"""
|
||||
Start up a socket server on the specified port, and listen for new
|
||||
configurations.
|
||||
|
||||
These will be sent as a file suitable for processing by fileConfig().
|
||||
Returns a Thread object on which you can call start() to start the server,
|
||||
and which you can join() when appropriate. To stop the server, call
|
||||
stopListening().
|
||||
"""
|
||||
if not thread:
|
||||
raise NotImplementedError, "listen() needs threading to work"
|
||||
|
||||
class ConfigStreamHandler(StreamRequestHandler):
|
||||
"""
|
||||
Handler for a logging configuration request.
|
||||
|
||||
It expects a completely new logging configuration and uses fileConfig
|
||||
to install it.
|
||||
"""
|
||||
def handle(self):
|
||||
"""
|
||||
Handle a request.
|
||||
|
||||
Each request is expected to be a 4-byte length,
|
||||
followed by the config file. Uses fileConfig() to do the
|
||||
grunt work.
|
||||
"""
|
||||
import tempfile
|
||||
try:
|
||||
conn = self.connection
|
||||
chunk = conn.recv(4)
|
||||
if len(chunk) == 4:
|
||||
slen = struct.unpack(">L", chunk)[0]
|
||||
chunk = self.connection.recv(slen)
|
||||
while len(chunk) < slen:
|
||||
chunk = chunk + conn.recv(slen - len(chunk))
|
||||
#Apply new configuration. We'd like to be able to
|
||||
#create a StringIO and pass that in, but unfortunately
|
||||
#1.5.2 ConfigParser does not support reading file
|
||||
#objects, only actual files. So we create a temporary
|
||||
#file and remove it later.
|
||||
file = tempfile.mktemp(".ini")
|
||||
f = open(file, "w")
|
||||
f.write(chunk)
|
||||
f.close()
|
||||
fileConfig(file)
|
||||
os.remove(file)
|
||||
except socket.error, e:
|
||||
if type(e.args) != types.TupleType:
|
||||
raise
|
||||
else:
|
||||
errcode = e.args[0]
|
||||
if errcode != RESET_ERROR:
|
||||
raise
|
||||
|
||||
class ConfigSocketReceiver(ThreadingTCPServer):
|
||||
"""
|
||||
A simple TCP socket-based logging config receiver.
|
||||
"""
|
||||
|
||||
allow_reuse_address = 1
|
||||
|
||||
def __init__(self, host='localhost', port=DEFAULT_LOGGING_CONFIG_PORT,
|
||||
handler=None):
|
||||
ThreadingTCPServer.__init__(self, (host, port), handler)
|
||||
logging._acquireLock()
|
||||
self.abort = 0
|
||||
logging._releaseLock()
|
||||
self.timeout = 1
|
||||
|
||||
def serve_until_stopped(self):
|
||||
import select
|
||||
abort = 0
|
||||
while not abort:
|
||||
rd, wr, ex = select.select([self.socket.fileno()],
|
||||
[], [],
|
||||
self.timeout)
|
||||
if rd:
|
||||
self.handle_request()
|
||||
logging._acquireLock()
|
||||
abort = self.abort
|
||||
logging._releaseLock()
|
||||
|
||||
def serve(rcvr, hdlr, port):
|
||||
server = rcvr(port=port, handler=hdlr)
|
||||
global _listener
|
||||
logging._acquireLock()
|
||||
_listener = server
|
||||
logging._releaseLock()
|
||||
server.serve_until_stopped()
|
||||
|
||||
return threading.Thread(target=serve,
|
||||
args=(ConfigSocketReceiver,
|
||||
ConfigStreamHandler, port))
|
||||
|
||||
def stopListening():
|
||||
"""
|
||||
Stop the listening server which was created with a call to listen().
|
||||
"""
|
||||
global _listener
|
||||
if _listener:
|
||||
logging._acquireLock()
|
||||
_listener.abort = 1
|
||||
_listener = None
|
||||
logging._releaseLock()
|
||||
@@ -0,0 +1,787 @@
|
||||
# Copyright 2001-2004 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
"""
|
||||
Additional handlers for the logging package for Python. The core package is
|
||||
based on PEP 282 and comments thereto in comp.lang.python, and influenced by
|
||||
Apache's log4j system.
|
||||
|
||||
Should work under Python versions >= 1.5.2, except that source line
|
||||
information is not available unless 'sys._getframe()' is.
|
||||
|
||||
Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved.
|
||||
|
||||
To use, simply 'import logging' and log away!
|
||||
"""
|
||||
|
||||
import sys, logging, socket, types, os, string, cPickle, struct, time
|
||||
|
||||
from SocketServer import ThreadingTCPServer, StreamRequestHandler
|
||||
|
||||
#
|
||||
# Some constants...
|
||||
#
|
||||
|
||||
DEFAULT_TCP_LOGGING_PORT = 9020
|
||||
DEFAULT_UDP_LOGGING_PORT = 9021
|
||||
DEFAULT_HTTP_LOGGING_PORT = 9022
|
||||
DEFAULT_SOAP_LOGGING_PORT = 9023
|
||||
SYSLOG_UDP_PORT = 514
|
||||
|
||||
|
||||
class RotatingFileHandler(logging.FileHandler):
|
||||
def __init__(self, filename, mode="a", maxBytes=0, backupCount=0):
|
||||
"""
|
||||
Open the specified file and use it as the stream for logging.
|
||||
|
||||
By default, the file grows indefinitely. You can specify particular
|
||||
values of maxBytes and backupCount to allow the file to rollover at
|
||||
a predetermined size.
|
||||
|
||||
Rollover occurs whenever the current log file is nearly maxBytes in
|
||||
length. If backupCount is >= 1, the system will successively create
|
||||
new files with the same pathname as the base file, but with extensions
|
||||
".1", ".2" etc. appended to it. For example, with a backupCount of 5
|
||||
and a base file name of "app.log", you would get "app.log",
|
||||
"app.log.1", "app.log.2", ... through to "app.log.5". The file being
|
||||
written to is always "app.log" - when it gets filled up, it is closed
|
||||
and renamed to "app.log.1", and if files "app.log.1", "app.log.2" etc.
|
||||
exist, then they are renamed to "app.log.2", "app.log.3" etc.
|
||||
respectively.
|
||||
|
||||
If maxBytes is zero, rollover never occurs.
|
||||
"""
|
||||
logging.FileHandler.__init__(self, filename, mode)
|
||||
self.maxBytes = maxBytes
|
||||
self.backupCount = backupCount
|
||||
if maxBytes > 0:
|
||||
self.mode = "a"
|
||||
|
||||
def doRollover(self):
|
||||
"""
|
||||
Do a rollover, as described in __init__().
|
||||
"""
|
||||
|
||||
self.stream.close()
|
||||
if self.backupCount > 0:
|
||||
for i in range(self.backupCount - 1, 0, -1):
|
||||
sfn = "%s.%d" % (self.baseFilename, i)
|
||||
dfn = "%s.%d" % (self.baseFilename, i + 1)
|
||||
if os.path.exists(sfn):
|
||||
#print "%s -> %s" % (sfn, dfn)
|
||||
if os.path.exists(dfn):
|
||||
os.remove(dfn)
|
||||
os.rename(sfn, dfn)
|
||||
dfn = self.baseFilename + ".1"
|
||||
if os.path.exists(dfn):
|
||||
os.remove(dfn)
|
||||
os.rename(self.baseFilename, dfn)
|
||||
#print "%s -> %s" % (self.baseFilename, dfn)
|
||||
self.stream = open(self.baseFilename, "w")
|
||||
|
||||
def emit(self, record):
|
||||
"""
|
||||
Emit a record.
|
||||
|
||||
Output the record to the file, catering for rollover as described
|
||||
in doRollover().
|
||||
"""
|
||||
if self.maxBytes > 0: # are we rolling over?
|
||||
msg = "%s\n" % self.format(record)
|
||||
self.stream.seek(0, 2) #due to non-posix-compliant Windows feature
|
||||
if self.stream.tell() + len(msg) >= self.maxBytes:
|
||||
self.doRollover()
|
||||
logging.FileHandler.emit(self, record)
|
||||
|
||||
|
||||
class SocketHandler(logging.Handler):
|
||||
"""
|
||||
A handler class which writes logging records, in pickle format, to
|
||||
a streaming socket. The socket is kept open across logging calls.
|
||||
If the peer resets it, an attempt is made to reconnect on the next call.
|
||||
The pickle which is sent is that of the LogRecord's attribute dictionary
|
||||
(__dict__), so that the receiver does not need to have the logging module
|
||||
installed in order to process the logging event.
|
||||
|
||||
To unpickle the record at the receiving end into a LogRecord, use the
|
||||
makeLogRecord function.
|
||||
"""
|
||||
|
||||
def __init__(self, host, port):
|
||||
"""
|
||||
Initializes the handler with a specific host address and port.
|
||||
|
||||
The attribute 'closeOnError' is set to 1 - which means that if
|
||||
a socket error occurs, the socket is silently closed and then
|
||||
reopened on the next logging call.
|
||||
"""
|
||||
logging.Handler.__init__(self)
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.sock = None
|
||||
self.closeOnError = 0
|
||||
self.retryTime = None
|
||||
#
|
||||
# Exponential backoff parameters.
|
||||
#
|
||||
self.retryStart = 1.0
|
||||
self.retryMax = 30.0
|
||||
self.retryFactor = 2.0
|
||||
|
||||
def makeSocket(self):
|
||||
"""
|
||||
A factory method which allows subclasses to define the precise
|
||||
type of socket they want.
|
||||
"""
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((self.host, self.port))
|
||||
return s
|
||||
|
||||
def createSocket(self):
|
||||
"""
|
||||
Try to create a socket, using an exponential backoff with
|
||||
a max retry time. Thanks to Robert Olson for the original patch
|
||||
(SF #815911) which has been slightly refactored.
|
||||
"""
|
||||
now = time.time()
|
||||
# Either retryTime is None, in which case this
|
||||
# is the first time back after a disconnect, or
|
||||
# we've waited long enough.
|
||||
if self.retryTime is None:
|
||||
attempt = 1
|
||||
else:
|
||||
attempt = (now >= self.retryTime)
|
||||
if attempt:
|
||||
try:
|
||||
self.sock = self.makeSocket()
|
||||
self.retryTime = None # next time, no delay before trying
|
||||
except:
|
||||
#Creation failed, so set the retry time and return.
|
||||
if self.retryTime is None:
|
||||
self.retryPeriod = self.retryStart
|
||||
else:
|
||||
self.retryPeriod = self.retryPeriod * self.retryFactor
|
||||
if self.retryPeriod > self.retryMax:
|
||||
self.retryPeriod = self.retryMax
|
||||
self.retryTime = now + self.retryPeriod
|
||||
|
||||
def send(self, s):
|
||||
"""
|
||||
Send a pickled string to the socket.
|
||||
|
||||
This function allows for partial sends which can happen when the
|
||||
network is busy.
|
||||
"""
|
||||
if self.sock is None:
|
||||
self.createSocket()
|
||||
#self.sock can be None either because we haven't reached the retry
|
||||
#time yet, or because we have reached the retry time and retried,
|
||||
#but are still unable to connect.
|
||||
if self.sock:
|
||||
try:
|
||||
if hasattr(self.sock, "sendall"):
|
||||
self.sock.sendall(s)
|
||||
else:
|
||||
sentsofar = 0
|
||||
left = len(s)
|
||||
while left > 0:
|
||||
sent = self.sock.send(s[sentsofar:])
|
||||
sentsofar = sentsofar + sent
|
||||
left = left - sent
|
||||
except socket.error:
|
||||
self.sock.close()
|
||||
self.sock = None # so we can call createSocket next time
|
||||
|
||||
def makePickle(self, record):
|
||||
"""
|
||||
Pickles the record in binary format with a length prefix, and
|
||||
returns it ready for transmission across the socket.
|
||||
"""
|
||||
ei = record.exc_info
|
||||
if ei:
|
||||
dummy = self.format(record) # just to get traceback text into record.exc_text
|
||||
record.exc_info = None # to avoid Unpickleable error
|
||||
s = cPickle.dumps(record.__dict__, 1)
|
||||
if ei:
|
||||
record.exc_info = ei # for next handler
|
||||
slen = struct.pack(">L", len(s))
|
||||
return slen + s
|
||||
|
||||
def handleError(self, record):
|
||||
"""
|
||||
Handle an error during logging.
|
||||
|
||||
An error has occurred during logging. Most likely cause -
|
||||
connection lost. Close the socket so that we can retry on the
|
||||
next event.
|
||||
"""
|
||||
if self.closeOnError and self.sock:
|
||||
self.sock.close()
|
||||
self.sock = None #try to reconnect next time
|
||||
else:
|
||||
logging.Handler.handleError(self, record)
|
||||
|
||||
def emit(self, record):
|
||||
"""
|
||||
Emit a record.
|
||||
|
||||
Pickles the record and writes it to the socket in binary format.
|
||||
If there is an error with the socket, silently drop the packet.
|
||||
If there was a problem with the socket, re-establishes the
|
||||
socket.
|
||||
"""
|
||||
try:
|
||||
s = self.makePickle(record)
|
||||
self.send(s)
|
||||
except:
|
||||
self.handleError(record)
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Closes the socket.
|
||||
"""
|
||||
if self.sock:
|
||||
self.sock.close()
|
||||
self.sock = None
|
||||
logging.Handler.close(self)
|
||||
|
||||
class DatagramHandler(SocketHandler):
|
||||
"""
|
||||
A handler class which writes logging records, in pickle format, to
|
||||
a datagram socket. The pickle which is sent is that of the LogRecord's
|
||||
attribute dictionary (__dict__), so that the receiver does not need to
|
||||
have the logging module installed in order to process the logging event.
|
||||
|
||||
To unpickle the record at the receiving end into a LogRecord, use the
|
||||
makeLogRecord function.
|
||||
|
||||
"""
|
||||
def __init__(self, host, port):
|
||||
"""
|
||||
Initializes the handler with a specific host address and port.
|
||||
"""
|
||||
SocketHandler.__init__(self, host, port)
|
||||
self.closeOnError = 0
|
||||
|
||||
def makeSocket(self):
|
||||
"""
|
||||
The factory method of SocketHandler is here overridden to create
|
||||
a UDP socket (SOCK_DGRAM).
|
||||
"""
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
return s
|
||||
|
||||
def send(self, s):
|
||||
"""
|
||||
Send a pickled string to a socket.
|
||||
|
||||
This function no longer allows for partial sends which can happen
|
||||
when the network is busy - UDP does not guarantee delivery and
|
||||
can deliver packets out of sequence.
|
||||
"""
|
||||
self.sock.sendto(s, (self.host, self.port))
|
||||
|
||||
class SysLogHandler(logging.Handler):
|
||||
"""
|
||||
A handler class which sends formatted logging records to a syslog
|
||||
server. Based on Sam Rushing's syslog module:
|
||||
http://www.nightmare.com/squirl/python-ext/misc/syslog.py
|
||||
Contributed by Nicolas Untz (after which minor refactoring changes
|
||||
have been made).
|
||||
"""
|
||||
|
||||
# from <linux/sys/syslog.h>:
|
||||
# ======================================================================
|
||||
# priorities/facilities are encoded into a single 32-bit quantity, where
|
||||
# the bottom 3 bits are the priority (0-7) and the top 28 bits are the
|
||||
# facility (0-big number). Both the priorities and the facilities map
|
||||
# roughly one-to-one to strings in the syslogd(8) source code. This
|
||||
# mapping is included in this file.
|
||||
#
|
||||
# priorities (these are ordered)
|
||||
|
||||
LOG_EMERG = 0 # system is unusable
|
||||
LOG_ALERT = 1 # action must be taken immediately
|
||||
LOG_CRIT = 2 # critical conditions
|
||||
LOG_ERR = 3 # error conditions
|
||||
LOG_WARNING = 4 # warning conditions
|
||||
LOG_NOTICE = 5 # normal but significant condition
|
||||
LOG_INFO = 6 # informational
|
||||
LOG_DEBUG = 7 # debug-level messages
|
||||
|
||||
# facility codes
|
||||
LOG_KERN = 0 # kernel messages
|
||||
LOG_USER = 1 # random user-level messages
|
||||
LOG_MAIL = 2 # mail system
|
||||
LOG_DAEMON = 3 # system daemons
|
||||
LOG_AUTH = 4 # security/authorization messages
|
||||
LOG_SYSLOG = 5 # messages generated internally by syslogd
|
||||
LOG_LPR = 6 # line printer subsystem
|
||||
LOG_NEWS = 7 # network news subsystem
|
||||
LOG_UUCP = 8 # UUCP subsystem
|
||||
LOG_CRON = 9 # clock daemon
|
||||
LOG_AUTHPRIV = 10 # security/authorization messages (private)
|
||||
|
||||
# other codes through 15 reserved for system use
|
||||
LOG_LOCAL0 = 16 # reserved for local use
|
||||
LOG_LOCAL1 = 17 # reserved for local use
|
||||
LOG_LOCAL2 = 18 # reserved for local use
|
||||
LOG_LOCAL3 = 19 # reserved for local use
|
||||
LOG_LOCAL4 = 20 # reserved for local use
|
||||
LOG_LOCAL5 = 21 # reserved for local use
|
||||
LOG_LOCAL6 = 22 # reserved for local use
|
||||
LOG_LOCAL7 = 23 # reserved for local use
|
||||
|
||||
priority_names = {
|
||||
"alert": LOG_ALERT,
|
||||
"crit": LOG_CRIT,
|
||||
"critical": LOG_CRIT,
|
||||
"debug": LOG_DEBUG,
|
||||
"emerg": LOG_EMERG,
|
||||
"err": LOG_ERR,
|
||||
"error": LOG_ERR, # DEPRECATED
|
||||
"info": LOG_INFO,
|
||||
"notice": LOG_NOTICE,
|
||||
"panic": LOG_EMERG, # DEPRECATED
|
||||
"warn": LOG_WARNING, # DEPRECATED
|
||||
"warning": LOG_WARNING,
|
||||
}
|
||||
|
||||
facility_names = {
|
||||
"auth": LOG_AUTH,
|
||||
"authpriv": LOG_AUTHPRIV,
|
||||
"cron": LOG_CRON,
|
||||
"daemon": LOG_DAEMON,
|
||||
"kern": LOG_KERN,
|
||||
"lpr": LOG_LPR,
|
||||
"mail": LOG_MAIL,
|
||||
"news": LOG_NEWS,
|
||||
"security": LOG_AUTH, # DEPRECATED
|
||||
"syslog": LOG_SYSLOG,
|
||||
"user": LOG_USER,
|
||||
"uucp": LOG_UUCP,
|
||||
"local0": LOG_LOCAL0,
|
||||
"local1": LOG_LOCAL1,
|
||||
"local2": LOG_LOCAL2,
|
||||
"local3": LOG_LOCAL3,
|
||||
"local4": LOG_LOCAL4,
|
||||
"local5": LOG_LOCAL5,
|
||||
"local6": LOG_LOCAL6,
|
||||
"local7": LOG_LOCAL7,
|
||||
}
|
||||
|
||||
def __init__(self, address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER):
|
||||
"""
|
||||
Initialize a handler.
|
||||
|
||||
If address is specified as a string, UNIX socket is used.
|
||||
If facility is not specified, LOG_USER is used.
|
||||
"""
|
||||
logging.Handler.__init__(self)
|
||||
|
||||
self.address = address
|
||||
self.facility = facility
|
||||
if type(address) == types.StringType:
|
||||
self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
|
||||
# syslog may require either DGRAM or STREAM sockets
|
||||
try:
|
||||
self.socket.connect(address)
|
||||
except socket.error:
|
||||
self.socket.close()
|
||||
self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
self.socket.connect(address)
|
||||
self.unixsocket = 1
|
||||
else:
|
||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
self.unixsocket = 0
|
||||
|
||||
self.formatter = None
|
||||
|
||||
# curious: when talking to the unix-domain '/dev/log' socket, a
|
||||
# zero-terminator seems to be required. this string is placed
|
||||
# into a class variable so that it can be overridden if
|
||||
# necessary.
|
||||
log_format_string = '<%d>%s\000'
|
||||
|
||||
def encodePriority (self, facility, priority):
|
||||
"""
|
||||
Encode the facility and priority. You can pass in strings or
|
||||
integers - if strings are passed, the facility_names and
|
||||
priority_names mapping dictionaries are used to convert them to
|
||||
integers.
|
||||
"""
|
||||
if type(facility) == types.StringType:
|
||||
facility = self.facility_names[facility]
|
||||
if type(priority) == types.StringType:
|
||||
priority = self.priority_names[priority]
|
||||
return (facility << 3) | priority
|
||||
|
||||
def close (self):
|
||||
"""
|
||||
Closes the socket.
|
||||
"""
|
||||
if self.unixsocket:
|
||||
self.socket.close()
|
||||
logging.Handler.close(self)
|
||||
|
||||
def emit(self, record):
|
||||
"""
|
||||
Emit a record.
|
||||
|
||||
The record is formatted, and then sent to the syslog server. If
|
||||
exception information is present, it is NOT sent to the server.
|
||||
"""
|
||||
msg = self.format(record)
|
||||
"""
|
||||
We need to convert record level to lowercase, maybe this will
|
||||
change in the future.
|
||||
"""
|
||||
msg = self.log_format_string % (
|
||||
self.encodePriority(self.facility,
|
||||
string.lower(record.levelname)),
|
||||
msg)
|
||||
try:
|
||||
if self.unixsocket:
|
||||
self.socket.send(msg)
|
||||
else:
|
||||
self.socket.sendto(msg, self.address)
|
||||
except:
|
||||
self.handleError(record)
|
||||
|
||||
class SMTPHandler(logging.Handler):
|
||||
"""
|
||||
A handler class which sends an SMTP email for each logging event.
|
||||
"""
|
||||
def __init__(self, mailhost, fromaddr, toaddrs, subject):
|
||||
"""
|
||||
Initialize the handler.
|
||||
|
||||
Initialize the instance with the from and to addresses and subject
|
||||
line of the email. To specify a non-standard SMTP port, use the
|
||||
(host, port) tuple format for the mailhost argument.
|
||||
"""
|
||||
logging.Handler.__init__(self)
|
||||
if type(mailhost) == types.TupleType:
|
||||
host, port = mailhost
|
||||
self.mailhost = host
|
||||
self.mailport = port
|
||||
else:
|
||||
self.mailhost = mailhost
|
||||
self.mailport = None
|
||||
self.fromaddr = fromaddr
|
||||
if type(toaddrs) == types.StringType:
|
||||
toaddrs = [toaddrs]
|
||||
self.toaddrs = toaddrs
|
||||
self.subject = subject
|
||||
|
||||
def getSubject(self, record):
|
||||
"""
|
||||
Determine the subject for the email.
|
||||
|
||||
If you want to specify a subject line which is record-dependent,
|
||||
override this method.
|
||||
"""
|
||||
return self.subject
|
||||
|
||||
weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||
|
||||
monthname = [None,
|
||||
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
||||
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
||||
|
||||
def date_time(self):
|
||||
"""Return the current date and time formatted for a MIME header."""
|
||||
year, month, day, hh, mm, ss, wd, y, z = time.gmtime(time.time())
|
||||
s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
|
||||
self.weekdayname[wd],
|
||||
day, self.monthname[month], year,
|
||||
hh, mm, ss)
|
||||
return s
|
||||
|
||||
def emit(self, record):
|
||||
"""
|
||||
Emit a record.
|
||||
|
||||
Format the record and send it to the specified addressees.
|
||||
"""
|
||||
try:
|
||||
import smtplib
|
||||
port = self.mailport
|
||||
if not port:
|
||||
port = smtplib.SMTP_PORT
|
||||
smtp = smtplib.SMTP(self.mailhost, port)
|
||||
msg = self.format(record)
|
||||
msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % (
|
||||
self.fromaddr,
|
||||
string.join(self.toaddrs, ","),
|
||||
self.getSubject(record),
|
||||
self.date_time(), msg)
|
||||
smtp.sendmail(self.fromaddr, self.toaddrs, msg)
|
||||
smtp.quit()
|
||||
except:
|
||||
self.handleError(record)
|
||||
|
||||
class NTEventLogHandler(logging.Handler):
|
||||
"""
|
||||
A handler class which sends events to the NT Event Log. Adds a
|
||||
registry entry for the specified application name. If no dllname is
|
||||
provided, win32service.pyd (which contains some basic message
|
||||
placeholders) is used. Note that use of these placeholders will make
|
||||
your event logs big, as the entire message source is held in the log.
|
||||
If you want slimmer logs, you have to pass in the name of your own DLL
|
||||
which contains the message definitions you want to use in the event log.
|
||||
"""
|
||||
def __init__(self, appname, dllname=None, logtype="Application"):
|
||||
logging.Handler.__init__(self)
|
||||
try:
|
||||
import win32evtlogutil, win32evtlog
|
||||
self.appname = appname
|
||||
self._welu = win32evtlogutil
|
||||
if not dllname:
|
||||
dllname = os.path.split(self._welu.__file__)
|
||||
dllname = os.path.split(dllname[0])
|
||||
dllname = os.path.join(dllname[0], r'win32service.pyd')
|
||||
self.dllname = dllname
|
||||
self.logtype = logtype
|
||||
self._welu.AddSourceToRegistry(appname, dllname, logtype)
|
||||
self.deftype = win32evtlog.EVENTLOG_ERROR_TYPE
|
||||
self.typemap = {
|
||||
logging.DEBUG : win32evtlog.EVENTLOG_INFORMATION_TYPE,
|
||||
logging.INFO : win32evtlog.EVENTLOG_INFORMATION_TYPE,
|
||||
logging.WARNING : win32evtlog.EVENTLOG_WARNING_TYPE,
|
||||
logging.ERROR : win32evtlog.EVENTLOG_ERROR_TYPE,
|
||||
logging.CRITICAL: win32evtlog.EVENTLOG_ERROR_TYPE,
|
||||
}
|
||||
except ImportError:
|
||||
print "The Python Win32 extensions for NT (service, event "\
|
||||
"logging) appear not to be available."
|
||||
self._welu = None
|
||||
|
||||
def getMessageID(self, record):
|
||||
"""
|
||||
Return the message ID for the event record. If you are using your
|
||||
own messages, you could do this by having the msg passed to the
|
||||
logger being an ID rather than a formatting string. Then, in here,
|
||||
you could use a dictionary lookup to get the message ID. This
|
||||
version returns 1, which is the base message ID in win32service.pyd.
|
||||
"""
|
||||
return 1
|
||||
|
||||
def getEventCategory(self, record):
|
||||
"""
|
||||
Return the event category for the record.
|
||||
|
||||
Override this if you want to specify your own categories. This version
|
||||
returns 0.
|
||||
"""
|
||||
return 0
|
||||
|
||||
def getEventType(self, record):
|
||||
"""
|
||||
Return the event type for the record.
|
||||
|
||||
Override this if you want to specify your own types. This version does
|
||||
a mapping using the handler's typemap attribute, which is set up in
|
||||
__init__() to a dictionary which contains mappings for DEBUG, INFO,
|
||||
WARNING, ERROR and CRITICAL. If you are using your own levels you will
|
||||
either need to override this method or place a suitable dictionary in
|
||||
the handler's typemap attribute.
|
||||
"""
|
||||
return self.typemap.get(record.levelno, self.deftype)
|
||||
|
||||
def emit(self, record):
|
||||
"""
|
||||
Emit a record.
|
||||
|
||||
Determine the message ID, event category and event type. Then
|
||||
log the message in the NT event log.
|
||||
"""
|
||||
if self._welu:
|
||||
try:
|
||||
id = self.getMessageID(record)
|
||||
cat = self.getEventCategory(record)
|
||||
type = self.getEventType(record)
|
||||
msg = self.format(record)
|
||||
self._welu.ReportEvent(self.appname, id, cat, type, [msg])
|
||||
except:
|
||||
self.handleError(record)
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Clean up this handler.
|
||||
|
||||
You can remove the application name from the registry as a
|
||||
source of event log entries. However, if you do this, you will
|
||||
not be able to see the events as you intended in the Event Log
|
||||
Viewer - it needs to be able to access the registry to get the
|
||||
DLL name.
|
||||
"""
|
||||
#self._welu.RemoveSourceFromRegistry(self.appname, self.logtype)
|
||||
logging.Handler.close(self)
|
||||
|
||||
class HTTPHandler(logging.Handler):
|
||||
"""
|
||||
A class which sends records to a Web server, using either GET or
|
||||
POST semantics.
|
||||
"""
|
||||
def __init__(self, host, url, method="GET"):
|
||||
"""
|
||||
Initialize the instance with the host, the request URL, and the method
|
||||
("GET" or "POST")
|
||||
"""
|
||||
logging.Handler.__init__(self)
|
||||
method = string.upper(method)
|
||||
if method not in ["GET", "POST"]:
|
||||
raise ValueError, "method must be GET or POST"
|
||||
self.host = host
|
||||
self.url = url
|
||||
self.method = method
|
||||
|
||||
def mapLogRecord(self, record):
|
||||
"""
|
||||
Default implementation of mapping the log record into a dict
|
||||
that is sent as the CGI data. Overwrite in your class.
|
||||
Contributed by Franz Glasner.
|
||||
"""
|
||||
return record.__dict__
|
||||
|
||||
def emit(self, record):
|
||||
"""
|
||||
Emit a record.
|
||||
|
||||
Send the record to the Web server as an URL-encoded dictionary
|
||||
"""
|
||||
try:
|
||||
import httplib, urllib
|
||||
h = httplib.HTTP(self.host)
|
||||
url = self.url
|
||||
data = urllib.urlencode(self.mapLogRecord(record))
|
||||
if self.method == "GET":
|
||||
if (string.find(url, '?') >= 0):
|
||||
sep = '&'
|
||||
else:
|
||||
sep = '?'
|
||||
url = url + "%c%s" % (sep, data)
|
||||
h.putrequest(self.method, url)
|
||||
if self.method == "POST":
|
||||
h.putheader("Content-length", str(len(data)))
|
||||
h.endheaders()
|
||||
if self.method == "POST":
|
||||
h.send(data)
|
||||
h.getreply() #can't do anything with the result
|
||||
except:
|
||||
self.handleError(record)
|
||||
|
||||
class BufferingHandler(logging.Handler):
|
||||
"""
|
||||
A handler class which buffers logging records in memory. Whenever each
|
||||
record is added to the buffer, a check is made to see if the buffer should
|
||||
be flushed. If it should, then flush() is expected to do what's needed.
|
||||
"""
|
||||
def __init__(self, capacity):
|
||||
"""
|
||||
Initialize the handler with the buffer size.
|
||||
"""
|
||||
logging.Handler.__init__(self)
|
||||
self.capacity = capacity
|
||||
self.buffer = []
|
||||
|
||||
def shouldFlush(self, record):
|
||||
"""
|
||||
Should the handler flush its buffer?
|
||||
|
||||
Returns true if the buffer is up to capacity. This method can be
|
||||
overridden to implement custom flushing strategies.
|
||||
"""
|
||||
return (len(self.buffer) >= self.capacity)
|
||||
|
||||
def emit(self, record):
|
||||
"""
|
||||
Emit a record.
|
||||
|
||||
Append the record. If shouldFlush() tells us to, call flush() to process
|
||||
the buffer.
|
||||
"""
|
||||
self.buffer.append(record)
|
||||
if self.shouldFlush(record):
|
||||
self.flush()
|
||||
|
||||
def flush(self):
|
||||
"""
|
||||
Override to implement custom flushing behaviour.
|
||||
|
||||
This version just zaps the buffer to empty.
|
||||
"""
|
||||
self.buffer = []
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Close the handler.
|
||||
|
||||
This version just flushes and chains to the parent class' close().
|
||||
"""
|
||||
self.flush()
|
||||
logging.Handler.close(self)
|
||||
|
||||
class MemoryHandler(BufferingHandler):
|
||||
"""
|
||||
A handler class which buffers logging records in memory, periodically
|
||||
flushing them to a target handler. Flushing occurs whenever the buffer
|
||||
is full, or when an event of a certain severity or greater is seen.
|
||||
"""
|
||||
def __init__(self, capacity, flushLevel=logging.ERROR, target=None):
|
||||
"""
|
||||
Initialize the handler with the buffer size, the level at which
|
||||
flushing should occur and an optional target.
|
||||
|
||||
Note that without a target being set either here or via setTarget(),
|
||||
a MemoryHandler is no use to anyone!
|
||||
"""
|
||||
BufferingHandler.__init__(self, capacity)
|
||||
self.flushLevel = flushLevel
|
||||
self.target = target
|
||||
|
||||
def shouldFlush(self, record):
|
||||
"""
|
||||
Check for buffer full or a record at the flushLevel or higher.
|
||||
"""
|
||||
return (len(self.buffer) >= self.capacity) or \
|
||||
(record.levelno >= self.flushLevel)
|
||||
|
||||
def setTarget(self, target):
|
||||
"""
|
||||
Set the target handler for this handler.
|
||||
"""
|
||||
self.target = target
|
||||
|
||||
def flush(self):
|
||||
"""
|
||||
For a MemoryHandler, flushing means just sending the buffered
|
||||
records to the target, if there is one. Override if you want
|
||||
different behaviour.
|
||||
"""
|
||||
if self.target:
|
||||
for record in self.buffer:
|
||||
self.target.handle(record)
|
||||
self.buffer = []
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Flush, set the target to None and lose the buffer.
|
||||
"""
|
||||
self.flush()
|
||||
self.target = None
|
||||
BufferingHandler.close(self)
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,29 @@
|
||||
from distutils.core import setup
|
||||
|
||||
setup(name = "logging",
|
||||
description="A logging module for Python",
|
||||
long_description = """This module is intended to provide a standard error logging mechanism in Python as per PEP 282.""",
|
||||
license="""Copyright (C) 2001-2004 by Vinay Sajip. All Rights Reserved.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of Vinay Sajip
|
||||
not be used in advertising or publicity pertaining to distribution
|
||||
of the software without specific, written prior permission.
|
||||
|
||||
VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.""",
|
||||
version = "0.4.9.2",
|
||||
author = "Vinay Sajip",
|
||||
author_email = "vinay_sajip@red-dove.com",
|
||||
maintainer = "Vinay Sajip",
|
||||
maintainer_email = "vinay_sajip@red-dove.com",
|
||||
url = "http://www.red-dove.com/python_logging.html",
|
||||
packages = ["logging"],
|
||||
)
|
||||
@@ -0,0 +1,5 @@
|
||||
import logging
|
||||
|
||||
logging.warning("Hello")
|
||||
logging.error("Still here...")
|
||||
logging.warning("Goodbye")
|
||||
@@ -0,0 +1,60 @@
|
||||
[loggers]
|
||||
keys=root,log02,log03,log04,log05
|
||||
|
||||
[handlers]
|
||||
keys=hand01
|
||||
|
||||
[formatters]
|
||||
keys=form01
|
||||
|
||||
[logger_root]
|
||||
level=WARN
|
||||
propagate=1
|
||||
channel=
|
||||
parent=
|
||||
qualname=(root)
|
||||
handlers=hand01
|
||||
|
||||
[logger_log02]
|
||||
level=CRITICAL
|
||||
propagate=1
|
||||
channel=A
|
||||
parent=(root)
|
||||
qualname=A
|
||||
handlers=
|
||||
|
||||
[logger_log03]
|
||||
level=CRITICAL
|
||||
propagate=1
|
||||
channel=B
|
||||
parent=log02
|
||||
qualname=A.B
|
||||
handlers=
|
||||
|
||||
[logger_log04]
|
||||
level=CRITICAL
|
||||
propagate=1
|
||||
channel=C
|
||||
parent=log03
|
||||
qualname=A.B.C
|
||||
handlers=
|
||||
|
||||
[logger_log05]
|
||||
level=CRITICAL
|
||||
propagate=1
|
||||
channel=D
|
||||
parent=log04
|
||||
qualname=A.B.C.D
|
||||
handlers=
|
||||
|
||||
[handler_hand01]
|
||||
class=StreamHandler
|
||||
level=NOTSET
|
||||
formatter=form01
|
||||
stream=sys.stderr
|
||||
args=(sys.stderr,)
|
||||
|
||||
[formatter_form01]
|
||||
format=critical.ini %(name)s %(levelname)s %(message)s
|
||||
datefmt=
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
[loggers]
|
||||
keys=root,log02,log03,log04,log05
|
||||
|
||||
[handlers]
|
||||
keys=hand01
|
||||
|
||||
[formatters]
|
||||
keys=form01
|
||||
|
||||
[logger_root]
|
||||
level=WARN
|
||||
propagate=1
|
||||
channel=
|
||||
parent=
|
||||
qualname=(root)
|
||||
handlers=hand01
|
||||
|
||||
[logger_log02]
|
||||
level=DEBUG
|
||||
propagate=1
|
||||
channel=A
|
||||
parent=(root)
|
||||
qualname=A
|
||||
handlers=
|
||||
|
||||
[logger_log03]
|
||||
level=DEBUG
|
||||
propagate=1
|
||||
channel=B
|
||||
parent=log02
|
||||
qualname=A.B
|
||||
handlers=
|
||||
|
||||
[logger_log04]
|
||||
level=DEBUG
|
||||
propagate=1
|
||||
channel=C
|
||||
parent=log03
|
||||
qualname=A.B.C
|
||||
handlers=
|
||||
|
||||
[logger_log05]
|
||||
level=DEBUG
|
||||
propagate=1
|
||||
channel=D
|
||||
parent=log04
|
||||
qualname=A.B.C.D
|
||||
handlers=
|
||||
|
||||
[handler_hand01]
|
||||
class=StreamHandler
|
||||
level=NOTSET
|
||||
formatter=form01
|
||||
stream=sys.stderr
|
||||
args=(sys.stderr,)
|
||||
|
||||
[formatter_form01]
|
||||
format=debug.ini %(name)s %(levelname)s %(message)s
|
||||
datefmt=
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
[loggers]
|
||||
keys=root,log02,log03,log04,log05
|
||||
|
||||
[handlers]
|
||||
keys=hand01
|
||||
|
||||
[formatters]
|
||||
keys=form01
|
||||
|
||||
[logger_root]
|
||||
level=WARN
|
||||
propagate=1
|
||||
channel=
|
||||
parent=
|
||||
qualname=(root)
|
||||
handlers=hand01
|
||||
|
||||
[logger_log02]
|
||||
level=ERROR
|
||||
propagate=1
|
||||
channel=A
|
||||
parent=(root)
|
||||
qualname=A
|
||||
handlers=
|
||||
|
||||
[logger_log03]
|
||||
level=ERROR
|
||||
propagate=1
|
||||
channel=B
|
||||
parent=log02
|
||||
qualname=A.B
|
||||
handlers=
|
||||
|
||||
[logger_log04]
|
||||
level=ERROR
|
||||
propagate=1
|
||||
channel=C
|
||||
parent=log03
|
||||
qualname=A.B.C
|
||||
handlers=
|
||||
|
||||
[logger_log05]
|
||||
level=ERROR
|
||||
propagate=1
|
||||
channel=D
|
||||
parent=log04
|
||||
qualname=A.B.C.D
|
||||
handlers=
|
||||
|
||||
[handler_hand01]
|
||||
class=StreamHandler
|
||||
level=NOTSET
|
||||
formatter=form01
|
||||
stream=sys.stderr
|
||||
args=(sys.stderr,)
|
||||
|
||||
[formatter_form01]
|
||||
format=error.ini %(name)s %(levelname)s %(message)s
|
||||
datefmt=
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
<event name="root" level="20" filename="log_test9.py" lineno="66">
|
||||
<message>Info index = 90</message>
|
||||
</event>
|
||||
<event name="root" level="20" filename="log_test9.py" lineno="66">
|
||||
<message>Info index = 91</message>
|
||||
</event>
|
||||
<event name="root" level="20" filename="log_test9.py" lineno="66">
|
||||
<message>Info index = 92</message>
|
||||
</event>
|
||||
<event name="root" level="20" filename="log_test9.py" lineno="66">
|
||||
<message>Info index = 93</message>
|
||||
</event>
|
||||
<event name="root" level="20" filename="log_test9.py" lineno="66">
|
||||
<message>Info index = 94</message>
|
||||
</event>
|
||||
<event name="root" level="20" filename="log_test9.py" lineno="66">
|
||||
<message>Info index = 95</message>
|
||||
</event>
|
||||
<event name="root" level="20" filename="log_test9.py" lineno="66">
|
||||
<message>Info index = 96</message>
|
||||
</event>
|
||||
<event name="root" level="20" filename="log_test9.py" lineno="66">
|
||||
<message>Info index = 97</message>
|
||||
</event>
|
||||
<event name="root" level="20" filename="log_test9.py" lineno="66">
|
||||
<message>Info index = 98</message>
|
||||
</event>
|
||||
<event name="root" level="20" filename="log_test9.py" lineno="66">
|
||||
<message>Info index = 99</message>
|
||||
</event>
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""Test harness for the logging module. Run all tests.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
|
||||
import os, sys, logging, threading, time
|
||||
|
||||
BANNER = "-- %-10s %-6s --------------------------------------------------------\n"
|
||||
|
||||
def banner(nm, typ):
|
||||
sep = BANNER % (nm, typ)
|
||||
sys.stdout.write(sep)
|
||||
sys.stdout.flush()
|
||||
sys.stderr.write(sep)
|
||||
sys.stderr.flush()
|
||||
|
||||
def main():
|
||||
oldout = sys.stdout
|
||||
olderr = sys.stderr
|
||||
sys.stdout = open("stdout.log", "w")
|
||||
sys.stderr = open("stderr.log", "w")
|
||||
logging.basicConfig()
|
||||
root = logging.getLogger("")
|
||||
hdlr0 = root.handlers[0]
|
||||
#Set up servers
|
||||
import logrecv
|
||||
threads = []
|
||||
tcpserver = logrecv.LogRecordSocketReceiver()
|
||||
tcpserver.logname = ""
|
||||
threads.append(threading.Thread(target=logrecv.runTCP, args=(tcpserver,)))
|
||||
udpserver = logrecv.LogRecordDatagramReceiver()
|
||||
udpserver.logname = ""
|
||||
threads.append(threading.Thread(target=logrecv.runUDP, args=(udpserver,)))
|
||||
httpserver = logrecv.LogRecordHTTPReceiver()
|
||||
httpserver.logname = ""
|
||||
threads.append(threading.Thread(target=logrecv.runHTTP, args=(httpserver,)))
|
||||
soapserver = None
|
||||
if logrecv.SOAPServer:
|
||||
soapserver = logrecv.SOAPServer()
|
||||
soapserver.modules = (sys.modules["logrecv"],)
|
||||
soapserver.logname = ""
|
||||
threads.append(threading.Thread(target=logrecv.runSOAP, args=(soapserver,)))
|
||||
|
||||
for thread in threads:
|
||||
thread.start()
|
||||
try:
|
||||
import log_test0
|
||||
banner("log_test0", "begin")
|
||||
log_test0.main()
|
||||
banner("log_test0", "end")
|
||||
try:
|
||||
import log_test1
|
||||
banner("log_test1", "begin")
|
||||
log_test1.main()
|
||||
banner("log_test1", "end")
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
import log_test2
|
||||
banner("log_test2", "begin")
|
||||
log_test2.main()
|
||||
banner("log_test2", "end")
|
||||
time.sleep(3)
|
||||
|
||||
#Skip 3 as it tests fileConfig
|
||||
|
||||
banner("log_test4", "begin")
|
||||
import log_test4
|
||||
banner("log_test4", "end")
|
||||
|
||||
#Skip 5 as it tests SMTPHandler, can't easily check results automatically
|
||||
|
||||
#Skip 6 as it tests NTEventLogHandler, can't easily check results automatically
|
||||
|
||||
banner("log_test7", "begin")
|
||||
root.removeHandler(hdlr0)
|
||||
import log_test7
|
||||
root.addHandler(hdlr0)
|
||||
banner("log_test7", "end")
|
||||
|
||||
banner("log_test8", "begin")
|
||||
import log_test8
|
||||
root.removeHandler(hdlr0)
|
||||
log_test8.main()
|
||||
root.addHandler(hdlr0)
|
||||
banner("log_test8", "end")
|
||||
|
||||
banner("log_test9", "begin")
|
||||
import log_test9
|
||||
root.removeHandler(hdlr0)
|
||||
log_test9.main()
|
||||
root.addHandler(hdlr0)
|
||||
banner("log_test9", "end")
|
||||
|
||||
banner("log_test10", "begin")
|
||||
import log_test10
|
||||
log_test10.main()
|
||||
banner("log_test10", "end")
|
||||
|
||||
#Skip 11 as it tests SMTPHandler, can't easily check results automatically
|
||||
|
||||
import log_test12
|
||||
banner("log_test12", "begin")
|
||||
log_test12.main()
|
||||
banner("log_test12", "end")
|
||||
|
||||
import log_test13
|
||||
banner("log_test13", "begin")
|
||||
log_test13.main()
|
||||
banner("log_test13", "end")
|
||||
|
||||
import log_test15
|
||||
banner("log_test15", "begin")
|
||||
log_test15.test(log_test15.FILTER)
|
||||
banner("log_test15", "end")
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
finally:
|
||||
#shut down servers
|
||||
olderr.write("Tidying up...")
|
||||
tcpserver.abort = 1
|
||||
udpserver.abort = 1
|
||||
httpserver.abort = 1
|
||||
if soapserver:
|
||||
soapserver.abort = 1
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
sys.stdout.close()
|
||||
sys.stdout = oldout
|
||||
#don't close this, as hdlr0 references it. hdlr0 will be closed at application exit
|
||||
#sys.stderr.close()
|
||||
sys.stderr = olderr
|
||||
print "Test run completed."
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""Test harness for the logging module. A basic test of levels.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
|
||||
import logging
|
||||
msgcount = 0
|
||||
|
||||
def nextmessage():
|
||||
global msgcount
|
||||
rv = "Message %d" % msgcount
|
||||
msgcount = msgcount + 1
|
||||
return rv
|
||||
|
||||
def main():
|
||||
logging.basicConfig()
|
||||
logging.getLogger("").setLevel(logging.DEBUG)
|
||||
ERR = logging.getLogger("ERR")
|
||||
ERR.setLevel(logging.ERROR)
|
||||
INF = logging.getLogger("INF")
|
||||
INF.setLevel(logging.INFO)
|
||||
INF_ERR = logging.getLogger("INF.ERR")
|
||||
INF_ERR.setLevel(logging.ERROR)
|
||||
DEB = logging.getLogger("DEB")
|
||||
DEB.setLevel(logging.DEBUG)
|
||||
|
||||
INF_UNDEF = logging.getLogger("INF.UNDEF")
|
||||
INF_ERR_UNDEF = logging.getLogger("INF.ERR.UNDEF")
|
||||
UNDEF = logging.getLogger("UNDEF")
|
||||
|
||||
GRANDCHILD = logging.getLogger("INF.BADPARENT.UNDEF")
|
||||
CHILD = logging.getLogger("INF.BADPARENT")
|
||||
|
||||
#These should log
|
||||
ERR.log(logging.CRITICAL, nextmessage())
|
||||
ERR.error(nextmessage())
|
||||
|
||||
INF.log(logging.CRITICAL, nextmessage())
|
||||
INF.error(nextmessage())
|
||||
INF.warning(nextmessage())
|
||||
INF.info(nextmessage())
|
||||
|
||||
INF_UNDEF.log(logging.CRITICAL, nextmessage())
|
||||
INF_UNDEF.error(nextmessage())
|
||||
INF_UNDEF.warning(nextmessage())
|
||||
INF_UNDEF.info(nextmessage())
|
||||
|
||||
INF_ERR.log(logging.CRITICAL, nextmessage())
|
||||
INF_ERR.error(nextmessage())
|
||||
|
||||
INF_ERR_UNDEF.log(logging.CRITICAL, nextmessage())
|
||||
INF_ERR_UNDEF.error(nextmessage())
|
||||
|
||||
DEB.log(logging.CRITICAL, nextmessage())
|
||||
DEB.error(nextmessage())
|
||||
DEB.warning(nextmessage())
|
||||
DEB.info(nextmessage())
|
||||
DEB.debug(nextmessage())
|
||||
|
||||
UNDEF.log(logging.CRITICAL, nextmessage())
|
||||
UNDEF.error(nextmessage())
|
||||
UNDEF.warning(nextmessage())
|
||||
UNDEF.info(nextmessage())
|
||||
|
||||
GRANDCHILD.log(logging.CRITICAL, nextmessage())
|
||||
CHILD.log(logging.CRITICAL, nextmessage())
|
||||
|
||||
#These should not log
|
||||
ERR.warning(nextmessage())
|
||||
ERR.info(nextmessage())
|
||||
ERR.debug(nextmessage())
|
||||
|
||||
INF.debug(nextmessage())
|
||||
INF_UNDEF.debug(nextmessage())
|
||||
|
||||
INF_ERR.warning(nextmessage())
|
||||
INF_ERR.info(nextmessage())
|
||||
INF_ERR.debug(nextmessage())
|
||||
INF_ERR_UNDEF.warning(nextmessage())
|
||||
INF_ERR_UNDEF.info(nextmessage())
|
||||
INF_ERR_UNDEF.debug(nextmessage())
|
||||
|
||||
INF.info("Messages should bear numbers 0 through 24.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
#print sys.argv[0]
|
||||
args = sys.argv[1:]
|
||||
if "-profile" in args:
|
||||
import profile, pstats
|
||||
args.remove("-profile")
|
||||
statf = "log_test0.pro"
|
||||
profile.run("main()", statf)
|
||||
stats = pstats.Stats(statf)
|
||||
stats.strip_dirs().sort_stats('time').print_stats()
|
||||
else:
|
||||
main()
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""Test harness for the logging module. A test showing exception handling and use of SysLogHandler.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
import sys, logging
|
||||
import syslog
|
||||
|
||||
class SLHandler(logging.Handler):
|
||||
def __init__(self, ident, logopt=0, facility=syslog.LOG_USER):
|
||||
logging.Handler.__init__(self)
|
||||
self.ident = ident
|
||||
self.logopt = logopt
|
||||
self.facility = facility
|
||||
self.mappings = {
|
||||
logging.DEBUG: syslog.LOG_DEBUG,
|
||||
logging.INFO: syslog.LOG_INFO,
|
||||
logging.WARNING: syslog.LOG_WARNING,
|
||||
logging.ERROR: syslog.LOG_ERR,
|
||||
logging.CRITICAL: syslog.LOG_CRIT,
|
||||
}
|
||||
|
||||
def encodeLevel(self, level):
|
||||
return self.mappings.get(level, syslog.LOG_INFO)
|
||||
|
||||
def emit(self, record):
|
||||
syslog.openlog(self.ident, self.logopt, self.facility)
|
||||
msg = self.format(record)
|
||||
prio = self.encodeLevel(record.levelno)
|
||||
syslog.syslog(prio, msg)
|
||||
syslog.closelog()
|
||||
|
||||
def config():
|
||||
logging.basicConfig()
|
||||
logging.getLogger("").setLevel(logging.DEBUG)
|
||||
if __name__ == "__main__":
|
||||
fmt = logging.Formatter("%(asctime)s %(filename)s:%(lineno)d %(levelname)-5s - %(message)s")
|
||||
hdlr = logging.FileHandler("tmp.tmp")
|
||||
hdlr.setFormatter(fmt)
|
||||
logging.getLogger("").addHandler(hdlr)
|
||||
else:
|
||||
fmt = None
|
||||
hdlr = SLHandler("log_test1")
|
||||
if fmt:
|
||||
hdlr.setFormatter(fmt)
|
||||
logging.getLogger("").addHandler(hdlr)
|
||||
return hdlr
|
||||
|
||||
def run():
|
||||
logging.info("Starting...")
|
||||
try:
|
||||
print "7" + 4
|
||||
except Exception, e:
|
||||
logging.error("Problem %s (%d)", "ERROR", logging.ERROR, exc_info=1)
|
||||
logging.debug("Problem %s (%d)", "DEBUG", logging.DEBUG, exc_info=1)
|
||||
logging.info("Done.")
|
||||
|
||||
|
||||
def main():
|
||||
hdlr = config()
|
||||
run()
|
||||
logging.getLogger("").removeHandler(hdlr)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""Test harness for the logging module. Shows use of a user-defined Logger subclass.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
import sys
|
||||
import locale
|
||||
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
|
||||
from logging import *
|
||||
|
||||
LOG_FORMAT = "%(asctime)s %(levelname)-5s %(message)s"
|
||||
DATE_FORMAT = "%x %X"
|
||||
|
||||
class MyLogger(Logger):
|
||||
"""
|
||||
A simple example of a logger extension.
|
||||
"""
|
||||
def debug(self, msg, *args, **kwargs):
|
||||
"""
|
||||
This overridden method passes exception information for DEBUG level calls
|
||||
"""
|
||||
if self.manager.disable >= DEBUG:
|
||||
return
|
||||
if DEBUG >= self.getEffectiveLevel():
|
||||
exc_info = kwargs.get("exc_info", 0)
|
||||
ei = None
|
||||
if exc_info:
|
||||
ei = sys.exc_info()
|
||||
if not ei[1]:
|
||||
ei = None
|
||||
self._log(DEBUG, msg, args, ei)
|
||||
del ei
|
||||
|
||||
class NotALogger:
|
||||
pass
|
||||
|
||||
def config():
|
||||
try:
|
||||
setLoggerClass(NotALogger)
|
||||
except Exception, e:
|
||||
sys.stderr.write("%s\n" % e)
|
||||
setLoggerClass(MyLogger)
|
||||
if __name__ == "__main__":
|
||||
basicConfig()
|
||||
if __name__ == "__main__":
|
||||
getLogger("").handlers[0].setFormatter(Formatter(LOG_FORMAT, DATE_FORMAT))
|
||||
|
||||
def run():
|
||||
getLogger("").setLevel(DEBUG)
|
||||
logger = getLogger("mylogger")
|
||||
logger.info("Starting...")
|
||||
logger.debug("Debug message not in exception handler (no traceback)")
|
||||
logger.info("About to throw exception...")
|
||||
try:
|
||||
print "7" + 4
|
||||
except Exception, e:
|
||||
logger.debug("Debug message inside exception handler (traceback)",exc_info=1)
|
||||
logger.info("Done.")
|
||||
|
||||
def main():
|
||||
config()
|
||||
run()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""Test harness for the logging module. Tests BufferingSMTPHandler, an alternative implementation
|
||||
of SMTPHandler.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
import string, logging, logging.handlers
|
||||
|
||||
MAILHOST = 'beta'
|
||||
FROM = 'log_test11@red-dove.com'
|
||||
TO = ['arkadi_renko']
|
||||
SUBJECT = 'Test Logging email from Python logging module (buffering)'
|
||||
|
||||
class BufferingSMTPHandler(logging.handlers.BufferingHandler):
|
||||
def __init__(self, mailhost, fromaddr, toaddrs, subject, capacity):
|
||||
logging.handlers.BufferingHandler.__init__(self, capacity)
|
||||
self.mailhost = mailhost
|
||||
self.mailport = None
|
||||
self.fromaddr = fromaddr
|
||||
self.toaddrs = toaddrs
|
||||
self.subject = subject
|
||||
self.setFormatter(logging.Formatter("%(asctime)s %(levelname)-5s %(message)s"))
|
||||
|
||||
def flush(self):
|
||||
if len(self.buffer) > 0:
|
||||
try:
|
||||
import smtplib
|
||||
port = self.mailport
|
||||
if not port:
|
||||
port = smtplib.SMTP_PORT
|
||||
smtp = smtplib.SMTP(self.mailhost, port)
|
||||
msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (self.fromaddr, string.join(self.toaddrs, ","), self.subject)
|
||||
for record in self.buffer:
|
||||
s = self.format(record)
|
||||
print s
|
||||
msg = msg + s + "\r\n"
|
||||
smtp.sendmail(self.fromaddr, self.toaddrs, msg)
|
||||
smtp.quit()
|
||||
except:
|
||||
self.handleError(None) # no particular record
|
||||
self.buffer = []
|
||||
|
||||
def test():
|
||||
logger = logging.getLogger("")
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.addHandler(BufferingSMTPHandler(MAILHOST, FROM, TO, SUBJECT, 10))
|
||||
for i in xrange(102):
|
||||
logger.info("Info index = %d", i)
|
||||
logging.shutdown()
|
||||
|
||||
if __name__ == "__main__":
|
||||
test()
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. Tests HTTPHandler.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
import sys, string, logging, logging.handlers
|
||||
|
||||
def main():
|
||||
import pdb
|
||||
host = "localhost:%d" % logging.handlers.DEFAULT_HTTP_LOGGING_PORT
|
||||
gh = logging.handlers.HTTPHandler(host, '/log', 'GET')
|
||||
ph = logging.handlers.HTTPHandler(host, '/log', 'POST')
|
||||
logger = logging.getLogger("log_test12")
|
||||
logger.propagate = 0
|
||||
logger.addHandler(gh)
|
||||
logger.addHandler(ph)
|
||||
logging.getLogger("").setLevel(logging.DEBUG)
|
||||
logger.info("Jackdaws love my big %s of %s", "sphinx", "quartz")
|
||||
logger.debug("Pack my %s with twelve dozen %s", "box", "liquor jugs")
|
||||
gh.close()
|
||||
ph.close()
|
||||
logger.removeHandler(gh)
|
||||
logger.removeHandler(ph)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. Implements a SOAPHandler class which
|
||||
can be used to form the basis of extended SOAP functionality.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
import string, logging, logging.handlers, types
|
||||
|
||||
SOAP_MESSAGE = """<SOAP-ENV:Envelope
|
||||
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:logging="http://www.red-dove.com/logging"
|
||||
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
|
||||
>
|
||||
<SOAP-ENV:Body>
|
||||
<logging:log>
|
||||
%s
|
||||
</logging:log>
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>
|
||||
"""
|
||||
|
||||
class SOAPHandler(logging.Handler):
|
||||
"""
|
||||
A class which sends records to a SOAP server.
|
||||
"""
|
||||
def __init__(self, host, url):
|
||||
"""
|
||||
Initialize the instance with the host and the request URL
|
||||
"""
|
||||
logging.Handler.__init__(self)
|
||||
self.host = host
|
||||
self.url = url
|
||||
|
||||
def emit(self, record):
|
||||
"""
|
||||
Send the record to the Web server as a SOAP message
|
||||
"""
|
||||
try:
|
||||
import httplib
|
||||
h = httplib.HTTP(self.host)
|
||||
h.putrequest("POST", self.url)
|
||||
keys = record.__dict__.keys()
|
||||
keys.sort()
|
||||
args = ""
|
||||
for key in keys:
|
||||
v = record.__dict__[key]
|
||||
if type(v) == types.StringType:
|
||||
t = "string"
|
||||
elif (type(v) == types.IntType) or (type(v) == types.LongType):
|
||||
t = "integer"
|
||||
elif type(v) == types.FloatType:
|
||||
t = "float"
|
||||
else:
|
||||
t = "string"
|
||||
args = args + "%12s<logging:%s xsi:type=\"xsd:%s\">%s</logging:%s>\n" % ("",
|
||||
key, t, str(v), key)
|
||||
data = SOAP_MESSAGE % args[:-1]
|
||||
h.putheader("Content-type", "text/plain; charset=\"utf-8\"")
|
||||
h.putheader("Content-length", str(len(data)))
|
||||
h.endheaders()
|
||||
#print data
|
||||
h.send(data)
|
||||
r = h.getreply() #can't do anything with the result
|
||||
f = h.getfile()
|
||||
if f:
|
||||
#print f.read()
|
||||
f.close()
|
||||
except:
|
||||
self.handleError(record)
|
||||
|
||||
def main():
|
||||
sh = SOAPHandler('localhost:%d' % logging.handlers.DEFAULT_SOAP_LOGGING_PORT, '/log')
|
||||
logger = logging.getLogger("log_test13")
|
||||
logging.getLogger("").setLevel(logging.DEBUG)
|
||||
logger.propagate = 0
|
||||
logger.addHandler(sh)
|
||||
logger.info("Jackdaws love my big %s of %s", "sphinx", "quartz")
|
||||
logger.debug("Pack my %s with five dozen %s", "box", "liquor jugs")
|
||||
logger.removeHandler(sh)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. An example handler - DBHandler -
|
||||
which writes to an Python DB API 2.0 data source. You'll need to set this
|
||||
source up before you run the test.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
import sys, string, time, logging
|
||||
|
||||
class DBHandler(logging.Handler):
|
||||
def __init__(self, dsn, uid='', pwd=''):
|
||||
logging.Handler.__init__(self)
|
||||
import mx.ODBC.Windows
|
||||
self.dsn = dsn
|
||||
self.uid = uid
|
||||
self.pwd = pwd
|
||||
self.conn = mx.ODBC.Windows.connect(self.dsn, self.uid, self.pwd)
|
||||
self.SQL = """INSERT INTO Events (
|
||||
Created,
|
||||
RelativeCreated,
|
||||
Name,
|
||||
LogLevel,
|
||||
LevelText,
|
||||
Message,
|
||||
Filename,
|
||||
Pathname,
|
||||
Lineno,
|
||||
Milliseconds,
|
||||
Exception,
|
||||
Thread
|
||||
)
|
||||
VALUES (
|
||||
%(dbtime)s,
|
||||
%(relativeCreated)d,
|
||||
'%(name)s',
|
||||
%(levelno)d,
|
||||
'%(levelname)s',
|
||||
'%(message)s',
|
||||
'%(filename)s',
|
||||
'%(pathname)s',
|
||||
%(lineno)d,
|
||||
%(msecs)d,
|
||||
'%(exc_text)s',
|
||||
'%(thread)s'
|
||||
);
|
||||
"""
|
||||
self.cursor = self.conn.cursor()
|
||||
|
||||
def formatDBTime(self, record):
|
||||
record.dbtime = time.strftime("#%m/%d/%Y#", time.localtime(record.created))
|
||||
|
||||
def emit(self, record):
|
||||
try:
|
||||
#use default formatting
|
||||
self.format(record)
|
||||
#now set the database time up
|
||||
self.formatDBTime(record)
|
||||
if record.exc_info:
|
||||
record.exc_text = logging._defaultFormatter.formatException(record.exc_info)
|
||||
else:
|
||||
record.exc_text = ""
|
||||
sql = self.SQL % record.__dict__
|
||||
self.cursor.execute(sql)
|
||||
self.conn.commit()
|
||||
except:
|
||||
import traceback
|
||||
ei = sys.exc_info()
|
||||
traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
|
||||
del ei
|
||||
|
||||
def close(self):
|
||||
self.cursor.close()
|
||||
self.conn.close()
|
||||
logging.Handler.close(self)
|
||||
|
||||
dh = DBHandler('Logging')
|
||||
logger = logging.getLogger("")
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.addHandler(dh)
|
||||
logger.info("Jackdaws love my big %s of %s", "sphinx", "quartz")
|
||||
logger.debug("Pack my %s with five dozen %s", "box", "liquor jugs")
|
||||
try:
|
||||
import math
|
||||
math.exp(1000)
|
||||
except:
|
||||
logger.exception("Problem with %s", "math.exp")
|
||||
logging.shutdown()
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. Tests Filter.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
|
||||
import sys, logging
|
||||
|
||||
FILTER = "a.b"
|
||||
|
||||
def message(s):
|
||||
sys.stderr.write("%s\n" % s)
|
||||
|
||||
def doLog():
|
||||
logging.getLogger("a").info("Info 1")
|
||||
logging.getLogger("a.b").info("Info 2")
|
||||
logging.getLogger("a.c").info("Info 3")
|
||||
logging.getLogger("a.b.c").info("Info 4")
|
||||
logging.getLogger("a.b.c.d").info("Info 5")
|
||||
logging.getLogger("a.bb.c").info("Info 6")
|
||||
logging.getLogger("b").info("Info 7")
|
||||
logging.getLogger("b.a").info("Info 8")
|
||||
logging.getLogger("c.a.b").info("Info 9")
|
||||
logging.getLogger("a.bb").info("Info 10")
|
||||
|
||||
def test(fs):
|
||||
root = logging.getLogger()
|
||||
root.setLevel(logging.DEBUG)
|
||||
if __name__ == "__main__":
|
||||
hand = logging.StreamHandler()
|
||||
hand.setFormatter(logging.Formatter("%(name)-10s %(message)s"))
|
||||
root.addHandler(hand)
|
||||
else:
|
||||
hand = root.handlers[0]
|
||||
message("Unfiltered...")
|
||||
doLog()
|
||||
message("Filtered with '%s'..." % fs)
|
||||
filt = logging.Filter(fs)
|
||||
hand.addFilter(filt)
|
||||
doLog()
|
||||
hand.removeFilter(filt)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
if len(sys.argv) > 1:
|
||||
fs = sys.argv[1]
|
||||
else:
|
||||
fs = FILTER
|
||||
test(fs)
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. Tests thread safety.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
|
||||
import logging, logging.handlers, thread, threading, random
|
||||
|
||||
logging.raiseExceptions = 1
|
||||
|
||||
NUM_THREADS = 10
|
||||
LOOP_COUNT = 10000
|
||||
|
||||
LOG_MESSAGES = [
|
||||
(logging.DEBUG, "%3d This is a %s message", "debug"),
|
||||
(logging.INFO, "%3d This is an %s message", "informational"),
|
||||
(logging.WARNING, "%3d This is a %s message", "warning"),
|
||||
(logging.ERROR, "%3d This is an %s message", "error"),
|
||||
(logging.CRITICAL, "%3d This is a %s message", "critical"),
|
||||
]
|
||||
|
||||
LOG_NAMES = ["A", "A.B", "A.B.C", "A.B.C.D"]
|
||||
|
||||
def doLog(num):
|
||||
logger = logging.getLogger('')
|
||||
logger.info("*** thread %s started (%d)", thread.get_ident(), num)
|
||||
for i in xrange(LOOP_COUNT):
|
||||
logger = logging.getLogger(random.choice(LOG_NAMES))
|
||||
a = random.choice(LOG_MESSAGES)
|
||||
args = a[0:2] + (num,) + a[2:]
|
||||
apply(logger.log, args)
|
||||
|
||||
def test():
|
||||
f = logging.Formatter("%(asctime)s %(levelname)-9s %(name)-8s %(thread)5s %(message)s")
|
||||
root = logging.getLogger('')
|
||||
root.setLevel(logging.DEBUG)
|
||||
h = logging.FileHandler('thread.log', 'w')
|
||||
root.addHandler(h)
|
||||
h.setFormatter(f)
|
||||
h = logging.handlers.SocketHandler('localhost', logging.handlers.DEFAULT_TCP_LOGGING_PORT)
|
||||
#h = logging.handlers.DatagramHandler('localhost', logging.handlers.DEFAULT_UDP_LOGGING_PORT)
|
||||
root.addHandler(h)
|
||||
threads = []
|
||||
for i in xrange(NUM_THREADS):
|
||||
threads.append(threading.Thread(target=doLog, args=(len(threads),)))
|
||||
for t in threads:
|
||||
t.start()
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
if __name__ == "__main__":
|
||||
test()
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. Tests thread safety.
|
||||
|
||||
To use as a server, run with no arguments in one process.
|
||||
To use as a client, run with arguments "-client <filename>" where <filename>
|
||||
is the name of a file containing a logging configuration.
|
||||
The example files debug.ini, warn.ini, error.ini and critical.ini are
|
||||
provided to use in the test. They each have a customized message format
|
||||
(prefixed with their name) and the loggers have their levels set to the
|
||||
value implied by their name.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
|
||||
import sys, logging, logging.config, thread, threading, random, time, struct
|
||||
|
||||
NUM_THREADS = 10
|
||||
LOOP_COUNT = 10
|
||||
|
||||
CONFIG_PORT = 9077
|
||||
|
||||
logging.raiseExceptions = 1
|
||||
|
||||
LOG_MESSAGES = [
|
||||
(logging.DEBUG, "%3d This is a %s message", "debug"),
|
||||
(logging.INFO, "%3d This is an %s message", "informational"),
|
||||
(logging.WARNING, "%3d This is a %s message", "warning"),
|
||||
(logging.ERROR, "%3d This is an %s message", "error"),
|
||||
(logging.CRITICAL, "%3d This is a %s message", "critical"),
|
||||
]
|
||||
|
||||
LOG_NAMES = ["A", "A.B", "A.B.C", "A.B.C.D"]
|
||||
|
||||
def doLog(num):
|
||||
logger = logging.getLogger('')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.info("*** thread %s started (%d)", thread.get_ident(), num)
|
||||
for i in xrange(LOOP_COUNT):
|
||||
logger = logging.getLogger(random.choice(LOG_NAMES))
|
||||
a = random.choice(LOG_MESSAGES)
|
||||
args = a[0:2] + (num,) + a[2:]
|
||||
time.sleep(random.random() * 3)
|
||||
apply(logger.log, args)
|
||||
|
||||
def runserver():
|
||||
f = logging.Formatter("%(asctime)s %(levelname)-9s %(name)-8s %(thread)5s %(message)s")
|
||||
root = logging.getLogger('')
|
||||
h = logging.StreamHandler()
|
||||
root.addHandler(h)
|
||||
h.setFormatter(f)
|
||||
threads = []
|
||||
for i in xrange(NUM_THREADS):
|
||||
threads.append(threading.Thread(target=doLog, args=(len(threads),)))
|
||||
threads.append(logging.config.listen(CONFIG_PORT)) #don't use default port
|
||||
for t in threads:
|
||||
t.start()
|
||||
for t in threads[:-1]:
|
||||
t.join()
|
||||
logging.config.stopListening()
|
||||
threads[-1].join()
|
||||
|
||||
def runclient(fname):
|
||||
import socket
|
||||
|
||||
print "configuring with '%s'" % fname
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.connect(('localhost', CONFIG_PORT))
|
||||
f = open(fname, "r")
|
||||
s = f.read()
|
||||
f.close()
|
||||
slen = struct.pack(">L", len(s))
|
||||
s = slen + s
|
||||
sentsofar = 0
|
||||
left = len(s)
|
||||
while left > 0:
|
||||
sent = sock.send(s[sentsofar:])
|
||||
sentsofar = sentsofar + sent
|
||||
left = left - sent
|
||||
sock.close()
|
||||
|
||||
if __name__ == "__main__":
|
||||
if "-client" not in sys.argv:
|
||||
runserver()
|
||||
else:
|
||||
sys.argv.remove("-client")
|
||||
if len(sys.argv) > 1:
|
||||
fname = sys.argv[1]
|
||||
else:
|
||||
fname = "warn.ini"
|
||||
runclient(fname)
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. Tests MatchFilter.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
|
||||
import logging, types, string
|
||||
|
||||
class MatchFilter(logging.Filter):
|
||||
def __init__(self, **kwargs):
|
||||
self.dict = kwargs
|
||||
|
||||
def matchOne(self, key, value, record):
|
||||
rv = getattr(record, key)
|
||||
if key != "name":
|
||||
if key not in ["message", "msg"]:
|
||||
return rv == value
|
||||
else:
|
||||
return string.find(str(rv), value) >= 0
|
||||
else:
|
||||
if rv == value:
|
||||
return 1
|
||||
nlen = len(value)
|
||||
if string.find(rv, value, 0, nlen) != 0:
|
||||
return 0
|
||||
if rv[nlen] == ".":
|
||||
return 1
|
||||
|
||||
def matchValue(self, key, record):
|
||||
vl = self.dict [key]
|
||||
if type(vl) != types.ListType:
|
||||
rv = self.matchOne(key, vl, record)
|
||||
else:
|
||||
for v in vl:
|
||||
rv = self.matchOne(key, v, record)
|
||||
if rv:
|
||||
break
|
||||
return rv
|
||||
|
||||
def filter(self, record):
|
||||
rv = 1
|
||||
for k in self.dict.keys():
|
||||
if self.matchValue(k, record):
|
||||
rv = 0
|
||||
break
|
||||
return rv
|
||||
|
||||
def doLog(logger, n):
|
||||
logger.debug("Debug %d" % n)
|
||||
logger.info("Info %d" % n)
|
||||
logger.warning("Warning %d" % n)
|
||||
logger.error("Error %d" % n)
|
||||
logger.critical("Critical %d" % n)
|
||||
|
||||
def test():
|
||||
fmt = logging.Formatter("%(name)-10s %(levelname)-9s %(message)s")
|
||||
hand = logging.StreamHandler()
|
||||
hand.setFormatter(fmt)
|
||||
root = logging.getLogger("")
|
||||
root.setLevel(logging.DEBUG)
|
||||
root.addHandler(hand)
|
||||
loggers = ['A',
|
||||
'A.B',
|
||||
'A.BB',
|
||||
'A.C',
|
||||
'AA.B',
|
||||
'A.B.C',
|
||||
'A.B.C.D',
|
||||
'A.B.C.D.E',
|
||||
'Z.A.B',
|
||||
]
|
||||
filt = MatchFilter(name = ['A.C', 'A.B.C'], #reject these loggers and their children
|
||||
levelno = [logging.WARNING, logging.CRITICAL], #reject these levels,
|
||||
msg = 'bug 2' #reject if this in message
|
||||
)
|
||||
hand.addFilter(filt)
|
||||
for log in loggers:
|
||||
doLog(logging.getLogger(log), loggers.index(log))
|
||||
|
||||
if __name__ == "__main__":
|
||||
test()
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""Test harness for the logging module. A basic test of parents.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
def main():
|
||||
logging.basicConfig()
|
||||
root = logging.getLogger("")
|
||||
ab = logging.getLogger("a.b")
|
||||
abc = logging.getLogger("a.b.c")
|
||||
root.setLevel(logging.ERROR)
|
||||
ab.setLevel(logging.INFO)
|
||||
abc.info("Info")
|
||||
abc.warning("Warning")
|
||||
abc.error("Error")
|
||||
print "abc = %s" % abc
|
||||
print "abc.parent = %s" % abc.parent
|
||||
print "ab = %s" % ab
|
||||
print "ab.parent = %s" % ab.parent
|
||||
print "root = %s" % root
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
print sys.argv[0]
|
||||
args = sys.argv[1:]
|
||||
if "-profile" in args:
|
||||
import profile, pstats
|
||||
args.remove("-profile")
|
||||
statf = "log_test19.pro"
|
||||
profile.run("main()", statf)
|
||||
stats = pstats.Stats(statf)
|
||||
stats.strip_dirs().sort_stats('time').print_stats()
|
||||
else:
|
||||
main()
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. Tests logger levels and basic Formatter, and logging to
|
||||
sockets.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
|
||||
import logging, logging.handlers, socket
|
||||
|
||||
msgcount = 0
|
||||
|
||||
def nextmessage():
|
||||
global msgcount
|
||||
rv = "Message %d" % msgcount
|
||||
msgcount = msgcount + 1
|
||||
return rv
|
||||
|
||||
def main():
|
||||
logging.basicConfig()
|
||||
logging.getLogger("").setLevel(logging.DEBUG)
|
||||
hdlr = logging.handlers.SocketHandler('localhost', logging.handlers.DEFAULT_TCP_LOGGING_PORT)
|
||||
if __name__ == "__main__":
|
||||
hdlr.setFormatter(logging.Formatter("%(asctime)s %(name)-19s %(levelname)-5s - %(message)s"))
|
||||
logging.getLogger("").addHandler(hdlr)
|
||||
ERR = logging.getLogger("ERR")
|
||||
ERR.setLevel(logging.ERROR)
|
||||
INF = logging.getLogger("INF")
|
||||
INF.setLevel(logging.INFO)
|
||||
INF_ERR = logging.getLogger("INF.ERR")
|
||||
INF_ERR.setLevel(logging.ERROR)
|
||||
DEB = logging.getLogger("DEB")
|
||||
DEB.setLevel(logging.DEBUG)
|
||||
|
||||
INF_UNDEF = logging.getLogger("INF.UNDEF")
|
||||
INF_ERR_UNDEF = logging.getLogger("INF.ERR.UNDEF")
|
||||
UNDEF = logging.getLogger("UNDEF")
|
||||
|
||||
GRANDCHILD = logging.getLogger("INF.BADPARENT.UNDEF")
|
||||
CHILD = logging.getLogger("INF.BADPARENT")
|
||||
|
||||
#These should log
|
||||
ERR.log(logging.CRITICAL, nextmessage())
|
||||
ERR.error(nextmessage())
|
||||
|
||||
INF.log(logging.CRITICAL, nextmessage())
|
||||
INF.error(nextmessage())
|
||||
INF.warning(nextmessage())
|
||||
INF.info(nextmessage())
|
||||
|
||||
INF_UNDEF.log(logging.CRITICAL, nextmessage())
|
||||
INF_UNDEF.error(nextmessage())
|
||||
INF_UNDEF.warning(nextmessage())
|
||||
INF_UNDEF.info(nextmessage())
|
||||
|
||||
INF_ERR.log(logging.CRITICAL, nextmessage())
|
||||
INF_ERR.error(nextmessage())
|
||||
|
||||
INF_ERR_UNDEF.log(logging.CRITICAL, nextmessage())
|
||||
INF_ERR_UNDEF.error(nextmessage())
|
||||
|
||||
DEB.log(logging.CRITICAL, nextmessage())
|
||||
DEB.error(nextmessage())
|
||||
DEB.warning(nextmessage())
|
||||
DEB.info(nextmessage())
|
||||
DEB.debug(nextmessage())
|
||||
|
||||
UNDEF.log(logging.CRITICAL, nextmessage())
|
||||
UNDEF.error(nextmessage())
|
||||
UNDEF.warning(nextmessage())
|
||||
UNDEF.info(nextmessage())
|
||||
|
||||
GRANDCHILD.log(logging.CRITICAL, nextmessage())
|
||||
CHILD.log(logging.CRITICAL, nextmessage())
|
||||
|
||||
#These should not log
|
||||
ERR.warning(nextmessage())
|
||||
ERR.info(nextmessage())
|
||||
ERR.debug(nextmessage())
|
||||
|
||||
INF.debug(nextmessage())
|
||||
INF_UNDEF.debug(nextmessage())
|
||||
|
||||
INF_ERR.warning(nextmessage())
|
||||
INF_ERR.info(nextmessage())
|
||||
INF_ERR.debug(nextmessage())
|
||||
INF_ERR_UNDEF.warning(nextmessage())
|
||||
INF_ERR_UNDEF.info(nextmessage())
|
||||
INF_ERR_UNDEF.debug(nextmessage())
|
||||
|
||||
INF.info("Messages should bear numbers 0 through 24.")
|
||||
hdlr.close()
|
||||
logging.getLogger("").removeHandler(hdlr)
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except socket.error:
|
||||
print "\nA socket error occurred. Ensure that logrecv.py is running to receive logging requests from this script."
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""Test harness for the logging module. Demonstrates the use of custom class
|
||||
instances for messages and filtering based on classes.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
class MyClass:
|
||||
def __init__(self, arg1, arg2):
|
||||
self.arg1 = arg1
|
||||
self.arg2 = arg2
|
||||
|
||||
def __str__(self):
|
||||
return "%s, %s" % (self.arg1, self.arg2)
|
||||
|
||||
class MyChildClass(MyClass):
|
||||
pass
|
||||
|
||||
class ClassFilter(logging.Filter):
|
||||
def __init__(self, klass):
|
||||
self.klass = klass
|
||||
|
||||
def filter(self, record):
|
||||
return isinstance(record.msg, self.klass)
|
||||
|
||||
class MyClassFilter(ClassFilter):
|
||||
def __init__(self, arg):
|
||||
ClassFilter.__init__(self, MyClass)
|
||||
self.arg = arg
|
||||
|
||||
def filter(self, record):
|
||||
return ClassFilter.filter(self, record) and (record.msg.arg2 == self.arg)
|
||||
|
||||
def main():
|
||||
handler = logging.StreamHandler()
|
||||
root = logging.getLogger("")
|
||||
root.setLevel(logging.DEBUG)
|
||||
root.addHandler(handler)
|
||||
root.addFilter(MyClassFilter("world"))
|
||||
#Not logged, as it's not a MyClass instance
|
||||
root.info("%s, %s", "Hello", "world")
|
||||
#Logged, as it's an appropriate instance which matches the filter criteria
|
||||
root.info(MyClass("Hello", "world"))
|
||||
#Not logged, as it's an appropriate class but doesn't match the filter criteria
|
||||
root.info(MyClass("Hello", "world!"))
|
||||
#Logged, as it's an appropriate instance which matches the filter criteria
|
||||
root.info(MyClass("Goodbye", "world"))
|
||||
#Logged, as it's an appropriate class which matches the filter criteria
|
||||
root.info(MyChildClass("Hello again", "world"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
args = sys.argv[1:]
|
||||
if "-profile" in args:
|
||||
import profile, pstats
|
||||
args.remove("-profile")
|
||||
statf = "log_test20.pro"
|
||||
profile.run("main()", statf)
|
||||
stats = pstats.Stats(statf)
|
||||
stats.strip_dirs().sort_stats('time').print_stats()
|
||||
else:
|
||||
main()
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""Test harness for the logging module. Demonstrates the use of a wildcard
|
||||
name-space filter with and without custom message classes.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
|
||||
import logging, re, string, types
|
||||
|
||||
class TaggedEvent:
|
||||
def __init__(self, tag, msg):
|
||||
self.tag = tag
|
||||
self.msg = msg
|
||||
|
||||
def __str__(self):
|
||||
return "%s: %s" % (self.tag, self.msg)
|
||||
|
||||
class WildcardFilter(logging.Filter):
|
||||
def __init__(self, wildcards):
|
||||
self.setWildcards(wildcards)
|
||||
|
||||
def setWildcard(self, wildcard):
|
||||
arr = string.split(wildcard, ".")
|
||||
for i in xrange(len(arr)):
|
||||
s = arr[i]
|
||||
if s == "*":
|
||||
arr[i] = r'[\w.]*'
|
||||
elif string.find(s, "*") > 0:
|
||||
arr[i] = string.replace(s, "*", r'[\w]*')
|
||||
s = "^%s$" % string.join(arr, r'\.')
|
||||
self.patterns.append(re.compile(s))
|
||||
|
||||
def setWildcards(self, wildcards):
|
||||
if type(wildcards) != types.ListType:
|
||||
wildcards = [wildcards]
|
||||
self.patterns = []
|
||||
for wildcard in wildcards:
|
||||
self.setWildcard(wildcard)
|
||||
|
||||
def filter(self, record):
|
||||
rv = 0
|
||||
for pat in self.patterns:
|
||||
m = pat.match(record.name)
|
||||
if m is not None:
|
||||
rv = 1
|
||||
break
|
||||
return rv
|
||||
|
||||
class TagFilter(WildcardFilter):
|
||||
def filter(self, record):
|
||||
rv = 0
|
||||
if isinstance(record.msg, TaggedEvent):
|
||||
tag = record.msg.tag
|
||||
else:
|
||||
tag = record.name
|
||||
for pat in self.patterns:
|
||||
m = pat.match(tag)
|
||||
if m is not None:
|
||||
rv = 1
|
||||
break
|
||||
return rv
|
||||
|
||||
def main():
|
||||
handler = logging.StreamHandler()
|
||||
root = logging.getLogger("")
|
||||
root.setLevel(logging.DEBUG)
|
||||
ab = logging.getLogger("a.b")
|
||||
abc = logging.getLogger("a.b.c")
|
||||
|
||||
root.addHandler(handler)
|
||||
filter = WildcardFilter("*.b")
|
||||
handler.addFilter(filter)
|
||||
|
||||
ab.info("#1 from a.b") #logged
|
||||
abc.info("#1 from a.b.c") #not logged
|
||||
filter.setWildcards("*.b.c")
|
||||
ab.info("#2 from a.b") #not logged
|
||||
abc.info("#2 from a.b.c") #logged
|
||||
filter.setWildcards("*.b*")
|
||||
ab.info("#3 from a.b") #logged
|
||||
abc.info("#3 from a.b.c") #not logged
|
||||
filter.setWildcards("*")
|
||||
ab.info("#4 from a.b") #logged
|
||||
abc.info("#4 from a.b.c") #logged
|
||||
filter.setWildcards("a*")
|
||||
ab.info("#5 from a.b") #not logged
|
||||
abc.info("#5 from a.b.c") #not logged
|
||||
filter.setWildcards("a.*")
|
||||
ab.info("#6 from a.b") #logged
|
||||
abc.info("#6 from a.b.c") #logged
|
||||
filter.setWildcards("*.b.*")
|
||||
ab.info("#7 from a.b") #not logged
|
||||
abc.info("#7 from a.b.c") #logged
|
||||
filter.setWildcards(["*.b", "*.b.*"])
|
||||
ab.info("#8 from a.b") #logged
|
||||
abc.info("#8 from a.b.c") #logged
|
||||
filter.setWildcards(["a.*.c"])
|
||||
ab.info("#9 from a.b") #not logged
|
||||
abc.info("#9 from a.b.c") #logged
|
||||
|
||||
#Now test filtering with a tagged class
|
||||
handler.removeFilter(filter)
|
||||
tagfilter = TagFilter(["*.b", "*.b.*"])
|
||||
root.addFilter(tagfilter)
|
||||
root.info(TaggedEvent("a.b", "#10")) #logged
|
||||
root.info(TaggedEvent("a.c", "#10")) #not logged
|
||||
root.info(TaggedEvent("a.b.c", "#10")) #logged
|
||||
root.info(TaggedEvent("a.b.d", "#10")) #logged
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
args = sys.argv[1:]
|
||||
if "-profile" in args:
|
||||
import profile, pstats
|
||||
args.remove("-profile")
|
||||
statf = "log_test21.pro"
|
||||
profile.run("main()", statf)
|
||||
stats = pstats.Stats(statf)
|
||||
stats.strip_dirs().sort_stats('time').print_stats()
|
||||
else:
|
||||
main()
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""Test harness for the logging module. Demonstrates the use of different
|
||||
converters for time(secs) -> time(tuple).
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
|
||||
import logging, time
|
||||
|
||||
def main():
|
||||
handler = logging.StreamHandler()
|
||||
f1 = logging.Formatter("%(asctime)s %(message)s", "%m/%d %H:%M:%S")
|
||||
f2 = logging.Formatter("%(asctime)s %(message)s", "%m/%d %H:%M:%S")
|
||||
f2.converter = time.gmtime
|
||||
handler.setFormatter(f1)
|
||||
root = logging.getLogger("")
|
||||
root.setLevel(logging.DEBUG)
|
||||
root.addHandler(handler)
|
||||
root.info("Something happened! [should be in local time]")
|
||||
handler.setFormatter(f2)
|
||||
root.info("Something else happened! [should be in GMT]")
|
||||
handler.setFormatter(f1)
|
||||
root.info("Something happened again! [should be in local time]")
|
||||
logging.Formatter.converter = time.gmtime
|
||||
root.info("Something else happened again! [should be in GMT]")
|
||||
logging.Formatter.converter = time.localtime
|
||||
root.info("Something else happened yet again! [should be in local time]")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,95 @@
|
||||
[loggers]
|
||||
keys=root,area1,area11,area111,area1111,area11111,area111111
|
||||
|
||||
[handlers]
|
||||
keys=console,file,socket,datagram,syslog,NT,SMTP
|
||||
|
||||
[formatters]
|
||||
keys=short,medium,long
|
||||
|
||||
[logger_root]
|
||||
handlers=console
|
||||
level=DEBUG
|
||||
|
||||
[logger_area1]
|
||||
level=DEBUG
|
||||
qualname=log02
|
||||
handlers=file
|
||||
|
||||
[logger_area11]
|
||||
level=INFO
|
||||
qualname=log02.log03
|
||||
handlers=socket
|
||||
|
||||
[logger_area111]
|
||||
level=WARN
|
||||
propagate=0
|
||||
qualname=log02.log03.log04
|
||||
handlers=datagram
|
||||
|
||||
[logger_area1111]
|
||||
level=ERROR
|
||||
qualname=log02.log03.log04.log05
|
||||
handlers=syslog
|
||||
|
||||
[logger_area11111]
|
||||
level=CRITICAL
|
||||
qualname=log02.log03.log04.log05.log06
|
||||
handlers=NT
|
||||
|
||||
[logger_area111111]
|
||||
level=WARN
|
||||
qualname=log02.log03.log04.log05.log06.log07
|
||||
handlers=SMTP
|
||||
|
||||
[handler_console]
|
||||
class=StreamHandler
|
||||
formatter=medium
|
||||
stream=sys.stdout
|
||||
args=(sys.stdout,)
|
||||
|
||||
[handler_file]
|
||||
class=FileHandler
|
||||
level=DEBUG
|
||||
formatter=long
|
||||
args=('python.log', 'w')
|
||||
|
||||
[handler_socket]
|
||||
class=handlers.SocketHandler
|
||||
level=INFO
|
||||
formatter=medium
|
||||
args=('localhost', handlers.DEFAULT_TCP_LOGGING_PORT)
|
||||
|
||||
[handler_datagram]
|
||||
class=handlers.DatagramHandler
|
||||
level=WARN
|
||||
formatter=medium
|
||||
args=('localhost', handlers.DEFAULT_UDP_LOGGING_PORT)
|
||||
|
||||
[handler_syslog]
|
||||
class=handlers.SysLogHandler
|
||||
level=ERROR
|
||||
formatter=short
|
||||
args=(('localhost', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER)
|
||||
|
||||
[handler_NT]
|
||||
class=handlers.NTEventLogHandler
|
||||
level=CRITICAL
|
||||
formatter=medium
|
||||
args=('Python Application', '', 'Application')
|
||||
|
||||
[handler_SMTP]
|
||||
class=handlers.SMTPHandler
|
||||
level=WARN
|
||||
formatter=long
|
||||
args=('localhost', 'from@abc', ['user1@abc', 'user2@xyz'], 'Logger Subject')
|
||||
|
||||
[formatter_short]
|
||||
format=%(message)s
|
||||
|
||||
[formatter_long]
|
||||
format=%(asctime)s %(pathname)s(%(lineno)d): %(levelname)s %(message)s
|
||||
|
||||
[formatter_medium]
|
||||
format=%(asctime)s %(levelname)s %(message)s
|
||||
datefmt=%m-%d-%Y
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. Tests new fileConfig (not yet a complete test).
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
import logging, logging.config
|
||||
|
||||
def doLog(logger):
|
||||
logger.debug("Debug")
|
||||
logger.info("Info")
|
||||
logger.warning("Warning")
|
||||
logger.error("Error")
|
||||
logger.critical("Critical")
|
||||
|
||||
def main():
|
||||
logging.config.fileConfig("log_test3.ini")
|
||||
logger = logging.getLogger(None)
|
||||
print "---------------------------------------------------"
|
||||
print "-- Logging to root; messages appear on console only"
|
||||
print "---------------------------------------------------"
|
||||
doLog(logger)
|
||||
print "----------------------------------------------------------------------"
|
||||
print "-- Logging to log02; messages appear on console and in file python.log"
|
||||
print "----------------------------------------------------------------------"
|
||||
logger = logging.getLogger("log02")
|
||||
doLog(logger)
|
||||
print "--------------------------------------------------------------------------"
|
||||
print "-- Logging to log02.log03; messages appear on console, in file python.log,"
|
||||
print "-- and at logrecv.py tcp (if running. <= DEBUG messages will not appear)."
|
||||
print "--------------------------------------------------------------------------"
|
||||
logger = logging.getLogger("log02.log03")
|
||||
doLog(logger)
|
||||
print "-----------------------------------------------------------------------"
|
||||
print "-- Logging to log02.log03.log04; messages appear only at logrecv.py udp"
|
||||
print "-- (if running. <= INFO messages will not appear)."
|
||||
print "-----------------------------------------------------------------------"
|
||||
logger = logging.getLogger("log02.log03.log04")
|
||||
doLog(logger)
|
||||
print "--------------------------------------------------------------------"
|
||||
print "-- Logging to log02.log03.log04.log05.log06; messages appear at"
|
||||
print "-- logrecv.py udp (if running. < CRITICAL messages will not appear)."
|
||||
print "--------------------------------------------------------------------"
|
||||
logger = logging.getLogger("log02.log03.log04.log05.log06")
|
||||
doLog(logger)
|
||||
print "-- All done."
|
||||
logging.shutdown()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. Tests arbitrary logging levels, filtering, and
|
||||
use of strftime formatting.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import locale, sys
|
||||
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
|
||||
def message(s):
|
||||
sys.stderr.write("%s\n" % s)
|
||||
|
||||
#
|
||||
# First, we define our levels. There can be as many as you want - the only limitations are that
|
||||
# they should be integers, the lowest should be > 0 and larger values mean less information being
|
||||
# logged. If you need specific level values which do not fit into these limitations, you can use
|
||||
# a mapping dictionary to convert between your application levels and the logging system.
|
||||
#
|
||||
SILENT = 10
|
||||
TACITURN = 9
|
||||
TERSE = 8
|
||||
EFFUSIVE = 7
|
||||
SOCIABLE = 6
|
||||
VERBOSE = 5
|
||||
TALKATIVE = 4
|
||||
GARRULOUS = 3
|
||||
CHATTERBOX = 2
|
||||
BORING = 1
|
||||
|
||||
LEVEL_RANGE = range(BORING, SILENT + 1)
|
||||
|
||||
#
|
||||
# Next, we define names for our levels. You don't need to do this - in which case the system will
|
||||
# use "Level n" to denote the text for the level.
|
||||
#
|
||||
my_logging_levels = {
|
||||
SILENT : 'Silent',
|
||||
TACITURN : 'Taciturn',
|
||||
TERSE : 'Terse',
|
||||
EFFUSIVE : 'Effusive',
|
||||
SOCIABLE : 'Sociable',
|
||||
VERBOSE : 'Verbose',
|
||||
TALKATIVE : 'Talkative',
|
||||
GARRULOUS : 'Garrulous',
|
||||
CHATTERBOX: 'Chatterbox',
|
||||
BORING : 'Boring',
|
||||
}
|
||||
|
||||
#
|
||||
# Now, tell the logging system to associate names with our levels.
|
||||
#
|
||||
for lvl in my_logging_levels.keys():
|
||||
logging.addLevelName(lvl, my_logging_levels[lvl])
|
||||
|
||||
#
|
||||
# Now, define a test function which logs an event at each of our levels.
|
||||
#
|
||||
def doLog(log):
|
||||
for lvl in LEVEL_RANGE:
|
||||
log.log(lvl, "This should only be seen at the '%s' logging level (or lower)", logging.getLevelName(lvl))
|
||||
|
||||
#
|
||||
# Get the root logger and add a console hander to it, when run as a script.
|
||||
#
|
||||
log = logging.getLogger("")
|
||||
|
||||
if __name__ == "__main__":
|
||||
hdlr = logging.StreamHandler()
|
||||
hdlr.setFormatter(logging.Formatter("%(asctime)s %(message)s", "%X")) #date format is as per the locale
|
||||
log.addHandler(hdlr)
|
||||
else:
|
||||
hdlr = log.handlers[0]
|
||||
#
|
||||
# Set the logging level to each different value and call the utility function to log events.
|
||||
# In the output, you should see that each time round the loop, the logging events actually output
|
||||
# decreases.
|
||||
#
|
||||
for lvl in LEVEL_RANGE:
|
||||
message("-- setting logging level to '%s' -----" % logging.getLevelName(lvl))
|
||||
log.setLevel(lvl)
|
||||
doLog(log)
|
||||
#
|
||||
# Now, we demonstrate level filtering at the handler level. Tell the handler defined above
|
||||
# to filter at level 'SOCIABLE', and repeat the above loop. Compare the output from the two runs.
|
||||
#
|
||||
hdlr.setLevel(SOCIABLE)
|
||||
message("-- Filtering at handler level to SOCIABLE --")
|
||||
for lvl in LEVEL_RANGE:
|
||||
message("-- setting logging level to '%s' -----" % logging.getLevelName(lvl))
|
||||
log.setLevel(lvl)
|
||||
doLog(log)
|
||||
|
||||
hdlr.setLevel(0) #turn off level filtering at the handler
|
||||
|
||||
#
|
||||
# Now, let's demonstrate filtering. Suppose for some perverse reason we only want to print out
|
||||
# all except GARRULOUS messages. Let's create a filter for this purpose...
|
||||
#
|
||||
class SpecificLevelFilter(logging.Filter):
|
||||
def __init__(self, lvl):
|
||||
self.level = lvl
|
||||
|
||||
def filter(self, record):
|
||||
return self.level != record.levelno
|
||||
|
||||
class GarrulousFilter(SpecificLevelFilter):
|
||||
def __init__(self):
|
||||
SpecificLevelFilter.__init__(self, GARRULOUS)
|
||||
|
||||
garr = GarrulousFilter()
|
||||
hdlr.addFilter(garr)
|
||||
message("-- Filtering using GARRULOUS filter --")
|
||||
for lvl in LEVEL_RANGE:
|
||||
message("-- setting logging level to '%s' -----" % logging.getLevelName(lvl))
|
||||
log.setLevel(lvl)
|
||||
doLog(log)
|
||||
#
|
||||
# Now, let's demonstrate filtering at the logger. This time, use a filter which excludes SOCIABLE
|
||||
# and TACITURN messages. Note that GARRULOUS events are still excluded.
|
||||
#
|
||||
class VerySpecificFilter(logging.Filter):
|
||||
def filter(self, record):
|
||||
return record.levelno not in [SOCIABLE, TACITURN]
|
||||
|
||||
spec = VerySpecificFilter()
|
||||
log.addFilter(spec)
|
||||
message("-- Filtering using specific filter for SOCIABLE, TACITURN --")
|
||||
for lvl in LEVEL_RANGE:
|
||||
message("-- setting logging level to '%s' -----" % logging.getLevelName(lvl))
|
||||
log.setLevel(lvl)
|
||||
doLog(log)
|
||||
|
||||
log.removeFilter(spec)
|
||||
hdlr.removeFilter(garr)
|
||||
#Undo the one level which clashes...for regression tests
|
||||
logging.addLevelName(logging.DEBUG, "DEBUG")
|
||||
|
||||
#
|
||||
# Er...that's it for now
|
||||
#
|
||||
if __name__ == "__main__":
|
||||
print "All done."
|
||||
logging.shutdown()
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. Tests SMTPHandler.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
import logging, logging.handlers
|
||||
|
||||
MAILHOST = 'beta'
|
||||
FROM = 'log_test5@yourdomain.com'
|
||||
TO = ['arkadi_renko']
|
||||
SUBJECT = 'Test Logging email from Python logging module (non-buffering)'
|
||||
|
||||
def main():
|
||||
log = logging.getLogger("")
|
||||
log.setLevel(logging.DEBUG)
|
||||
hdlr = logging.handlers.SMTPHandler(MAILHOST, FROM, TO, SUBJECT)
|
||||
hdlr.setFormatter(logging.Formatter("%(asctime)s %(levelname)-5s %(message)s"))
|
||||
log.addHandler(hdlr)
|
||||
log.info("Test email contents")
|
||||
log.removeHandler(hdlr)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. Tests NTEventLogHandler.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
import logging, logging.handlers
|
||||
|
||||
def main():
|
||||
ntl = logging.handlers.NTEventLogHandler("Python Logging Test")
|
||||
logger = logging.getLogger("")
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.addHandler(ntl)
|
||||
logger.debug("This is a '%s' message", "Debug")
|
||||
logger.info("This is a '%s' message", "Info")
|
||||
logger.warning("This is a '%s' message", "Warning")
|
||||
logger.error("This is a '%s' message", "Error")
|
||||
logger.critical("This is a '%s' message", "Critical")
|
||||
try:
|
||||
x = 4 / 0
|
||||
except:
|
||||
logger.info("This is an %s (or should that be %s?)", "informational exception", "exceptional information", exc_info=1)
|
||||
logger.exception("This is the same stuff, via a %s", "exception() call")
|
||||
logger.removeHandler(ntl)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. Tests MemoryHandler.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
import sys, logging, logging.handlers
|
||||
|
||||
def message(s):
|
||||
sys.stderr.write("%s\n" % s)
|
||||
|
||||
sh = logging.StreamHandler()
|
||||
mh = logging.handlers.MemoryHandler(10,logging.WARNING, sh)
|
||||
logger = logging.getLogger("")
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.addHandler(mh)
|
||||
message("-- logging at DEBUG, nothing should be seen yet --")
|
||||
logger.debug("Debug message")
|
||||
message("-- logging at INFO, nothing should be seen yet --")
|
||||
logger.info("Info message")
|
||||
message("-- logging at WARNING, 3 messages should be seen --")
|
||||
logger.warning("Warning message")
|
||||
for i in xrange(102):
|
||||
message("-- logging %d at level INFO, messages should be seen every 10 events --" % i)
|
||||
logger.info("Info index = %d", i)
|
||||
sh.close()
|
||||
mh.close()
|
||||
logger.removeHandler(mh)
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. Tests FileHandler rollover.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
import logging, logging.handlers
|
||||
import locale
|
||||
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
|
||||
sequence = 0
|
||||
|
||||
def doLog(logger):
|
||||
global sequence
|
||||
sequence = sequence + 1
|
||||
logger.debug("%6d This message should be at level %d - %s", sequence,\
|
||||
logging.DEBUG, logging.getLevelName(logging.DEBUG))
|
||||
sequence = sequence + 1
|
||||
logger.info("%6d This message should be at level %d - %s", sequence,
|
||||
logging.INFO, logging.getLevelName(logging.INFO))
|
||||
sequence = sequence + 1
|
||||
logger.warning("%6d This message should be at level %d - %s", sequence,\
|
||||
logging.WARNING, logging.getLevelName(logging.WARNING))
|
||||
sequence = sequence + 1
|
||||
logger.error("%6d This message should be at level %d - %s", sequence,\
|
||||
logging.ERROR, logging.getLevelName(logging.ERROR))
|
||||
sequence = sequence + 1
|
||||
logger.critical("%6d This message should be at level %d - %s", sequence,\
|
||||
logging.CRITICAL, logging.getLevelName(logging.CRITICAL))
|
||||
|
||||
def main():
|
||||
logger = logging.getLogger("") #root logger
|
||||
logger.setLevel(logging.DEBUG)
|
||||
if __name__ == "__main__":
|
||||
logname = "rollover.log"
|
||||
else:
|
||||
logname = "log_test_rollover.log"
|
||||
hdlr = logging.handlers.RotatingFileHandler(logname, "a", 5000, 3)
|
||||
if __name__ == "__main__":
|
||||
fmt = logging.Formatter("%(asctime)s %(levelname)-5s %(message)s", "%x %X")
|
||||
hdlr.setFormatter(fmt)
|
||||
logger.addHandler(hdlr)
|
||||
for i in xrange(100):
|
||||
doLog(logger)
|
||||
logger.removeHandler(hdlr)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
# This file is part of the Python logging distribution. See
|
||||
# http://www.red-dove.com/python_logging.html
|
||||
#
|
||||
"""
|
||||
A test harness for the logging module. Tests BufferingHandler, BufferingFormatter.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
import logging, logging.handlers
|
||||
|
||||
class XMLFormatter(logging.BufferingFormatter):
|
||||
"""
|
||||
A formatter which formats a set of records using XML, using an example DTD called "logging.dtd".
|
||||
"""
|
||||
def __init__(self):
|
||||
fmtstr = """
|
||||
<event name="%(name)s" level="%(levelno)d" filename="%(filename)s" lineno="%(lineno)d">
|
||||
<message>%(message)s</message>
|
||||
</event>"""
|
||||
logging.BufferingFormatter.__init__(self, logging.Formatter(fmtstr))
|
||||
|
||||
# def formatHeader(self, records):
|
||||
# return """
|
||||
#<?xml version="1.0" ?><!DOCTYPE eventSet SYSTEM "logging.dtd">
|
||||
#<eventSet xmlns="http://www.red-dove.com/logging">"""
|
||||
#
|
||||
# def formatFooter(self, records):
|
||||
# return "</eventSet>"
|
||||
|
||||
class XMLHandler(logging.handlers.BufferingHandler):
|
||||
def __init__(self, capacity):
|
||||
logging.handlers.BufferingHandler.__init__(self, capacity)
|
||||
self.setFormatter(XMLFormatter())
|
||||
|
||||
def flush(self):
|
||||
if len(self.buffer) > 0:
|
||||
file = open("events.xml","w")
|
||||
file.write(self.formatter.format(self.buffer))
|
||||
file.close()
|
||||
self.buffer = []
|
||||
|
||||
def main():
|
||||
logger = logging.getLogger("")
|
||||
logger.setLevel(logging.DEBUG)
|
||||
xh = XMLHandler(10)
|
||||
logger.addHandler(xh)
|
||||
for i in xrange(100):
|
||||
logger.info("Info index = %d", i)
|
||||
xh.close()
|
||||
logger.removeHandler(xh)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,180 @@
|
||||
[loggers]
|
||||
keys=root,log02,log03,log04,log05,log06,log07
|
||||
|
||||
[handlers]
|
||||
keys=hand01,hand02,hand03,hand04,hand05,hand06,hand07,hand08,hand09
|
||||
|
||||
[formatters]
|
||||
keys=form01,form02,form03,form04,form05,form06,form07,form08,form09
|
||||
|
||||
[logger_root]
|
||||
level=NOTSET
|
||||
propagate=1
|
||||
channel=
|
||||
parent=
|
||||
qualname=(root)
|
||||
handlers=hand01
|
||||
|
||||
[logger_log02]
|
||||
level=DEBUG
|
||||
propagate=1
|
||||
channel=log02
|
||||
parent=(root)
|
||||
qualname=log02
|
||||
handlers=hand02
|
||||
|
||||
[logger_log03]
|
||||
level=INFO
|
||||
propagate=1
|
||||
channel=log03
|
||||
parent=log02
|
||||
qualname=log02.log03
|
||||
handlers=hand03
|
||||
|
||||
[logger_log04]
|
||||
level=WARN
|
||||
propagate=0
|
||||
channel=log04
|
||||
parent=log03
|
||||
qualname=log02.log03.log04
|
||||
handlers=hand04
|
||||
|
||||
[logger_log05]
|
||||
level=ERROR
|
||||
propagate=1
|
||||
channel=log05
|
||||
parent=log04
|
||||
qualname=log02.log03.log04.log05
|
||||
handlers=hand05
|
||||
|
||||
[logger_log06]
|
||||
level=CRITICAL
|
||||
propagate=1
|
||||
channel=log06
|
||||
parent=log05
|
||||
qualname=log02.log03.log04.log05.log06
|
||||
handlers=hand06
|
||||
|
||||
[logger_log07]
|
||||
level=WARN
|
||||
propagate=1
|
||||
channel=log07
|
||||
parent=log06
|
||||
qualname=log02.log03.log04.log05.log06.log07
|
||||
handlers=hand07
|
||||
|
||||
[handler_hand01]
|
||||
class=StreamHandler
|
||||
level=NOTSET
|
||||
formatter=form01
|
||||
stream=sys.stdout
|
||||
args=(sys.stdout,)
|
||||
|
||||
[handler_hand02]
|
||||
class=FileHandler
|
||||
level=DEBUG
|
||||
formatter=form02
|
||||
filename=python.log
|
||||
mode=w
|
||||
args=('python.log', 'w')
|
||||
|
||||
[handler_hand03]
|
||||
class=handlers.SocketHandler
|
||||
level=INFO
|
||||
formatter=form03
|
||||
host=localhost
|
||||
port=handlers.DEFAULT_TCP_LOGGING_PORT
|
||||
args=('localhost', handlers.DEFAULT_TCP_LOGGING_PORT)
|
||||
|
||||
[handler_hand04]
|
||||
class=handlers.DatagramHandler
|
||||
level=WARN
|
||||
formatter=form04
|
||||
host=localhost
|
||||
port=handlers.DEFAULT_UDP_LOGGING_PORT
|
||||
args=('localhost', handlers.DEFAULT_UDP_LOGGING_PORT)
|
||||
|
||||
[handler_hand05]
|
||||
class=handlers.SysLogHandler
|
||||
level=ERROR
|
||||
formatter=form05
|
||||
host=localhost
|
||||
port=handlers.SYSLOG_UDP_PORT
|
||||
facility=LOG_USER
|
||||
args=(('localhost', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER)
|
||||
|
||||
[handler_hand06]
|
||||
class=handlers.NTEventLogHandler
|
||||
level=CRITICAL
|
||||
formatter=form06
|
||||
appname=Python Application
|
||||
dllname=
|
||||
logtype=Application
|
||||
args=('Python Application', '', 'Application')
|
||||
|
||||
[handler_hand07]
|
||||
class=handlers.SMTPHandler
|
||||
level=WARN
|
||||
formatter=form07
|
||||
host=localhost
|
||||
port=25
|
||||
from=from@abc
|
||||
to=user1@abc,user2@xyz
|
||||
subject=Logger Subject
|
||||
args=('localhost', 'from@abc', ['user1@abc', 'user2@xyz'], 'Logger Subject')
|
||||
|
||||
[handler_hand08]
|
||||
class=handlers.MemoryHandler
|
||||
level=NOTSET
|
||||
formatter=form08
|
||||
capacity=10
|
||||
flushlevel=ERROR
|
||||
target=
|
||||
args=(10, ERROR)
|
||||
|
||||
[handler_hand09]
|
||||
class=handlers.HTTPHandler
|
||||
level=NOTSET
|
||||
formatter=form09
|
||||
host=localhost
|
||||
port=9022
|
||||
url=/log
|
||||
method=GET
|
||||
args=('localhost:9022', '/log', 'GET')
|
||||
|
||||
[formatter_form01]
|
||||
format=F1 %(asctime)s %(levelname)s %(message)s
|
||||
datefmt=
|
||||
|
||||
[formatter_form02]
|
||||
format=F2 %(asctime)s %(pathname)s(%(lineno)d): %(levelname)s %(message)s
|
||||
datefmt=
|
||||
|
||||
[formatter_form03]
|
||||
format=F3 %(asctime)s %(levelname)s %(message)s
|
||||
datefmt=
|
||||
|
||||
[formatter_form04]
|
||||
format=%(asctime)s %(levelname)s %(message)s
|
||||
datefmt=
|
||||
|
||||
[formatter_form05]
|
||||
format=F5 %(asctime)s %(levelname)s %(message)s
|
||||
datefmt=
|
||||
|
||||
[formatter_form06]
|
||||
format=F6 %(asctime)s %(levelname)s %(message)s
|
||||
datefmt=
|
||||
|
||||
[formatter_form07]
|
||||
format=F7 %(asctime)s %(levelname)s %(message)s
|
||||
datefmt=
|
||||
|
||||
[formatter_form08]
|
||||
format=F8 %(asctime)s %(levelname)s %(message)s
|
||||
datefmt=
|
||||
|
||||
[formatter_form09]
|
||||
format=F9 %(asctime)s %(levelname)s %(message)s
|
||||
datefmt=
|
||||
|
||||
+1738
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<!-- Author: Vinay Sajip, Red Dove Consultants Ltd. http://www.red-dove.com/ -->
|
||||
|
||||
<!-- THIS IS ONLY A VERY SIMPLE EXAMPLE -->
|
||||
|
||||
<!ELEMENT logging:events (logging:event*)>
|
||||
|
||||
<!ELEMENT logging:event (logging:message)>
|
||||
|
||||
<!ATTLIST logging:event
|
||||
name CDATA #REQUIRED
|
||||
level CDATA #REQUIRED
|
||||
created CDATA #IMPLIED
|
||||
filename CDATA #IMPLIED
|
||||
lineno CDATA #IMPLIED
|
||||
>
|
||||
|
||||
<!ELEMENT logging:message (#PCDATA)>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" ?>
|
||||
<!DOCTYPE events SYSTEM "logging.dtd" [<!ENTITY data SYSTEM "events.xml">]>
|
||||
<events xmlns="http://www.red-dove.com/logging">
|
||||
&data;
|
||||
</events>
|
||||
@@ -0,0 +1,36 @@
|
||||
[loggers]
|
||||
keys=root
|
||||
|
||||
[handlers]
|
||||
keys=hand01,hand02
|
||||
|
||||
[formatters]
|
||||
keys=form01
|
||||
|
||||
[logger_root]
|
||||
level=NOTSET
|
||||
propagate=1
|
||||
channel=
|
||||
parent=
|
||||
qualname=(root)
|
||||
handlers=hand01,hand02
|
||||
|
||||
[handler_hand01]
|
||||
class=FileHandler
|
||||
level=NOTSET
|
||||
formatter=form01
|
||||
filename=logrecv.log
|
||||
mode=w
|
||||
args=('logrecv.log', 'w')
|
||||
|
||||
[handler_hand02]
|
||||
class=StreamHandler
|
||||
level=NOTSET
|
||||
formatter=form01
|
||||
stream=sys.stderr
|
||||
args=(sys.stderr,)
|
||||
|
||||
[formatter_form01]
|
||||
format=%(asctime)s %(levelname)-9s %(name)-8s %(thread)5s %(message)s
|
||||
datefmt=
|
||||
|
||||
+443
@@ -0,0 +1,443 @@
|
||||
#! /usr/bin/env python
|
||||
#
|
||||
# Copyright 2001-2002 by Vinay Sajip. All Rights Reserved.
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted,
|
||||
# provided that the above copyright notice appear in all copies and that
|
||||
# both that copyright notice and this permission notice appear in
|
||||
# supporting documentation, and that the name of Vinay Sajip
|
||||
# not be used in advertising or publicity pertaining to distribution
|
||||
# of the software without specific, written prior permission.
|
||||
# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||
# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
"""
|
||||
Simple socket-based logging event receiver for use with "logging.py" logging
|
||||
module.
|
||||
|
||||
Should work under Python versions >= 1.5.2, except that source line information
|
||||
is not available unless 'inspect' is.
|
||||
|
||||
Copyright (C) 2001-2002 Vinay Sajip. All Rights Reserved.
|
||||
"""
|
||||
|
||||
from select import select
|
||||
import sys, string, struct, types, cPickle, socket
|
||||
import logging, logging.handlers, logging.config
|
||||
|
||||
TIMEOUT = 10
|
||||
if sys.platform == "win32":
|
||||
RESET_ERROR = 10054
|
||||
else:
|
||||
RESET_ERROR = 0 #FIXME get correct value for Unix...
|
||||
|
||||
logging.raiseExceptions = 1
|
||||
|
||||
#
|
||||
# TCP receiver
|
||||
#
|
||||
|
||||
from SocketServer import ThreadingTCPServer, StreamRequestHandler
|
||||
|
||||
class LogRecordStreamHandler(StreamRequestHandler):
|
||||
"""
|
||||
Handler for a streaming logging request. It basically logs the record
|
||||
using whatever logging policy is configured locally.
|
||||
"""
|
||||
|
||||
def handle(self):
|
||||
"""
|
||||
Handle multiple requests - each expected to be a 4-byte length,
|
||||
followed by the LogRecord in pickle format. Logs the record
|
||||
according to whatever policy is configured locally.
|
||||
"""
|
||||
while 1:
|
||||
try:
|
||||
chunk = self.connection.recv(4)
|
||||
if len(chunk) < 4:
|
||||
break
|
||||
slen = struct.unpack(">L", chunk)[0]
|
||||
chunk = self.connection.recv(slen)
|
||||
while len(chunk) < slen:
|
||||
chunk = chunk + self.connection.recv(slen - len(chunk))
|
||||
obj = self.unPickle(chunk)
|
||||
record = logging.makeLogRecord(obj)
|
||||
self.handleLogRecord(record)
|
||||
except socket.error, e:
|
||||
if type(e.args) != types.TupleType:
|
||||
raise
|
||||
else:
|
||||
errcode = e.args[0]
|
||||
if errcode != RESET_ERROR:
|
||||
raise
|
||||
break
|
||||
|
||||
def unPickle(self, data):
|
||||
return cPickle.loads(data)
|
||||
|
||||
def handleLogRecord(self, record):
|
||||
#if a name is specified, we use the named logger rather than the one
|
||||
#implied by the record. This is so test harnesses don't get into
|
||||
#endless loops (particularly log_test.py, which has this code and the
|
||||
#client code in the same Python instance)
|
||||
if self.server.logname is not None:
|
||||
name = self.server.logname
|
||||
else:
|
||||
name = record.name
|
||||
logger = logging.getLogger(name)
|
||||
logger.handle(record)
|
||||
|
||||
class LogRecordSocketReceiver(ThreadingTCPServer):
|
||||
"""
|
||||
A simple-minded TCP socket-based logging receiver suitable for test
|
||||
purposes.
|
||||
"""
|
||||
|
||||
allow_reuse_address = 1
|
||||
|
||||
def __init__(self, host='localhost', port=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
|
||||
handler=LogRecordStreamHandler):
|
||||
ThreadingTCPServer.__init__(self, (host, port), handler)
|
||||
self.abort = 0
|
||||
self.timeout = 1
|
||||
self.logname = None
|
||||
|
||||
def serve_until_stopped(self):
|
||||
import select
|
||||
abort = 0
|
||||
while not abort:
|
||||
rd, wr, ex = select.select([self.socket.fileno()],
|
||||
[], [],
|
||||
self.timeout)
|
||||
if rd:
|
||||
self.handle_request()
|
||||
abort = self.abort
|
||||
|
||||
#
|
||||
# UDP receiver
|
||||
#
|
||||
|
||||
from SocketServer import ThreadingUDPServer, DatagramRequestHandler
|
||||
|
||||
class LogRecordDatagramHandler(DatagramRequestHandler):
|
||||
"""
|
||||
Handler for a datagram logging request. It basically logs the record using
|
||||
whatever logging policy is configured locally.
|
||||
"""
|
||||
def handle(self):
|
||||
chunk = self.packet
|
||||
slen = struct.unpack(">L", chunk[:4])[0]
|
||||
chunk = chunk[4:]
|
||||
assert len(chunk) == slen
|
||||
obj = self.unPickle(chunk)
|
||||
record = logging.LogRecord(None, None, "", 0, "", (), None)
|
||||
record.__dict__.update(obj)
|
||||
self.handleLogRecord(record)
|
||||
|
||||
def unPickle(self, data):
|
||||
return cPickle.loads(data)
|
||||
|
||||
def handleLogRecord(self, record):
|
||||
#if a name is specified, we use the named logger rather than the one
|
||||
#implied by the record. This is so test harnesses don't get into
|
||||
#endless loops (particularly log_test.py, which has this code and the
|
||||
#client code in the same Python instance)
|
||||
if self.server.logname is not None:
|
||||
name = self.server.logname
|
||||
else:
|
||||
name = record.name
|
||||
logger = logging.getLogger(name)
|
||||
logger.handle(record)
|
||||
|
||||
def finish(self):
|
||||
pass
|
||||
|
||||
class LogRecordDatagramReceiver(ThreadingUDPServer):
|
||||
"""
|
||||
A simple-minded UDP datagram-based logging receiver suitable for test
|
||||
purposes.
|
||||
"""
|
||||
|
||||
allow_reuse_address = 1
|
||||
|
||||
def __init__(self, host='localhost', port=logging.handlers.DEFAULT_UDP_LOGGING_PORT,
|
||||
handler=LogRecordDatagramHandler):
|
||||
ThreadingUDPServer.__init__(self, (host, port), handler)
|
||||
self.abort = 0
|
||||
self.timeout = 1
|
||||
self.logname = None
|
||||
|
||||
def serve_until_stopped(self):
|
||||
import select
|
||||
abort = 0
|
||||
while not abort:
|
||||
rd, wr, ex = select.select([self.socket.fileno()],
|
||||
[], [],
|
||||
self.timeout)
|
||||
if rd:
|
||||
self.handle_request()
|
||||
abort = self.abort
|
||||
|
||||
#
|
||||
# HTTP receiver
|
||||
#
|
||||
|
||||
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
|
||||
|
||||
import cgi
|
||||
|
||||
class LogRecordHTTPHandler(BaseHTTPRequestHandler):
|
||||
def makeDict(self, fs):
|
||||
dict = {}
|
||||
for mfs in fs.list:
|
||||
dict[mfs.name] = mfs.value
|
||||
for key in ["args", "exc_info", "exc_text", "lineno", "msecs", "created",
|
||||
"thread", "levelno", "relativeCreated"]:
|
||||
if dict.has_key(key):
|
||||
dict[key] = eval(dict[key])
|
||||
return dict
|
||||
|
||||
def do_GET(self):
|
||||
"""Serve a GET request."""
|
||||
sts = "OK"
|
||||
env = { 'REQUEST_METHOD' : 'GET'}
|
||||
try:
|
||||
i = string.find(self.path, '?')
|
||||
if i >= 0:
|
||||
env['QUERY_STRING'] = self.path[i + 1:]
|
||||
fs = cgi.FieldStorage(environ=env)
|
||||
dict = self.makeDict(fs)
|
||||
record = logging.LogRecord(None, None, "", 0, "", (), None)
|
||||
record.__dict__.update(dict)
|
||||
self.handleLogRecord(record)
|
||||
except Exception, e:
|
||||
sts = "ERROR"
|
||||
raise
|
||||
self.send_head()
|
||||
self.wfile.write("GET %s" % sts)
|
||||
|
||||
def handleLogRecord(self, record):
|
||||
#if a name is specified, we use the named logger rather than the one
|
||||
#implied by the record. This is so test harnesses don't get into
|
||||
#endless loops (particularly log_test.py, which has this code and the
|
||||
#client code in the same Python instance)
|
||||
if self.server.logname is not None:
|
||||
name = self.server.logname
|
||||
else:
|
||||
name = record.name
|
||||
logger = logging.getLogger(name)
|
||||
logger.handle(record)
|
||||
|
||||
def do_HEAD(self):
|
||||
"""Serve a HEAD request."""
|
||||
self.send_head()
|
||||
|
||||
def do_POST(self):
|
||||
"""Serve a POST request."""
|
||||
sts = "OK"
|
||||
env = { 'REQUEST_METHOD' : 'POST'}
|
||||
try:
|
||||
length = self.headers.getheader('content-length')
|
||||
if length:
|
||||
env['CONTENT_LENGTH'] = length
|
||||
#print self.headers
|
||||
i = string.find(self.path, '?')
|
||||
if i >= 0:
|
||||
env['QUERY_STRING'] = self.path[i + 1:]
|
||||
fs = cgi.FieldStorage(fp=self.rfile, environ=env)
|
||||
dict = self.makeDict(fs)
|
||||
record = logging.LogRecord(None, None, "", 0, "", (), None)
|
||||
record.__dict__.update(dict)
|
||||
self.handleLogRecord(record)
|
||||
except Exception, e:
|
||||
print e
|
||||
sys.stdout.flush()
|
||||
sts = "ERROR"
|
||||
raise
|
||||
self.send_head()
|
||||
self.wfile.write("POST %s" % sts)
|
||||
|
||||
def send_head(self):
|
||||
"""Common code for GET and HEAD commands.
|
||||
|
||||
This sends the response code and MIME headers.
|
||||
|
||||
Return value is either a file object (which has to be copied
|
||||
to the outputfile by the caller unless the command was HEAD,
|
||||
and must be closed by the caller under all circumstances), or
|
||||
None, in which case the caller has nothing further to do.
|
||||
|
||||
"""
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", "text/plain")
|
||||
self.end_headers()
|
||||
|
||||
def log_message(self, *args):
|
||||
#comment out the following line if you don't want to show requests
|
||||
#apply(BaseHTTPRequestHandler.log_message, (self,) + args)
|
||||
pass
|
||||
|
||||
class LogRecordHTTPReceiver(HTTPServer):
|
||||
def __init__(self, host='localhost', port=logging.handlers.DEFAULT_HTTP_LOGGING_PORT,
|
||||
handler=LogRecordHTTPHandler):
|
||||
HTTPServer.__init__(self, (host, port), handler)
|
||||
self.abort = 0
|
||||
self.timeout = 1
|
||||
self.logname = None
|
||||
|
||||
def serve_until_stopped(self):
|
||||
import select
|
||||
abort = 0
|
||||
while not abort:
|
||||
rd, wr, ex = select.select([self.socket.fileno()],
|
||||
[], [],
|
||||
self.timeout)
|
||||
if rd:
|
||||
self.handle_request()
|
||||
abort = self.abort
|
||||
|
||||
|
||||
#
|
||||
# SOAP receiver
|
||||
#
|
||||
|
||||
try:
|
||||
from ZSI import dispatch
|
||||
|
||||
logname = None
|
||||
|
||||
def log(args, created, exc_info, exc_text, filename, levelname, levelno, lineno, module, msecs, msg, name, pathname, process, relativeCreated, thread):
|
||||
record = logging.LogRecord(None, None, "", 0, "", (), None)
|
||||
record.args = eval(args)
|
||||
record.exc_info = eval(exc_info)
|
||||
record.exc_text = eval(exc_text)
|
||||
record.created = created
|
||||
record.filename = filename
|
||||
record.module = module
|
||||
record.levelname = levelname
|
||||
record.lineno = lineno
|
||||
record.levelno = levelno
|
||||
record.msecs = msecs
|
||||
record.msg = msg
|
||||
record.name = name
|
||||
record.pathname = pathname
|
||||
record.process = process
|
||||
record.relativeCreated = relativeCreated
|
||||
record.thread = thread
|
||||
#if a name is specified, we use the named logger rather than the one
|
||||
#implied by the record. This is so test harnesses don't get into
|
||||
#endless loops (particularly log_test.py, which has this code and the
|
||||
#client code in the same Python instance)
|
||||
if logname is not None:
|
||||
lname = logname
|
||||
else:
|
||||
lname = name
|
||||
logger = logging.getLogger(lname)
|
||||
logger.handle(record)
|
||||
|
||||
class MySOAPRequestHandler(dispatch.SOAPRequestHandler):
|
||||
def log_message(self, *args):
|
||||
#comment out the following line if you don't want to show requests
|
||||
#apply(BaseHTTPRequestHandler.log_message, (self,) + args)
|
||||
pass
|
||||
|
||||
class SOAPServer(HTTPServer):
|
||||
def __init__(self, port=logging.handlers.DEFAULT_SOAP_LOGGING_PORT):
|
||||
address = ('', port)
|
||||
HTTPServer.__init__(self, address, MySOAPRequestHandler)
|
||||
self.abort = 0
|
||||
self.timeout = 1
|
||||
self.logname = None
|
||||
self.docstyle = 0
|
||||
self.nsdict = {}
|
||||
self.typesmodule = None
|
||||
self.rpc = 1
|
||||
self.modules = (sys.modules["__main__"],)
|
||||
|
||||
def serve_until_stopped(self):
|
||||
import select
|
||||
abort = 0
|
||||
while not abort:
|
||||
rd, wr, ex = select.select([self.socket.fileno()],
|
||||
[], [],
|
||||
self.timeout)
|
||||
if rd:
|
||||
global logname
|
||||
logname = self.logname
|
||||
self.handle_request()
|
||||
abort = self.abort
|
||||
|
||||
except ImportError:
|
||||
"Import failed"
|
||||
SOAPServer = None
|
||||
|
||||
def runTCP(tcpserver=None):
|
||||
if not tcpserver:
|
||||
tcpserver = LogRecordSocketReceiver()
|
||||
print "About to start TCP server..."
|
||||
tcpserver.serve_until_stopped()
|
||||
|
||||
def runUDP(udpserver=None):
|
||||
if not udpserver:
|
||||
udpserver = LogRecordDatagramReceiver()
|
||||
print "About to start UDP server..."
|
||||
udpserver.serve_until_stopped()
|
||||
|
||||
def runHTTP(httpserver=None):
|
||||
if not httpserver:
|
||||
httpserver = LogRecordHTTPReceiver()
|
||||
print "About to start HTTP server..."
|
||||
httpserver.serve_until_stopped()
|
||||
|
||||
def runSOAP(soapserver=None):
|
||||
if not SOAPServer:
|
||||
print "Sorry, ZSI is not available. Install PyXML-0.6.6 and ZSI first."
|
||||
print "See README.txt and python_logging.html for more information."
|
||||
else:
|
||||
if not soapserver:
|
||||
soapserver = SOAPServer()
|
||||
print "About to start SOAP server..."
|
||||
soapserver.serve_until_stopped()
|
||||
|
||||
FORMAT_STR = "%(asctime)s %(name)-19s %(levelname)-5s - %(message)s"
|
||||
|
||||
if __name__ == "__main__":
|
||||
if (len(sys.argv) < 2) or not (string.lower(sys.argv[1]) in \
|
||||
["udp", "tcp", "http", "soap"]):
|
||||
print "usage: logrecv.py [UDP|TCP|HTTP|SOAP]"
|
||||
else:
|
||||
#logging.basicConfig()
|
||||
logging.config.fileConfig("logrecv.ini")
|
||||
# both = string.lower(sys.argv[1]) == "both"
|
||||
# hdlr = logging.FileHandler("test.log")
|
||||
# hdlr.setFormatter(logging.Formatter(FORMAT_STR))
|
||||
# logging.getLogger("").addHandler(hdlr)
|
||||
# if both:
|
||||
# import threading
|
||||
# tcpthread = threading.Thread(target=runTCP)
|
||||
# udpthread = threading.Thread(target=runUDP)
|
||||
# tcpthread.start()
|
||||
# udpthread.start()
|
||||
# tcpthread.join()
|
||||
# udpthread.join()
|
||||
# else:
|
||||
# tcp = string.lower(sys.argv[1]) == "tcp"
|
||||
# if tcp:
|
||||
# runTCP()
|
||||
# else:
|
||||
# runUDP()
|
||||
arg = string.lower(sys.argv[1])
|
||||
if arg == "tcp":
|
||||
runTCP()
|
||||
elif arg == "udp":
|
||||
runUDP()
|
||||
elif arg == "http":
|
||||
runHTTP()
|
||||
elif arg == "soap":
|
||||
runSOAP()
|
||||
@@ -0,0 +1,13 @@
|
||||
import logging, mymodule
|
||||
|
||||
logging.basicConfig()
|
||||
|
||||
log = logging.getLogger("MyApp")
|
||||
log.setLevel(logging.DEBUG) #set verbosity to show all messages of severity >= DEBUG
|
||||
log.info("Starting my app")
|
||||
try:
|
||||
mymodule.doIt()
|
||||
except Exception, e:
|
||||
log.exception("There was a problem.")
|
||||
log.info("Ending my app")
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import logging
|
||||
log = logging.getLogger("MyModule")
|
||||
|
||||
def doIt():
|
||||
log.debug("Doin' stuff...")
|
||||
#do stuff...
|
||||
raise TypeError, "Bogus type error for testing"
|
||||
|
||||
@@ -0,0 +1,566 @@
|
||||
-- log_test0 begin --------------------------------------------------------
|
||||
CRITICAL:ERR:Message 0
|
||||
ERROR:ERR:Message 1
|
||||
CRITICAL:INF:Message 2
|
||||
ERROR:INF:Message 3
|
||||
WARNING:INF:Message 4
|
||||
INFO:INF:Message 5
|
||||
CRITICAL:INF.UNDEF:Message 6
|
||||
ERROR:INF.UNDEF:Message 7
|
||||
WARNING:INF.UNDEF:Message 8
|
||||
INFO:INF.UNDEF:Message 9
|
||||
CRITICAL:INF.ERR:Message 10
|
||||
ERROR:INF.ERR:Message 11
|
||||
CRITICAL:INF.ERR.UNDEF:Message 12
|
||||
ERROR:INF.ERR.UNDEF:Message 13
|
||||
CRITICAL:DEB:Message 14
|
||||
ERROR:DEB:Message 15
|
||||
WARNING:DEB:Message 16
|
||||
INFO:DEB:Message 17
|
||||
DEBUG:DEB:Message 18
|
||||
CRITICAL:UNDEF:Message 19
|
||||
ERROR:UNDEF:Message 20
|
||||
WARNING:UNDEF:Message 21
|
||||
INFO:UNDEF:Message 22
|
||||
CRITICAL:INF.BADPARENT.UNDEF:Message 23
|
||||
CRITICAL:INF.BADPARENT:Message 24
|
||||
INFO:INF:Messages should bear numbers 0 through 24.
|
||||
-- log_test0 end --------------------------------------------------------
|
||||
-- log_test2 begin --------------------------------------------------------
|
||||
CRITICAL:ERR:Message 0
|
||||
ERROR:ERR:Message 1
|
||||
CRITICAL:INF:Message 2
|
||||
ERROR:INF:Message 3
|
||||
WARNING:INF:Message 4
|
||||
INFO:INF:Message 5
|
||||
CRITICAL:INF.UNDEF:Message 6
|
||||
ERROR:INF.UNDEF:Message 7
|
||||
WARNING:INF.UNDEF:Message 8
|
||||
INFO:INF.UNDEF:Message 9
|
||||
CRITICAL:INF.ERR:Message 10
|
||||
ERROR:INF.ERR:Message 11
|
||||
CRITICAL:INF.ERR.UNDEF:Message 12
|
||||
ERROR:INF.ERR.UNDEF:Message 13
|
||||
CRITICAL:DEB:Message 14
|
||||
ERROR:DEB:Message 15
|
||||
WARNING:DEB:Message 16
|
||||
INFO:DEB:Message 17
|
||||
DEBUG:DEB:Message 18
|
||||
CRITICAL:UNDEF:Message 19
|
||||
ERROR:UNDEF:Message 20
|
||||
WARNING:UNDEF:Message 21
|
||||
INFO:UNDEF:Message 22
|
||||
CRITICAL:INF.BADPARENT.UNDEF:Message 23
|
||||
CRITICAL:INF.BADPARENT:Message 24
|
||||
INFO:INF:Messages should bear numbers 0 through 24.
|
||||
-- log_test2 end --------------------------------------------------------
|
||||
CRITICAL:ERR:Message 0
|
||||
ERROR:ERR:Message 1
|
||||
CRITICAL:INF:Message 2
|
||||
ERROR:INF:Message 3
|
||||
WARNING:INF:Message 4
|
||||
INFO:INF:Message 5
|
||||
CRITICAL:INF.UNDEF:Message 6
|
||||
ERROR:INF.UNDEF:Message 7
|
||||
WARNING:INF.UNDEF:Message 8
|
||||
INFO:INF.UNDEF:Message 9
|
||||
CRITICAL:INF.ERR:Message 10
|
||||
ERROR:INF.ERR:Message 11
|
||||
CRITICAL:INF.ERR.UNDEF:Message 12
|
||||
ERROR:INF.ERR.UNDEF:Message 13
|
||||
CRITICAL:DEB:Message 14
|
||||
ERROR:DEB:Message 15
|
||||
WARNING:DEB:Message 16
|
||||
INFO:DEB:Message 17
|
||||
DEBUG:DEB:Message 18
|
||||
CRITICAL:UNDEF:Message 19
|
||||
ERROR:UNDEF:Message 20
|
||||
WARNING:UNDEF:Message 21
|
||||
INFO:UNDEF:Message 22
|
||||
CRITICAL:INF.BADPARENT.UNDEF:Message 23
|
||||
CRITICAL:INF.BADPARENT:Message 24
|
||||
INFO:INF:Messages should bear numbers 0 through 24.
|
||||
-- log_test4 begin --------------------------------------------------------
|
||||
-- setting logging level to 'Boring' -----
|
||||
Boring:root:This should only be seen at the 'Boring' logging level (or lower)
|
||||
Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
|
||||
Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower)
|
||||
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Chatterbox' -----
|
||||
Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
|
||||
Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower)
|
||||
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Garrulous' -----
|
||||
Garrulous:root:This should only be seen at the 'Garrulous' logging level (or lower)
|
||||
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Talkative' -----
|
||||
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Verbose' -----
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Sociable' -----
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Effusive' -----
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Terse' -----
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Taciturn' -----
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Silent' -----
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- Filtering at handler level to SOCIABLE --
|
||||
-- setting logging level to 'Boring' -----
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Chatterbox' -----
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Garrulous' -----
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Talkative' -----
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Verbose' -----
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Sociable' -----
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Effusive' -----
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Terse' -----
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Taciturn' -----
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Silent' -----
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- Filtering using GARRULOUS filter --
|
||||
-- setting logging level to 'Boring' -----
|
||||
Boring:root:This should only be seen at the 'Boring' logging level (or lower)
|
||||
Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
|
||||
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Chatterbox' -----
|
||||
Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
|
||||
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Garrulous' -----
|
||||
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Talkative' -----
|
||||
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Verbose' -----
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Sociable' -----
|
||||
Sociable:root:This should only be seen at the 'Sociable' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Effusive' -----
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Terse' -----
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Taciturn' -----
|
||||
Taciturn:root:This should only be seen at the 'Taciturn' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Silent' -----
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- Filtering using specific filter for SOCIABLE, TACITURN --
|
||||
-- setting logging level to 'Boring' -----
|
||||
Boring:root:This should only be seen at the 'Boring' logging level (or lower)
|
||||
Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
|
||||
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Chatterbox' -----
|
||||
Chatterbox:root:This should only be seen at the 'Chatterbox' logging level (or lower)
|
||||
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Garrulous' -----
|
||||
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Talkative' -----
|
||||
Talkative:root:This should only be seen at the 'Talkative' logging level (or lower)
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Verbose' -----
|
||||
Verbose:root:This should only be seen at the 'Verbose' logging level (or lower)
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Sociable' -----
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Effusive' -----
|
||||
Effusive:root:This should only be seen at the 'Effusive' logging level (or lower)
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Terse' -----
|
||||
Terse:root:This should only be seen at the 'Terse' logging level (or lower)
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Taciturn' -----
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- setting logging level to 'Silent' -----
|
||||
Silent:root:This should only be seen at the 'Silent' logging level (or lower)
|
||||
-- log_test4 end --------------------------------------------------------
|
||||
-- log_test7 begin --------------------------------------------------------
|
||||
-- logging at DEBUG, nothing should be seen yet --
|
||||
-- logging at INFO, nothing should be seen yet --
|
||||
-- logging at WARNING, 3 messages should be seen --
|
||||
Debug message
|
||||
Info message
|
||||
Warning message
|
||||
-- logging 0 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 1 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 2 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 3 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 4 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 5 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 6 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 7 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 8 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 9 at level INFO, messages should be seen every 10 events --
|
||||
Info index = 0
|
||||
Info index = 1
|
||||
Info index = 2
|
||||
Info index = 3
|
||||
Info index = 4
|
||||
Info index = 5
|
||||
Info index = 6
|
||||
Info index = 7
|
||||
Info index = 8
|
||||
Info index = 9
|
||||
-- logging 10 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 11 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 12 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 13 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 14 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 15 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 16 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 17 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 18 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 19 at level INFO, messages should be seen every 10 events --
|
||||
Info index = 10
|
||||
Info index = 11
|
||||
Info index = 12
|
||||
Info index = 13
|
||||
Info index = 14
|
||||
Info index = 15
|
||||
Info index = 16
|
||||
Info index = 17
|
||||
Info index = 18
|
||||
Info index = 19
|
||||
-- logging 20 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 21 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 22 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 23 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 24 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 25 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 26 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 27 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 28 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 29 at level INFO, messages should be seen every 10 events --
|
||||
Info index = 20
|
||||
Info index = 21
|
||||
Info index = 22
|
||||
Info index = 23
|
||||
Info index = 24
|
||||
Info index = 25
|
||||
Info index = 26
|
||||
Info index = 27
|
||||
Info index = 28
|
||||
Info index = 29
|
||||
-- logging 30 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 31 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 32 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 33 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 34 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 35 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 36 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 37 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 38 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 39 at level INFO, messages should be seen every 10 events --
|
||||
Info index = 30
|
||||
Info index = 31
|
||||
Info index = 32
|
||||
Info index = 33
|
||||
Info index = 34
|
||||
Info index = 35
|
||||
Info index = 36
|
||||
Info index = 37
|
||||
Info index = 38
|
||||
Info index = 39
|
||||
-- logging 40 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 41 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 42 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 43 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 44 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 45 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 46 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 47 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 48 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 49 at level INFO, messages should be seen every 10 events --
|
||||
Info index = 40
|
||||
Info index = 41
|
||||
Info index = 42
|
||||
Info index = 43
|
||||
Info index = 44
|
||||
Info index = 45
|
||||
Info index = 46
|
||||
Info index = 47
|
||||
Info index = 48
|
||||
Info index = 49
|
||||
-- logging 50 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 51 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 52 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 53 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 54 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 55 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 56 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 57 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 58 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 59 at level INFO, messages should be seen every 10 events --
|
||||
Info index = 50
|
||||
Info index = 51
|
||||
Info index = 52
|
||||
Info index = 53
|
||||
Info index = 54
|
||||
Info index = 55
|
||||
Info index = 56
|
||||
Info index = 57
|
||||
Info index = 58
|
||||
Info index = 59
|
||||
-- logging 60 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 61 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 62 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 63 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 64 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 65 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 66 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 67 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 68 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 69 at level INFO, messages should be seen every 10 events --
|
||||
Info index = 60
|
||||
Info index = 61
|
||||
Info index = 62
|
||||
Info index = 63
|
||||
Info index = 64
|
||||
Info index = 65
|
||||
Info index = 66
|
||||
Info index = 67
|
||||
Info index = 68
|
||||
Info index = 69
|
||||
-- logging 70 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 71 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 72 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 73 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 74 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 75 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 76 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 77 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 78 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 79 at level INFO, messages should be seen every 10 events --
|
||||
Info index = 70
|
||||
Info index = 71
|
||||
Info index = 72
|
||||
Info index = 73
|
||||
Info index = 74
|
||||
Info index = 75
|
||||
Info index = 76
|
||||
Info index = 77
|
||||
Info index = 78
|
||||
Info index = 79
|
||||
-- logging 80 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 81 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 82 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 83 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 84 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 85 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 86 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 87 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 88 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 89 at level INFO, messages should be seen every 10 events --
|
||||
Info index = 80
|
||||
Info index = 81
|
||||
Info index = 82
|
||||
Info index = 83
|
||||
Info index = 84
|
||||
Info index = 85
|
||||
Info index = 86
|
||||
Info index = 87
|
||||
Info index = 88
|
||||
Info index = 89
|
||||
-- logging 90 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 91 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 92 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 93 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 94 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 95 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 96 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 97 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 98 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 99 at level INFO, messages should be seen every 10 events --
|
||||
Info index = 90
|
||||
Info index = 91
|
||||
Info index = 92
|
||||
Info index = 93
|
||||
Info index = 94
|
||||
Info index = 95
|
||||
Info index = 96
|
||||
Info index = 97
|
||||
Info index = 98
|
||||
Info index = 99
|
||||
-- logging 100 at level INFO, messages should be seen every 10 events --
|
||||
-- logging 101 at level INFO, messages should be seen every 10 events --
|
||||
Info index = 100
|
||||
Info index = 101
|
||||
-- log_test7 end --------------------------------------------------------
|
||||
-- log_test8 begin --------------------------------------------------------
|
||||
-- log_test8 end --------------------------------------------------------
|
||||
-- log_test9 begin --------------------------------------------------------
|
||||
-- log_test9 end --------------------------------------------------------
|
||||
-- log_test10 begin --------------------------------------------------------
|
||||
logger not derived from logging.Logger: NotALogger
|
||||
INFO:mylogger:Starting...
|
||||
DEBUG:mylogger:Debug message not in exception handler (no traceback)
|
||||
INFO:mylogger:About to throw exception...
|
||||
DEBUG:mylogger:Debug message inside exception handler (traceback)
|
||||
Traceback (most recent call last):
|
||||
File "C:\Projects\RDC\Python\packages\logging\test\log_test10.py", line 77, in run
|
||||
print "7" + 4
|
||||
TypeError: cannot concatenate 'str' and 'int' objects
|
||||
INFO:mylogger:Done.
|
||||
-- log_test10 end --------------------------------------------------------
|
||||
-- log_test12 begin --------------------------------------------------------
|
||||
INFO:log_test12:Jackdaws love my big sphinx of quartz
|
||||
INFO:log_test12:Jackdaws love my big sphinx of quartz
|
||||
DEBUG:log_test12:Pack my box with twelve dozen liquor jugs
|
||||
DEBUG:log_test12:Pack my box with twelve dozen liquor jugs
|
||||
-- log_test12 end --------------------------------------------------------
|
||||
-- log_test13 begin --------------------------------------------------------
|
||||
INFO:log_test13:Jackdaws love my big sphinx of quartz
|
||||
DEBUG:log_test13:Pack my box with five dozen liquor jugs
|
||||
-- log_test13 end --------------------------------------------------------
|
||||
-- log_test15 begin --------------------------------------------------------
|
||||
Unfiltered...
|
||||
INFO:a:Info 1
|
||||
INFO:a.b:Info 2
|
||||
INFO:a.c:Info 3
|
||||
INFO:a.b.c:Info 4
|
||||
INFO:a.b.c.d:Info 5
|
||||
INFO:a.bb.c:Info 6
|
||||
INFO:b:Info 7
|
||||
INFO:b.a:Info 8
|
||||
INFO:c.a.b:Info 9
|
||||
INFO:a.bb:Info 10
|
||||
Filtered with 'a.b'...
|
||||
INFO:a.b:Info 2
|
||||
INFO:a.b.c:Info 4
|
||||
INFO:a.b.c.d:Info 5
|
||||
-- log_test15 end --------------------------------------------------------
|
||||
@@ -0,0 +1,24 @@
|
||||
About to start TCP server...
|
||||
About to start UDP server...
|
||||
About to start HTTP server...
|
||||
About to start SOAP server...
|
||||
-- log_test0 begin --------------------------------------------------------
|
||||
-- log_test0 end --------------------------------------------------------
|
||||
-- log_test2 begin --------------------------------------------------------
|
||||
-- log_test2 end --------------------------------------------------------
|
||||
-- log_test4 begin --------------------------------------------------------
|
||||
-- log_test4 end --------------------------------------------------------
|
||||
-- log_test7 begin --------------------------------------------------------
|
||||
-- log_test7 end --------------------------------------------------------
|
||||
-- log_test8 begin --------------------------------------------------------
|
||||
-- log_test8 end --------------------------------------------------------
|
||||
-- log_test9 begin --------------------------------------------------------
|
||||
-- log_test9 end --------------------------------------------------------
|
||||
-- log_test10 begin --------------------------------------------------------
|
||||
-- log_test10 end --------------------------------------------------------
|
||||
-- log_test12 begin --------------------------------------------------------
|
||||
-- log_test12 end --------------------------------------------------------
|
||||
-- log_test13 begin --------------------------------------------------------
|
||||
-- log_test13 end --------------------------------------------------------
|
||||
-- log_test15 begin --------------------------------------------------------
|
||||
-- log_test15 end --------------------------------------------------------
|
||||
@@ -0,0 +1,60 @@
|
||||
[loggers]
|
||||
keys=root,log02,log03,log04,log05
|
||||
|
||||
[handlers]
|
||||
keys=hand01
|
||||
|
||||
[formatters]
|
||||
keys=form01
|
||||
|
||||
[logger_root]
|
||||
level=WARN
|
||||
propagate=1
|
||||
channel=
|
||||
parent=
|
||||
qualname=(root)
|
||||
handlers=hand01
|
||||
|
||||
[logger_log02]
|
||||
level=WARN
|
||||
propagate=1
|
||||
channel=A
|
||||
parent=(root)
|
||||
qualname=A
|
||||
handlers=
|
||||
|
||||
[logger_log03]
|
||||
level=WARN
|
||||
propagate=1
|
||||
channel=B
|
||||
parent=log02
|
||||
qualname=A.B
|
||||
handlers=
|
||||
|
||||
[logger_log04]
|
||||
level=WARN
|
||||
propagate=1
|
||||
channel=C
|
||||
parent=log03
|
||||
qualname=A.B.C
|
||||
handlers=
|
||||
|
||||
[logger_log05]
|
||||
level=WARN
|
||||
propagate=1
|
||||
channel=D
|
||||
parent=log04
|
||||
qualname=A.B.C.D
|
||||
handlers=
|
||||
|
||||
[handler_hand01]
|
||||
class=StreamHandler
|
||||
level=NOTSET
|
||||
formatter=form01
|
||||
stream=sys.stderr
|
||||
args=(sys.stderr,)
|
||||
|
||||
[formatter_form01]
|
||||
format=warn.ini %(name)s %(levelname)s %(message)s
|
||||
datefmt=
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#============================================================================
|
||||
# Install the logging package from python 2.3 if not present.
|
||||
#============================================================================
|
||||
import os
|
||||
|
||||
try:
|
||||
import logging
|
||||
except ImportError:
|
||||
print 'logging package not found: installing'
|
||||
os.chdir('logging-0.4.9.2')
|
||||
execfile('setup.py')
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
from distutils.core import setup, Extension
|
||||
import os
|
||||
|
||||
XEN_ROOT = "../.."
|
||||
|
||||
@@ -47,3 +48,6 @@ setup(name = 'xen',
|
||||
ext_package = "xen.lowlevel",
|
||||
ext_modules = [ xc, xu ]
|
||||
)
|
||||
|
||||
os.chdir('logging')
|
||||
execfile('setup.py')
|
||||
@@ -22,6 +22,8 @@ import XendConsole
|
||||
import XendMigrate
|
||||
import EventServer
|
||||
from XendError import XendError
|
||||
from XendLogging import log
|
||||
|
||||
|
||||
from xen.xend.server import SrvDaemon
|
||||
xend = SrvDaemon.instance()
|
||||
@@ -52,7 +54,7 @@ class XendDomain:
|
||||
self.db = XendDB.XendDB(self.dbpath)
|
||||
self.domain_db = self.db.fetchall("")
|
||||
if xroot.get_rebooted():
|
||||
print 'XendDomain> rebooted: removing all domain info'
|
||||
log.info('XendDomain> rebooted: removing all domain info')
|
||||
self.rm_all()
|
||||
eserver.subscribe('xend.virq', self.onVirq)
|
||||
self.initial_refresh()
|
||||
@@ -226,10 +228,10 @@ class XendDomain:
|
||||
casualties.append(d)
|
||||
for d in casualties:
|
||||
id = str(d['dom'])
|
||||
print 'XendDomain>reap> died id=', id, d
|
||||
log.debug('XendDomain>reap> domain died id=%s', id)
|
||||
if d['shutdown']:
|
||||
reason = XendDomainInfo.shutdown_reason(d['shutdown_reason'])
|
||||
print 'XendDomain>reap> shutdown id=', id, reason
|
||||
log.debug('XendDomain>reap> shutdown id=%s reason=%s', id, reason)
|
||||
if reason in ['poweroff', 'reboot']:
|
||||
self.domain_restart_schedule(id, reason)
|
||||
self.final_domain_destroy(id)
|
||||
@@ -283,7 +285,7 @@ class XendDomain:
|
||||
try:
|
||||
self._delete_domain(id)
|
||||
except:
|
||||
print 'refresh_domain: error'
|
||||
log.exception('refresh_domain> error')
|
||||
raise
|
||||
pass
|
||||
else:
|
||||
@@ -328,7 +330,7 @@ class XendDomain:
|
||||
@param config: configuration
|
||||
@return: deferred
|
||||
"""
|
||||
print 'domain_configure>', id, config
|
||||
log.debug('domain_configure> id=%s config=%s', id, str(config))
|
||||
dom = int(id)
|
||||
dominfo = self.domain_get(dom)
|
||||
if not dominfo:
|
||||
@@ -417,7 +419,7 @@ class XendDomain:
|
||||
@param id: domain id
|
||||
@param reason: shutdown reason
|
||||
"""
|
||||
print 'domain_restart_schedule>', id, reason, set
|
||||
log.debug('domain_restart_schedule> %s %s %d', id, reason, set)
|
||||
dominfo = self.domain.get(id)
|
||||
if not dominfo:
|
||||
return
|
||||
@@ -430,7 +432,7 @@ class XendDomain:
|
||||
# Avoid multiple restarts.
|
||||
dominfo.restart_mode = XendDomainInfo.RESTART_NEVER
|
||||
self.restarts[id] = dominfo.config
|
||||
print 'Scheduling restart for domain:', id, dominfo.name
|
||||
log.info('Scheduling restart for domain: id=%s name=%s', id, dominfo.name)
|
||||
self.domain_restarts_schedule()
|
||||
|
||||
def domain_restart_cancel(self, id):
|
||||
@@ -456,18 +458,17 @@ class XendDomain:
|
||||
# Remove it from the restarts.
|
||||
del self.restarts[id]
|
||||
try:
|
||||
print 'domain_restarts> restart:', id, config
|
||||
log.info('domain_restarts> restart: id=%s config=%s', id, str(config))
|
||||
def cbok(dominfo):
|
||||
print 'Restarted domain', id, 'as', dominfo.id
|
||||
log.info('Restarted domain %s as %s', id, dominfo.id)
|
||||
self.domain_unpause(dominfo.id)
|
||||
def cberr(err):
|
||||
print >>sys.stderr, "Delayed exception restarting domain: ", err
|
||||
log.exception("Delayed exception restarting domain")
|
||||
deferred = self.domain_create(config)
|
||||
deferred.addCallback(cbok)
|
||||
deferred.addErrback(cberr)
|
||||
except:
|
||||
print >>sys.stderr, "XendDomain> Exception restarting domain"
|
||||
traceback.print_exc(sys.stderr)
|
||||
log.exception("Exception restarting domain")
|
||||
if len(self.restarts):
|
||||
self.refresh_schedule(delay=5)
|
||||
|
||||
@@ -479,6 +480,7 @@ class XendDomain:
|
||||
dom = int(id)
|
||||
if dom <= 0:
|
||||
return 0
|
||||
log.info('Destroying domain %s', str(id))
|
||||
eserver.inject('xend.domain.destroy', id)
|
||||
dominfo = self.domain.get(id)
|
||||
if dominfo:
|
||||
|
||||
@@ -26,6 +26,7 @@ import sxp
|
||||
|
||||
import XendConsole
|
||||
xendConsole = XendConsole.instance()
|
||||
from XendLogging import log
|
||||
|
||||
import server.SrvDaemon
|
||||
xend = server.SrvDaemon.instance()
|
||||
@@ -537,6 +538,7 @@ class XendDomainInfo:
|
||||
if self.dom is None: return 0
|
||||
chan = xend.getDomChannel(self.dom)
|
||||
if chan:
|
||||
log.debug("Closing channel to domain %d", self.dom)
|
||||
chan.close()
|
||||
return xc.domain_destroy(dom=self.dom)
|
||||
|
||||
@@ -564,6 +566,7 @@ class XendDomainInfo:
|
||||
if self.dom is None: return
|
||||
ctrl = xend.netif_get(self.dom)
|
||||
if ctrl:
|
||||
log.debug("Destroying vifs for domain %d", self.dom)
|
||||
ctrl.destroy()
|
||||
|
||||
def release_vbds(self):
|
||||
@@ -572,6 +575,7 @@ class XendDomainInfo:
|
||||
if self.dom is None: return
|
||||
ctrl = xend.blkif_get(self.dom)
|
||||
if ctrl:
|
||||
log.debug("Destroying vbds for domain %d", self.dom)
|
||||
ctrl.destroy()
|
||||
|
||||
def show(self):
|
||||
@@ -599,11 +603,11 @@ class XendDomainInfo:
|
||||
memory = self.memory
|
||||
name = self.name
|
||||
cpu = int(sxp.child_value(self.config, 'cpu', '-1'))
|
||||
#print 'init_domain>', memory, name, cpu
|
||||
dom = xc.domain_create(mem_kb= memory * 1024, name= name, cpu= cpu)
|
||||
if dom <= 0:
|
||||
raise VmError('Creating domain failed: name=%s memory=%d'
|
||||
% (name, memory))
|
||||
log.debug('init_domain> Created domain=%d name=%s memory=%d', dom, name, memory)
|
||||
self.setdom(dom)
|
||||
|
||||
if self.startTime is None:
|
||||
@@ -614,7 +618,7 @@ class XendDomainInfo:
|
||||
"""
|
||||
if self.recreate: return
|
||||
if len(cmdline) >= 256:
|
||||
print 'Warning: kernel cmdline too long'
|
||||
log.warning('kernel cmdline too long, domain %d', self.dom)
|
||||
dom = self.dom
|
||||
buildfn = getattr(xc, '%s_build' % ostype)
|
||||
#print 'build_domain>', ostype, dom, kernel, cmdline, ramdisk
|
||||
@@ -803,6 +807,8 @@ class XendDomainInfo:
|
||||
if field_handler:
|
||||
v = field_handler(self, self.config, field, field_index)
|
||||
append_deferred(dlist, v)
|
||||
else:
|
||||
log.warning("Unknown config field %s", field_name)
|
||||
index[field_name] = field_index + 1
|
||||
d = defer.DeferredList(dlist, fireOnOneErrback=1)
|
||||
return d
|
||||
@@ -872,6 +878,7 @@ def vm_dev_vif(vm, val, index):
|
||||
vif = index #todo
|
||||
vmac = sxp.child_value(val, "mac")
|
||||
xend.netif_create(vm.dom, recreate=vm.recreate)
|
||||
log.debug("Creating vif dom=%d vif=%d mac=%s", vm.dom, vif, str(vmac))
|
||||
defer = xend.netif_dev_create(vm.dom, vif, val, recreate=vm.recreate)
|
||||
def fn(id):
|
||||
dev = xend.netif_dev(vm.dom, vif)
|
||||
@@ -898,6 +905,7 @@ def vm_dev_vbd(vm, val, index):
|
||||
if not dev:
|
||||
raise VmError('vbd: Missing dev')
|
||||
mode = sxp.child_value(val, 'mode', 'r')
|
||||
log.debug("Creating vbd dom=%d uname=%s dev=%s", vm.dom, uname, dev)
|
||||
defer = make_disk(vm.dom, uname, dev, mode, vm.recreate)
|
||||
def fn(vbd):
|
||||
dev = xend.blkif_dev(vm.dom, vdev)
|
||||
@@ -932,6 +940,7 @@ def vm_dev_pci(vm, val, index):
|
||||
func = parse_pci(func)
|
||||
except:
|
||||
raise VmError('pci: invalid parameter')
|
||||
log.debug("Creating pci device dom=%d bus=%x dev=%x func=%x", vm.dom, bus, dev, func)
|
||||
rc = xc.physdev_pci_access_modify(dom=vm.dom, bus=bus, dev=dev,
|
||||
func=func, enable=1)
|
||||
if rc < 0:
|
||||
@@ -974,13 +983,13 @@ def vnet_bridge(vnet, vmac, dom, idx):
|
||||
vif = "vif%d.%d" % (dom, idx)
|
||||
try:
|
||||
cmd = "(vif.conn (vif %s) (vnet %s) (vmac %s))" % (vif, vnet, vmac)
|
||||
print "*** vnet_bridge>", cmd
|
||||
log.debug("vnet_bridge> %s", cmd)
|
||||
out = file("/proc/vnet/policy", "wb")
|
||||
out.write(cmd)
|
||||
err = out.close()
|
||||
print "vnet_bridge>", "err=", err
|
||||
log.debug("vnet_bridge> err=%d", err)
|
||||
except IOError, ex:
|
||||
print "vnet_bridge>", ex
|
||||
log.exception("vnet_bridge>")
|
||||
|
||||
def vm_field_vnet(vm, config, val, index):
|
||||
"""Handle a vnet field in a config.
|
||||
@@ -1005,6 +1014,9 @@ def vm_field_vnet(vm, config, val, index):
|
||||
#vnet_bridge(vnet, mac, vm.dom, 0)
|
||||
#vm.add_config([ 'vif.vnet', ['id', id], ['vnet', vnet], ['mac', mac]])
|
||||
|
||||
def vm_field_ignore(vm, config, val, index):
|
||||
pass
|
||||
|
||||
# Register image handlers for linux and bsd.
|
||||
add_image_handler('linux', vm_image_linux)
|
||||
add_image_handler('netbsd', vm_image_netbsd)
|
||||
@@ -1014,6 +1026,15 @@ add_device_handler('vif', vm_dev_vif)
|
||||
add_device_handler('vbd', vm_dev_vbd)
|
||||
add_device_handler('pci', vm_dev_pci)
|
||||
|
||||
# Ignore the fields we already handle.
|
||||
add_config_handler('name', vm_field_ignore)
|
||||
add_config_handler('memory', vm_field_ignore)
|
||||
add_config_handler('cpu', vm_field_ignore)
|
||||
add_config_handler('console', vm_field_ignore)
|
||||
add_config_handler('image', vm_field_ignore)
|
||||
add_config_handler('device', vm_field_ignore)
|
||||
add_config_handler('backend', vm_field_ignore)
|
||||
|
||||
# Register config handlers for vfr and vnet.
|
||||
add_config_handler('vfr', vm_field_vfr)
|
||||
add_config_handler('vnet', vm_field_vnet)
|
||||
@@ -0,0 +1,63 @@
|
||||
# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
|
||||
|
||||
import types
|
||||
import logging
|
||||
from logging import Formatter, StreamHandler
|
||||
from logging.handlers import RotatingFileHandler
|
||||
|
||||
class XendLogging:
|
||||
|
||||
KB = 1024
|
||||
MB = 1024 * KB
|
||||
|
||||
maxBytes = 1 * MB
|
||||
backupCount = 5
|
||||
|
||||
logStderrFormat = "[%(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
|
||||
logFileFormat = "[%(asctime)s %(name)s] %(levelname)s (%(module)s:%(lineno)d) %(message)s"
|
||||
dateFormat = "%Y-%m-%d %H:%M:%S"
|
||||
|
||||
def __init__(self, filename, level=logging.INFO, maxBytes=None, backupCount=None):
|
||||
self.setLevel(level)
|
||||
if maxBytes:
|
||||
self.maxBytes = maxBytes
|
||||
if backupCount:
|
||||
self.backupCount = backupCount
|
||||
self.initLogFile(filename)
|
||||
self.initLogStderr()
|
||||
pass
|
||||
|
||||
def setLevel(self, level):
|
||||
if isinstance(level, types.StringType):
|
||||
level = logging._levelNames[level]
|
||||
self.getLogger().setLevel(level)
|
||||
self.level = level
|
||||
|
||||
def getLevel(self, level):
|
||||
return logging.getLevelName(self.level)
|
||||
|
||||
def getLogger(self):
|
||||
return logging.getLogger("xend")
|
||||
|
||||
def initLogFile(self, filename):
|
||||
self.logfile = RotatingFileHandler(filename,
|
||||
mode='a',
|
||||
maxBytes=self.maxBytes,
|
||||
backupCount=self.backupCount)
|
||||
self.logfile.setFormatter(Formatter(self.logFileFormat, self.dateFormat))
|
||||
log = self.getLogger()
|
||||
log.addHandler(self.logfile)
|
||||
|
||||
def getLogFile(self):
|
||||
return self.logfile
|
||||
|
||||
def initLogStderr(self):
|
||||
self.logstderr = StreamHandler()
|
||||
self.logstderr.setFormatter(Formatter(self.logStderrFormat, self.dateFormat))
|
||||
self.getLogger().addHandler(self.logstderr)
|
||||
|
||||
def getLogStderr(self):
|
||||
return self.logstderr
|
||||
|
||||
log = logging.getLogger("xend")
|
||||
|
||||
@@ -7,7 +7,9 @@ Creates the event server and handles configuration.
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
import EventServer
|
||||
from XendLogging import XendLogging
|
||||
|
||||
# Initial create of the event server.
|
||||
eserver = EventServer.instance()
|
||||
@@ -44,6 +46,10 @@ class XendRoot:
|
||||
"""Where network control scripts live."""
|
||||
network_script_dir = "/etc/xen"
|
||||
|
||||
logfile_default = "/var/log/xend.log"
|
||||
|
||||
loglevel_default = 'DEBUG'
|
||||
|
||||
def __init__(self):
|
||||
self.rebooted = 0
|
||||
self.last_reboot = None
|
||||
@@ -104,9 +110,21 @@ class XendRoot:
|
||||
def configure(self):
|
||||
print 'XendRoot>configure>'
|
||||
self.set_config()
|
||||
self.configure_logger()
|
||||
self.dbroot = self.get_config_value("dbroot", self.dbroot_default)
|
||||
self.lastboot = self.get_config_value("lastboot", self.lastboot_default)
|
||||
|
||||
def configure_logger(self):
|
||||
logfile = self.get_config_value("logfile", self.logfile_default)
|
||||
loglevel = self.get_config_value("loglevel", self.loglevel_default)
|
||||
self.logging = XendLogging(logfile, level=loglevel)
|
||||
|
||||
def get_logging(self):
|
||||
return self.logging
|
||||
|
||||
def get_logger(self):
|
||||
return self.logging.getLogger()
|
||||
|
||||
def get_dbroot(self):
|
||||
"""Get the path to the database root.
|
||||
"""
|
||||
@@ -181,3 +199,6 @@ def instance():
|
||||
except:
|
||||
inst = XendRoot()
|
||||
return inst
|
||||
|
||||
def logger():
|
||||
return instance().get_logger()
|
||||
@@ -32,8 +32,9 @@ from xen.xend import PrettyPrint
|
||||
from xen.xend import EventServer
|
||||
eserver = EventServer.instance()
|
||||
from xen.xend.XendError import XendError
|
||||
|
||||
from xen.xend.server import SrvServer
|
||||
from xen.xend import XendRoot
|
||||
from xen.xend.XendLogging import log
|
||||
|
||||
import channel
|
||||
import blkif
|
||||
@@ -514,11 +515,7 @@ class Daemon:
|
||||
pidfile.close()
|
||||
return 0
|
||||
# Child
|
||||
logfile = self.open_logfile()
|
||||
self.redirect_output(logfile)
|
||||
|
||||
self.tracing(trace)
|
||||
|
||||
self.run()
|
||||
return 0
|
||||
|
||||
@@ -590,16 +587,6 @@ class Daemon:
|
||||
#del tb
|
||||
return self.trace
|
||||
|
||||
def open_logfile(self):
|
||||
if not os.path.exists(CONTROL_DIR):
|
||||
os.makedirs(CONTROL_DIR)
|
||||
|
||||
# Open log file. Truncate it if non-empty, and request line buffering.
|
||||
if os.path.isfile(LOG_FILE):
|
||||
os.rename(LOG_FILE, LOG_FILE+'.old')
|
||||
logfile = open(LOG_FILE, 'w+', 1)
|
||||
return logfile
|
||||
|
||||
def set_user(self):
|
||||
# Set the UID.
|
||||
try:
|
||||
@@ -609,22 +596,12 @@ class Daemon:
|
||||
print "Error: no such user '%s'" % USER
|
||||
return 1
|
||||
|
||||
def redirect_output(self, logfile):
|
||||
if DEBUG: return
|
||||
# Close down standard file handles
|
||||
try:
|
||||
os.close(0) # stdin
|
||||
os.close(1) # stdout
|
||||
os.close(2) # stderr
|
||||
except:
|
||||
pass
|
||||
# Redirect output to log file.
|
||||
sys.stdout = sys.stderr = logfile
|
||||
|
||||
def stop(self):
|
||||
return self.cleanup(kill=True)
|
||||
|
||||
def run(self):
|
||||
xroot = XendRoot.instance()
|
||||
log.info("Xend Daemon started")
|
||||
self.createFactories()
|
||||
self.listenMgmt()
|
||||
self.listenEvent()
|
||||
@@ -709,7 +686,6 @@ class Daemon:
|
||||
ctrl = self.blkifCF.getInstanceByDom(dom)
|
||||
if not ctrl:
|
||||
raise XendError('No blkif controller: %d' % dom)
|
||||
print 'blkif_dev_create>', dom, vdev, mode, segment
|
||||
d = ctrl.attachDevice(vdev, mode, segment, recreate=recreate)
|
||||
return d
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ from twisted.internet import defer
|
||||
#defer.Deferred.debug = 1
|
||||
|
||||
from xen.xend import sxp
|
||||
from xen.xend import PrettyPrint
|
||||
from xen.xend.XendLogging import log
|
||||
|
||||
import channel
|
||||
import controller
|
||||
@@ -143,7 +143,6 @@ class BlkifControllerFactory(controller.ControllerFactory):
|
||||
@param d: deferred to call
|
||||
@type d: Deferred
|
||||
"""
|
||||
print 'respond_be_create>'
|
||||
val = unpackMsg('blkif_be_create_t', msg)
|
||||
blkif = self.getInstanceByDom(val['domid'])
|
||||
d.callback(blkif)
|
||||
@@ -154,7 +153,6 @@ class BlkifControllerFactory(controller.ControllerFactory):
|
||||
@param msg: message
|
||||
@type msg: xu message
|
||||
"""
|
||||
print 'respond_be_connect>', self
|
||||
val = unpackMsg('blkif_be_connect_t', msg)
|
||||
blkif = self.getInstanceByDom(val['domid'])
|
||||
if blkif:
|
||||
@@ -172,7 +170,6 @@ class BlkifControllerFactory(controller.ControllerFactory):
|
||||
@param d: deferred to call
|
||||
@type d: Deferred
|
||||
"""
|
||||
print 'recv_be_vbd_create>', self
|
||||
val = unpackMsg('blkif_be_vbd_create_t', msg)
|
||||
blkif = self.getInstanceByDom(val['domid'])
|
||||
if blkif:
|
||||
@@ -191,7 +188,6 @@ class BlkifControllerFactory(controller.ControllerFactory):
|
||||
@param d: deferred to call
|
||||
@type d: Deferred or None
|
||||
"""
|
||||
print 'recv_be_vbd_grow>', self
|
||||
val = unpackMsg('blkif_be_vbd_grow_t', msg)
|
||||
# Check status?
|
||||
if self.attached:
|
||||
@@ -208,7 +204,6 @@ class BlkifControllerFactory(controller.ControllerFactory):
|
||||
@param req: request flag (true if the msg is a request)
|
||||
@type req: bool
|
||||
"""
|
||||
print 'recv_be_driver_status_changed>', self, req
|
||||
val = unpackMsg('blkif_be_driver_status_changed_t', msg)
|
||||
status = val['status']
|
||||
if status == BLKIF_DRIVER_STATUS_UP and not self.attached:
|
||||
@@ -236,6 +231,7 @@ class BlkDev(controller.Dev):
|
||||
return val
|
||||
|
||||
def destroy(self):
|
||||
log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev)
|
||||
self.controller.send_be_vbd_destroy(self.vdev)
|
||||
|
||||
class BlkifController(controller.Controller):
|
||||
@@ -319,6 +315,7 @@ class BlkifController(controller.Controller):
|
||||
def destroy(self):
|
||||
def cb_destroy(val):
|
||||
self.send_be_destroy()
|
||||
log.debug("Destroying blkif domain=%d", self.dom)
|
||||
d = defer.Deferred()
|
||||
d.addCallback(cb_destroy)
|
||||
self.send_be_disconnect(response=d)
|
||||
@@ -369,8 +366,8 @@ class BlkifController(controller.Controller):
|
||||
def recv_fe_interface_connect(self, msg, req):
|
||||
val = unpackMsg('blkif_fe_interface_connect_t', msg)
|
||||
self.evtchn = channel.eventChannel(0, self.dom)
|
||||
print 'recv_fe_interface_connect>'
|
||||
PrettyPrint.prettyprint(self.sxpr())
|
||||
log.debug("Connecting blkif to event channel dom=%d ports=%d:%d",
|
||||
self.dom, self.evtchn['port1'], self.evtchn['port2'])
|
||||
msg = packMsg('blkif_be_connect_t',
|
||||
{ 'domid' : self.dom,
|
||||
'blkif_handle' : val['handle'],
|
||||
@@ -394,14 +391,14 @@ class BlkifController(controller.Controller):
|
||||
self.factory.writeRequest(msg, response=response)
|
||||
|
||||
def send_be_disconnect(self, response=None):
|
||||
print '>BlkifController>send_be_disconnect>', 'dom=', self.dom
|
||||
log.debug('>BlkifController>send_be_disconnect> dom=%d', self.dom)
|
||||
msg = packMsg('blkif_be_disconnect_t',
|
||||
{ 'domid' : self.dom,
|
||||
'blkif_handle' : 0 })
|
||||
self.factory.writeRequest(msg, response=response)
|
||||
|
||||
def send_be_destroy(self, response=None):
|
||||
print '>BlkifController>send_be_destroy>', 'dom=', self.dom
|
||||
log.debug('>BlkifController>send_be_destroy> dom=%d', self.dom)
|
||||
msg = packMsg('blkif_be_destroy_t',
|
||||
{ 'domid' : self.dom,
|
||||
'blkif_handle' : 0 })
|
||||
@@ -428,8 +425,7 @@ class BlkifController(controller.Controller):
|
||||
self.factory.writeRequest(msg, response=response)
|
||||
|
||||
def send_be_vbd_destroy(self, vdev, response=None):
|
||||
print '>BlkifController>send_be_vbd_destroy>', 'dom=', self.dom, 'vdev=', vdev
|
||||
PrettyPrint.prettyprint(self.sxpr())
|
||||
log.debug('>BlkifController>send_be_vbd_destroy> dom=%d vdev=%d', self.dom, vdev)
|
||||
dev = self.devices[vdev]
|
||||
msg = packMsg('blkif_be_vbd_destroy_t',
|
||||
{ 'domid' : self.dom,
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
from twisted.internet import reactor
|
||||
from twisted.internet import protocol
|
||||
from twisted.protocols import telnet
|
||||
|
||||
from xen.lowlevel import xu
|
||||
|
||||
from xen.xend.XendError import XendError
|
||||
from xen.xend import EventServer
|
||||
eserver = EventServer.instance()
|
||||
from xen.xend.XendLogging import log
|
||||
|
||||
import controller
|
||||
from messages import *
|
||||
@@ -36,6 +36,8 @@ class ConsoleProtocol(protocol.Protocol):
|
||||
# KAF: A nice quiet successful connect.
|
||||
#self.transport.write("Connected to console %d on domain %d\n"
|
||||
# % (self.idx, self.controller.dom))
|
||||
log.info("Console connected %s %s %s",
|
||||
self.idx, str(self.addr[0]), str(self.addr[1]))
|
||||
eserver.inject('xend.console.connect',
|
||||
[self.idx, self.addr[0], self.addr[1]])
|
||||
|
||||
@@ -49,6 +51,8 @@ class ConsoleProtocol(protocol.Protocol):
|
||||
return len(data)
|
||||
|
||||
def connectionLost(self, reason=None):
|
||||
log.info("Console disconnected %s %s %s",
|
||||
self.idx, str(self.addr[0]), str(self.addr[1]))
|
||||
eserver.inject('xend.console.disconnect',
|
||||
[self.idx, self.addr[0], self.addr[1]])
|
||||
self.controller.disconnect()
|
||||
@@ -83,11 +87,14 @@ class ConsoleControllerFactory(controller.ControllerFactory):
|
||||
raise XendError('console port in use: ' + str(console_port))
|
||||
console = ConsoleController(self, dom, console_port)
|
||||
self.addInstance(console)
|
||||
log.info("Created console id=%s domain=%d port=%d",
|
||||
console.idx, console.dom, console.console_port)
|
||||
eserver.inject('xend.console.create',
|
||||
[console.idx, console.dom, console.console_port])
|
||||
return console
|
||||
|
||||
def consoleClosed(self, console):
|
||||
log.info("Closed console id=%s", console.idx)
|
||||
eserver.inject('xend.console.close', console.idx)
|
||||
self.delInstance(console)
|
||||
|
||||
|
||||
@@ -50,7 +50,6 @@ class DomainController(controller.Controller):
|
||||
controller.Controller.__init__(self, factory, dom)
|
||||
self.majorTypes = [ CMSG_SHUTDOWN ]
|
||||
self.registerChannel()
|
||||
print 'DomainController>', self, self.channel, self.idx
|
||||
|
||||
def shutdown(self, reason):
|
||||
"""Shutdown a domain.
|
||||
|
||||
@@ -6,9 +6,9 @@ from twisted.internet import defer
|
||||
#defer.Deferred.debug = 1
|
||||
|
||||
from xen.xend import sxp
|
||||
from xen.xend import PrettyPrint
|
||||
from xen.xend import Vifctl
|
||||
from xen.xend.XendError import XendError
|
||||
from xen.xend.XendLogging import log
|
||||
|
||||
import channel
|
||||
import controller
|
||||
@@ -93,7 +93,7 @@ class NetifControllerFactory(controller.ControllerFactory):
|
||||
if netif:
|
||||
netif.send_interface_connected(vif)
|
||||
else:
|
||||
print "respond_be_connect> unknown vif=", vif
|
||||
log.warning("respond_be_connect> unknown dom=%d vif=%d", dom, vif)
|
||||
pass
|
||||
|
||||
def recv_be_driver_status_changed(self, msg, req):
|
||||
@@ -183,6 +183,7 @@ class NetDev(controller.Dev):
|
||||
"""
|
||||
def cb_destroy(val):
|
||||
self.controller.send_be_destroy(self.vif)
|
||||
log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
|
||||
self.vifctl('down')
|
||||
d = defer.Deferred()
|
||||
d.addCallback(cb_destroy)
|
||||
@@ -328,7 +329,6 @@ class NetifController(controller.Controller):
|
||||
self.factory.writeRequest(msg, response=response)
|
||||
|
||||
def send_be_destroy(self, vif, response=None):
|
||||
PrettyPrint.prettyprint(self.sxpr())
|
||||
dev = self.devices[vif]
|
||||
del self.devices[vif]
|
||||
msg = packMsg('netif_be_destroy_t',
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# The following parameters could be placed in a configuration file.
|
||||
PID_FILE = '/var/run/xend.pid'
|
||||
LOG_FILE = '/var/log/xend.log'
|
||||
USER = 'root'
|
||||
CONTROL_DIR = '/var/run/xend'
|
||||
MGMT_SOCK = 'xendsock' # relative to CONTROL_DIR
|
||||
|
||||