This class wraps the functionality in the logging module to
provide an easier to use API for logging while providing advanced
features including a independent namespace. Each application or
library wishing to have it's own logging namespace should instantiate
exactly one instance of this class and use it to manage all it's
logging.
Traditionally (or simplistically) logging was set up with a single
global root logger with output handlers bound to it. The global
root logger (whose name is the empty string) was shared by all
code in a loaded process. The only the global unamed root logger
had a level set on it, all other loggers created inherited this
global level. This can cause conflicts in more complex scenarios
where loaded code wants to maintain it's own logging configuration
independent of whomever loaded it's code. By using only a single
logger level set on the global root logger it was not possible to
have fine grained control over individual logger output. The
pattern seen with this simplistic setup has been frequently copied
despite being clumsy and awkward. The logging module has the tools
available to support a more sophisitcated and useful model, but it
requires an overarching framework to manage. This class provides
such a framework.
An independent namespace is established by creating a independent
root logger for this manager (root_logger_name). This root logger
is a direct child of the global unamed root logger. All loggers
created by this manager will be descendants of this managers root
logger. The managers root logger has it's propagate flag set
to False which means all loggers and handlers created by this
manager will be isolated in the global logging tree.
Log level management:
Traditionally loggers inherited their logging level from the root
logger. This was simple but made it impossible to independently
control logging output from different loggers. If you set the root
level to DEBUG you got DEBUG output from every logger in the
system, often overwhelming in it's voluminous output. Many times
you want to turn on debug for just one class (a common idom is to
have one logger per class). To achieve the fine grained control
you can either use filters or set a logging level on every logger
(see the module documentation for the pros and cons). This manager
sets a log level on every logger instead of using level
inheritence because it's more efficient at run time.
Global levels are supported via the verbose and debug flags
setting every logger level to INFO and DEBUG respectively. Fine
grained level control is provided via regular expression matching
on logger names (see configure() for the details. For
example if you want to set a debug level for the foo.bar logger
set a regular expression to match it and bind it to the debug
level. Note, the global verbose and debug flags always override
the regular expression level configuration. Do not set these
global flags if you want fine grained control.
The manager maintains the minimum level for all loggers under it's
control and the minimum level for all handlers under it's
control. The reason it does this is because there is no point in
generating debug messages on a logger if there is no handler
defined which will output a debug message. Thus when the level is
set on a logger it takes into consideration the set of handlers
that logger can emit to.
IMPORTANT: Because the manager maintains knowledge about all the
loggers and handlers under it's control it is essential you use
only the managers interface to modify a logger or handler and not
set levels on the objects directly, otherwise the manger will not
know to visit every object under it's control when a configuraiton
changes (see 'LogManager.apply_configuration()).
Example Usage:
# Create a log managers for use by 'my_app'
log_mgr = LogManager('my_app')
# Create a handler to send error messages to stderr
log_mgr.create_log_handlers([dict(stream=sys.stdout,
level=logging.ERROR)])
# Create logger for a class
class Foo(object):
def __init__(self):
self.log = log_mgr.get_logger(self)
|
__init__(self,
root_logger_name='
' ,
configure_state=None)
Create a new LogManager instance using root_logger_name as the
parent of all loggers maintained by the manager. |
source code
|
|
|
|
|
configure(self,
config,
configure_state=None)
The log manager is initialized from key,value pairs in the
config dict. |
source code
|
|
|
create_log_handlers(self,
configs,
logger=None,
configure_state=None)
Create new handlers and attach them to a logger (log mangers
root logger by default). |
source code
|
|
|
get_handler(self,
handler_name)
Given a handler name return the handler object associated with
it. |
source code
|
|
|
set_handler_level(self,
handler_name,
level,
configure_state=None)
Given a handler name, set the handler's level, return previous level. |
source code
|
|
|
|
|
|
|
apply_configuration(self,
configure_state=None)
Using the log manager's internal configuration state apply the
configuration to all the objects managed by the log manager. |
source code
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Inherited from object :
__delattr__ ,
__format__ ,
__getattribute__ ,
__hash__ ,
__new__ ,
__reduce__ ,
__reduce_ex__ ,
__repr__ ,
__setattr__ ,
__sizeof__ ,
__subclasshook__
|