Python 未找到已配置日志记录的库的处理程序

Python 未找到已配置日志记录的库的处理程序,python,logging,Python,Logging,我配置了日志记录,但似乎遗漏了一步。在本例中,我使用的是sud,但使用此log方法的任何库日志记录都存在此问题 这很有效 host-03:~ # python2.7 Python 2.7.7 (default, Aug 27 2014, 16:51:46) [GCC 4.3.4 [gcc-4_3-branch revision 152973]] on linux2 Type "help", "copyright", "credits" or "license" for more informat

我配置了日志记录,但似乎遗漏了一步。在本例中,我使用的是sud,但使用此log方法的任何库日志记录都存在此问题

这很有效

host-03:~ # python2.7
Python 2.7.7 (default, Aug 27 2014, 16:51:46)
[GCC 4.3.4 [gcc-4_3-branch revision 152973]] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import logging
>>> logging.basicConfig()
>>> from suds.client import Client
>>> logging.getLogger('suds.client').setLevel(logging.DEBUG)
>>> client = Client('https://10.10.10.10:8443/path/to/wsdl?wsdl')
>>> user = 'User'
>>> password = 'pass'
>>> client.service.checkAuthentication(user, password)
DEBUG:suds.client:sending to (https://10.10.10.10:8443/path/to/wsdl)
message:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:ns3="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://DefaultNamespace" xmlns:ns2="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
   <SOAP-ENV:Header/>
   <ns2:Body>
      <ns1:checkAuthentication>
         <username xsi:type="ns3:string">User</username>
         <password xsi:type="ns3:string">pass</password>
      </ns1:checkAuthentication>
   </ns2:Body>
</SOAP-ENV:Envelope>
DEBUG:suds.client:headers = {'SOAPAction': '""', 'Content-Type': 'text/xml; charset=utf-8'}
DEBUG:suds.client:HTTP succeeded:
<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><ns1:checkAuthenticationResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://DefaultNamespace"><checkAuthenticationReturn xsi:type="xsd:boolean">true</checkAuthenticationReturn></ns1:checkAuthenticationResponse></soapenv:Body></soapenv:Envelope>
True
>>>
当我直接给他们打电话时,日志记录工作正常

>>> logger.debug('some test message')
2015-01-15 09:10:18.523 <stdin>     DEBUG     MainThread some test message
>>>
host-03:~ # cat /app/logs/app.log
2015-01-15 09:10:18.523 <stdin>     DEBUG     MainThread some test message
>logger.debug('some test message')
2015-01-15 09:10:18.523调试主线程一些测试消息
>>>
host-03:~#cat/app/logs/app.log
2015-01-15 09:10:18.523调试主线程一些测试消息

我的日志配置中缺少了什么导致库找不到我的日志处理程序?

所以我设法解决了这个问题。不明显的是。。。当您使用除basicConfig、file或dict config之外的任何类型的日志配置时,现有的日志记录器将被禁用。如果图书馆使用

logger = logging.getLogger('your app or module')
那就行了,但既然他们都在抢夺

logger = logging.getLogger(__name__)
然后滚动您自己的记录器会使lib没有配置的处理程序。你有两个选择

将lib设置为空处理程序(如上面的文章suds.client)

但是,如果您想查看消息,这不是很有用

或者您可以使用file或dictConfig并指定
disable\u existing\u loggers=False

但我仍然对结果不满意。如果您将默认日志级别设置为debug,您的lib将污染您的输出,但是如果您将默认日志级别设置为warning,这对您自己的日志记录不是很有用。虽然可以独立设置LIB,但这可能有点麻烦

我最后做的是将级别设置为DEBUG,但我添加了一个lib过滤器,它将任何日志记录从库发送到它自己的文件。然后,在运行我的应用程序实例后,我查看了日志,以确定我认为有用的内容,然后降低了那些被认为不必要的警告级别

logging.getLogger('suds.client').setLevel(logging.DEBUG)
logging.getLogger('suds.transport.http').setLevel(logging.WARN)
最后我留下了lib过滤器,因为它对我有一些库的详细跟踪是有用的,但对于我的标准日志来说太多了。我还添加了一些初始化来删除应用程序每个实例之前的日志

下面是一个类似于我现在使用的代码片段

"""some sample log"""
import os
import logging
import logging.config
import logging.handlers
from datetime import datetime

logger = logging.getLogger(__name__)


class CustomFormatter(logging.Formatter):
    """used for colored terminal logging"""
    BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
    colors = dict(
        CRITICAL='\33[1;9%dm' % RED,
        ERROR='\33[9%dm' % RED,
        WARNING='\33[9%dm' % YELLOW,
        INFO='\33[1;9%dm' % GREEN,
        DEBUG='\33[9%dm' % BLUE,
        NOTSET='\33[%dm' % BLACK,  # reset
    )

    def __init__(self, fmt=None, datefmt=None, color=False):
        fmt = fmt if fmt else ('%(asctime)s %(module)-11s %(levelname)-9s '
                               '%(threadName)-10s %(message)s')
        logging.Formatter.__init__(self, fmt, datefmt)
        self.color = color

    def formatTime(self, record, datefmt=None):
        create_time = datetime.fromtimestamp(record.created)
        if datefmt:
            s = create_time.strftime(datefmt)
        else:
            t = create_time.strftime("%Y-%m-%d %H:%M:%S")
            s = "%s.%03d" % (t, record.msecs)
        return s

    def format(self, record):
        s = super(CustomFormatter, self).format(record)
        if self.color:
            s = self.colors[record.levelname] + s + self.colors['NOTSET']
        return s


class LibFilter(logging.Filter):
    """custom filter to send suds logging to a separate file"""
    def filter(self, record):
        if [x for x in '__main__', __name__.split('.', 1)[0]
                if x in record.name]:
            return True
        else:
            create_time = datetime.fromtimestamp(record.created)
            t = create_time.strftime("%Y-%m-%d %H:%M:%S")
            s = "%s.%03d" % (t, record.msecs)
            with open('logs/%s.log' % record.name, 'a') as f:
                f.write(s + '\n')
                f.write(record.getMessage() + '\n\n')
            return False


def setup_logging():
    """use dictConfig to setup logging"""
    log_file = 'logs/app.log'
    doRollover = os.path.isfile(log_file)
    logging.config.dictConfig(
        dict(
            version=1,
            disable_existing_loggers=False,
            filters=dict(libfilter={'()': LibFilter}),
            formatters=dict(
                colorformatter={'()': CustomFormatter, 'color': True},
                fileformatter={'()': CustomFormatter}),
            handlers=dict(
                console={
                    'class': 'logging.StreamHandler',
                    'filters': ['libfilter'],
                    'formatter': 'colorformatter',
                    'level': 'DEBUG'},
                filehandler={
                    'class': 'logging.handlers.RotatingFileHandler',
                    'filename': log_file,
                    'backupCount': 3,
                    'filters': ['libfilter'],
                    'formatter': 'fileformatter',
                    'level': 'DEBUG'}),
            root=dict(level='INFO', handlers=['console', 'filehandler'])
        )
    )
    if doRollover:
        for handler in logging.getLogger('').handlers:
            if getattr(handler, 'doRollover', None):
                handler.doRollover()
还有我的测试应用程序

"""
    test logging configuration
"""
import logging

from mod import log
log.setup_logging()

logger = logging.getLogger(__name__)

logger.debug('debug msg')
logger.info('info msg')
logger.warning('warning msg')
logger.error('error msg')
logger.exception('exception msg')
现在,我的控制台和文件日志与以前一样,对于我所有的lib,每个lib都有一个单独的文件。我没有实现滚动逻辑,但在我的应用程序中,每次运行应用程序时,我都会删除以前的库日志

"""some sample log"""
import os
import logging
import logging.config
import logging.handlers
from datetime import datetime

logger = logging.getLogger(__name__)


class CustomFormatter(logging.Formatter):
    """used for colored terminal logging"""
    BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
    colors = dict(
        CRITICAL='\33[1;9%dm' % RED,
        ERROR='\33[9%dm' % RED,
        WARNING='\33[9%dm' % YELLOW,
        INFO='\33[1;9%dm' % GREEN,
        DEBUG='\33[9%dm' % BLUE,
        NOTSET='\33[%dm' % BLACK,  # reset
    )

    def __init__(self, fmt=None, datefmt=None, color=False):
        fmt = fmt if fmt else ('%(asctime)s %(module)-11s %(levelname)-9s '
                               '%(threadName)-10s %(message)s')
        logging.Formatter.__init__(self, fmt, datefmt)
        self.color = color

    def formatTime(self, record, datefmt=None):
        create_time = datetime.fromtimestamp(record.created)
        if datefmt:
            s = create_time.strftime(datefmt)
        else:
            t = create_time.strftime("%Y-%m-%d %H:%M:%S")
            s = "%s.%03d" % (t, record.msecs)
        return s

    def format(self, record):
        s = super(CustomFormatter, self).format(record)
        if self.color:
            s = self.colors[record.levelname] + s + self.colors['NOTSET']
        return s


class LibFilter(logging.Filter):
    """custom filter to send suds logging to a separate file"""
    def filter(self, record):
        if [x for x in '__main__', __name__.split('.', 1)[0]
                if x in record.name]:
            return True
        else:
            create_time = datetime.fromtimestamp(record.created)
            t = create_time.strftime("%Y-%m-%d %H:%M:%S")
            s = "%s.%03d" % (t, record.msecs)
            with open('logs/%s.log' % record.name, 'a') as f:
                f.write(s + '\n')
                f.write(record.getMessage() + '\n\n')
            return False


def setup_logging():
    """use dictConfig to setup logging"""
    log_file = 'logs/app.log'
    doRollover = os.path.isfile(log_file)
    logging.config.dictConfig(
        dict(
            version=1,
            disable_existing_loggers=False,
            filters=dict(libfilter={'()': LibFilter}),
            formatters=dict(
                colorformatter={'()': CustomFormatter, 'color': True},
                fileformatter={'()': CustomFormatter}),
            handlers=dict(
                console={
                    'class': 'logging.StreamHandler',
                    'filters': ['libfilter'],
                    'formatter': 'colorformatter',
                    'level': 'DEBUG'},
                filehandler={
                    'class': 'logging.handlers.RotatingFileHandler',
                    'filename': log_file,
                    'backupCount': 3,
                    'filters': ['libfilter'],
                    'formatter': 'fileformatter',
                    'level': 'DEBUG'}),
            root=dict(level='INFO', handlers=['console', 'filehandler'])
        )
    )
    if doRollover:
        for handler in logging.getLogger('').handlers:
            if getattr(handler, 'doRollover', None):
                handler.doRollover()
"""
    test logging configuration
"""
import logging

from mod import log
log.setup_logging()

logger = logging.getLogger(__name__)

logger.debug('debug msg')
logger.info('info msg')
logger.warning('warning msg')
logger.error('error msg')
logger.exception('exception msg')