2015-01-15 45 views
1

我配置了日志记录,但我似乎错过了一个步骤。在这个例子中,我使用了suds,但是在使用这种日志方法进行日志记录时,我遇到了这个问题。找不到配置日志库的处理程序

这工作

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等),按预期方式工作,不过,从任何日志一个图书馆总是说“找不到处理程序”。

from datetime import datetime 
import logging 
import logging.handlers 
import os 

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 

# get logger 
logger = logging.getLogger(__name__) 
logger.setLevel(logging.DEBUG) 

# configure file handler 
path_to_log = '/app/logs/app.log' 
filehandler = logging.handlers.RotatingFileHandler(path_to_log, backupCount=5) 
filehandler.setLevel(logging.DEBUG) 
filehandler.setFormatter(CustomFormatter()) 
if os.path.isfile(path_to_log): 
    filehandler.doRollover() 

# configure stream handler 
console = logging.StreamHandler() 
console.setLevel(logging.DEBUG) 
console.setFormatter(CustomFormatter(color=True)) 

# add handlers to logger 
logger.addHandler(filehandler) 
logger.addHandler(console) 

# configure client 
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) 


>>> client.service.checkAuthentication(user, password) 
No handlers could be found for logger "suds.client" 
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 

叫他们什么我从导致该库找不到我的日志处理我的日志配置不见了?

回答

0

所以我设法弄清楚了这一点。什么是不明显的...当你使用任何类型的日志配置,除了basicConfig,文件或字典配置,现有的记录器被禁用。如果库使用

logger = logging.getLogger('your app or module') 

然后,它会工作,但由于它们都抓住

logger = logging.getLogger(__name__) 

然后滚动自己留下记录器没有配置的处理程序的lib。你有几个选择。

设置你的lib到空处理器(如上面的帖子,suds.client)

logging.getLogger('suds.client').addHandler(logging.NullHandler()) 

,但如果你想看到的消息

或者你可以使用文件,这不是非常有用或dictConfig并指定disable_existing_loggers=False

但我仍然对结果不满意。如果您将默认日志级别设置为调试,则您的库会污染您的输出,但是如果您将默认设置为警告,那么对于您自己的日志记录来说这不是非常有用。你可以独立设置库,但它可能有点痛苦。

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

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') 

现在我的控制台和文件日志,之前都和我所有的库我得到每一个单独的文件。我没有实现翻转逻辑,但在我的应用程序中,我将每次运行应用程序时删除之前的库日志。

相关问题