morro
This commit is contained in:
119
sqlalchemy/log.py
Normal file
119
sqlalchemy/log.py
Normal file
@@ -0,0 +1,119 @@
|
||||
# log.py - adapt python logging module to SQLAlchemy
|
||||
# Copyright (C) 2006, 2007, 2008, 2009, 2010 Michael Bayer mike_mp@zzzcomputing.com
|
||||
#
|
||||
# This module is part of SQLAlchemy and is released under
|
||||
# the MIT License: http://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
"""Logging control and utilities.
|
||||
|
||||
Control of logging for SA can be performed from the regular python logging
|
||||
module. The regular dotted module namespace is used, starting at
|
||||
'sqlalchemy'. For class-level logging, the class name is appended.
|
||||
|
||||
The "echo" keyword parameter which is available on SQLA ``Engine``
|
||||
and ``Pool`` objects corresponds to a logger specific to that
|
||||
instance only.
|
||||
|
||||
E.g.::
|
||||
|
||||
engine.echo = True
|
||||
|
||||
is equivalent to::
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger('sqlalchemy.engine.Engine.%s' % hex(id(engine)))
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
"""
|
||||
|
||||
import logging
|
||||
import sys
|
||||
from sqlalchemy import util
|
||||
|
||||
rootlogger = logging.getLogger('sqlalchemy')
|
||||
if rootlogger.level == logging.NOTSET:
|
||||
rootlogger.setLevel(logging.WARN)
|
||||
|
||||
default_enabled = False
|
||||
def default_logging(name):
|
||||
global default_enabled
|
||||
if logging.getLogger(name).getEffectiveLevel() < logging.WARN:
|
||||
default_enabled = True
|
||||
if not default_enabled:
|
||||
default_enabled = True
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
handler.setFormatter(logging.Formatter(
|
||||
'%(asctime)s %(levelname)s %(name)s %(message)s'))
|
||||
rootlogger.addHandler(handler)
|
||||
|
||||
_logged_classes = set()
|
||||
def class_logger(cls, enable=False):
|
||||
logger = logging.getLogger(cls.__module__ + "." + cls.__name__)
|
||||
if enable == 'debug':
|
||||
logger.setLevel(logging.DEBUG)
|
||||
elif enable == 'info':
|
||||
logger.setLevel(logging.INFO)
|
||||
cls._should_log_debug = lambda self: logger.isEnabledFor(logging.DEBUG)
|
||||
cls._should_log_info = lambda self: logger.isEnabledFor(logging.INFO)
|
||||
cls.logger = logger
|
||||
_logged_classes.add(cls)
|
||||
|
||||
|
||||
class Identified(object):
|
||||
@util.memoized_property
|
||||
def logging_name(self):
|
||||
# limit the number of loggers by chopping off the hex(id).
|
||||
# some novice users unfortunately create an unlimited number
|
||||
# of Engines in their applications which would otherwise
|
||||
# cause the app to run out of memory.
|
||||
return "0x...%s" % hex(id(self))[-4:]
|
||||
|
||||
|
||||
def instance_logger(instance, echoflag=None):
|
||||
"""create a logger for an instance that implements :class:`Identified`.
|
||||
|
||||
Warning: this is an expensive call which also results in a permanent
|
||||
increase in memory overhead for each call. Use only for
|
||||
low-volume, long-time-spanning objects.
|
||||
|
||||
"""
|
||||
|
||||
name = "%s.%s.%s" % (instance.__class__.__module__,
|
||||
instance.__class__.__name__, instance.logging_name)
|
||||
|
||||
if echoflag is not None:
|
||||
l = logging.getLogger(name)
|
||||
if echoflag == 'debug':
|
||||
default_logging(name)
|
||||
l.setLevel(logging.DEBUG)
|
||||
elif echoflag is True:
|
||||
default_logging(name)
|
||||
l.setLevel(logging.INFO)
|
||||
elif echoflag is False:
|
||||
l.setLevel(logging.WARN)
|
||||
else:
|
||||
l = logging.getLogger(name)
|
||||
instance._should_log_debug = lambda: l.isEnabledFor(logging.DEBUG)
|
||||
instance._should_log_info = lambda: l.isEnabledFor(logging.INFO)
|
||||
return l
|
||||
|
||||
class echo_property(object):
|
||||
__doc__ = """\
|
||||
When ``True``, enable log output for this element.
|
||||
|
||||
This has the effect of setting the Python logging level for the namespace
|
||||
of this element's class and object reference. A value of boolean ``True``
|
||||
indicates that the loglevel ``logging.INFO`` will be set for the logger,
|
||||
whereas the string value ``debug`` will set the loglevel to
|
||||
``logging.DEBUG``.
|
||||
"""
|
||||
|
||||
def __get__(self, instance, owner):
|
||||
if instance is None:
|
||||
return self
|
||||
else:
|
||||
return instance._should_log_debug() and 'debug' or \
|
||||
(instance._should_log_info() and True or False)
|
||||
|
||||
def __set__(self, instance, value):
|
||||
instance_logger(instance, echoflag=value)
|
||||
Reference in New Issue
Block a user