Module AELog
[hide private]
[frames] | no frames]

Source Code for Module AELog

  1  ''' 
  2  Defines a function for configuring the standard Python logging module, a class 
  3  that redirects print statements through the configured logging system, and 
  4  a class that defines a logging handler using XML-RPC as the transport. 
  5   
  6  @var LOG_FORMAT: Default log output format 
  7  @type LOG_FORMAT: string 
  8   
  9  @author: Peter Parente 
 10  @organization: IBM Corporation 
 11  @copyright: Copyright (c) 2005, 2007 IBM Corporation 
 12  @license: The BSD License 
 13   
 14  All rights reserved. This program and the accompanying materials are made  
 15  available under the terms of the BSD license which accompanies 
 16  this distribution, and is available at  
 17  U{http://www.opensource.org/licenses/bsd-license.php} 
 18  ''' 
 19  import logging, logging.config, sys, socket, xmlrpclib 
 20   
 21  # define a default format for log entries 
 22  # see http://docs.python.org/lib/node352.html 
 23  LOG_FORMAT = '[%(name)s %(levelname)s %(asctime)s] %(message)s' 
 24   
25 -class XMLRPCHandler(logging.Handler):
26 ''' 27 Defines an XML-RPC handler for the standard Python logging system. 28 29 @ivar server: Server proxy mirroring methods on the server side 30 @type server: xmlrpclib.ServerProxy 31 '''
32 - def __init__(self, host='127.0.0.1', port=9000):
33 ''' 34 Constructs a proxy to the server. 35 36 @param host: Hostname on which the server is running 37 @type host: string 38 @param port: Port on which the server is listening 39 @type port: integer 40 ''' 41 logging.Handler.__init__(self) 42 self.server = xmlrpclib.ServerProxy('http://%s:%d' % (host, port))
43
44 - def emit(self, record):
45 ''' 46 Writes interpolated string log messages to the server. 47 48 @param record: Record to log 49 @type record: logging.LogRecord 50 ''' 51 if record is not None: 52 msg = self.format(record) 53 if msg is not None: 54 try: 55 self.server.write(msg) 56 except socket.error: 57 # ignore connection exceptions 58 pass
59 60 # hack: the logging.config.fileConfig function only looks in the logging 61 # module name space for handlers; put our handler there 62 logging.XMLRPCHandler = XMLRPCHandler 63
64 -class PrintLogger(object):
65 ''' 66 Provides a dirt-simple interface compatible with stdout and stderr. When 67 assigned to sys.stdout or sys.stderr, an instance of this class redirects 68 print statements to the logging system. This means the result of the 69 print statements can be silenced, sent to a file, etc. using the command 70 line options to LSR. The log level used is defined by the L{LEVEL} constant 71 in this class. 72 73 @cvar LEVEL: Logging level for writes directed through this class, above 74 DEBUG and below INFO 75 @type LEVEL: integer 76 @ivar log: Reference to the Print log channel 77 @type log: logging.Logger 78 ''' 79 LEVEL = 15 80
81 - def __init__(self):
82 ''' 83 Create the logger. 84 ''' 85 self.log = logging.getLogger('print') 86 self.chunks = []
87
88 - def write(self, data):
89 ''' 90 Write the given data at the debug level to the logger. Stores chunks of 91 text until a new line is encountered, then sends to the logger. 92 93 @param data: Any object that can be converted to a string 94 @type data: stringable 95 ''' 96 s = data.encode('utf-8') 97 if s.endswith('\n'): 98 self.chunks.append(s[:-1]) 99 s = ''.join(self.chunks) 100 self.log.log(self.LEVEL, s) 101 self.chunks = [] 102 else: 103 self.chunks.append(s)
104
105 -def configure(log_conf=None, log_level=None, log_channels=None, log_file=None):
106 ''' 107 Configures the logging system based on the setting specified on the command 108 line or Python logging module compatible configuration file. Defaults to 109 logging messages at the INFO level or higher to stdout. Options in the 110 configuration file always override those given on the command line. 111 112 @param log_conf: Filename of a logging module configuration file. See 113 U{http://antonym.org/node/76} and 114 U{http://docs.python.org/lib/logging-config-fileformat.html}. 115 @type log_conf: string 116 @param log_level: Include messages at this level or higher 117 @type log_level: integer 118 @param log_channels: Include messages sent only on these channels, or None 119 meaning all 120 @type log_channels: list of string 121 @param log_file: Log messages in a basic, fixed format to this file. Provided 122 for convenience for users who do not want to write their own logging conf 123 file. 124 @type log_file: string 125 ''' 126 # if a configuration file is provided, use that 127 if log_conf is not None: 128 logging.config.fileConfig(log_conf) 129 else: 130 # otherwise, fall back on a basic config 131 if log_level is None: 132 # default to logging critical messages only 133 log_level = 'info' 134 if log_level == 'print': 135 # set the log level to print statements if specified 136 level = PrintLogger.LEVEL 137 else: 138 # get the logging constant from the logging module by name; it's an 139 # uppercase version of the log_level string provided on the command line 140 level = getattr(logging, log_level.upper()) 141 # get the root logger 142 root = logging.getLogger() 143 # log to a file or to stderr 144 if log_file: 145 handler = logging.FileHandler(log_file) 146 else: 147 handler = logging.StreamHandler(sys.stderr) 148 # set the format and handler for messages 149 formatter = logging.Formatter(LOG_FORMAT) 150 root.addHandler(handler) 151 root.setLevel(level) 152 handler.setFormatter(formatter) 153 # add filters to the root handler 154 if log_channels is not None: 155 for name in log_channels: 156 handler.addFilter(logging.Filter(name)) 157 # create a print log channel, redirect all print statements to the log 158 stdout = sys.stdout 159 sys.stdout = PrintLogger()
160