2015-01-15 48 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') 

現在我的控制檯和文件日誌,之前都和我所有的庫我得到每一個單獨的文件。我沒有實現翻轉邏輯,但在我的應用程序中,我將每次運行應用程序時刪除之前的庫日誌。

相關問題