2016-11-15 7 views
1

プログラムの実行中にフォーマットを変更するPythonプログラム用のロガーを作成したいと思います。これは、ロガーに、ログメッセージに加えて現在実行中のプログラムの部分に関する情報を表示させたい場合に必要です。 はこのような何か私は何をしたいです(プログラムの異なる部分 - 前編、第2の部分は、ログインしている必要があります):しかし、私は何を得るロギングフォーマットを動的に調整する

import logging 

#Set up logger 
logfile = str('example.log') 
logger = logging.getLogger('MyProgram') 
logger.setLevel(logging.DEBUG) 
fh = logging.FileHandler(logfile) 
fh.setLevel(logging.INFO) 

ch = logging.StreamHandler() 
ch.setLevel(logging.INFO) 

log_status = 'First Part' 
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - {0} - %(message)s'.format(log_status)) 

fh.setFormatter(formatter) 
ch.setFormatter(formatter) 


logger.addHandler(fh) 
logger.addHandler(ch) 

#First part of the program 
logger.info("One log message") 

#Second part of the program 
log_status = 'Second Part' 

logger.info("Another log message") 

2016-11-15 21:09:07,042 - MyProgram - INFO - First Part - One log message 
2016-11-15 21:09:07,042 - MyProgram - INFO - Second Part - Another log message 

は、私は次のコードを試してみました

2016-11-15 21:09:07,042 - MyProgram - INFO - First Part - One log message 
2016-11-15 21:09:07,042 - MyProgram - INFO - First Part - Another log message 

どうすればこの問題を解決できますか?私のコードの残りの部分にも助言を与えるのをためらってください。

答えて

2

'%(asctime)s - %(name)s - %(levelname)s - {0} - %(message)s'.format(log_status)を呼び出すと、新しい文字列が作成され、Formatterに渡され、log_statusが再び使用されることはないため、ソリューションが機能しません。フォーマット文字列を動的に作成するカスタムFormatterが必要です。

しかし、この問題はPython公式ドキュメントのLogging Cookbook: Adding contextual information to your logging outputで解決されています - カスタムlogging.Filterの例を参照してください。

import logging 
from random import choice 

class ContextFilter(logging.Filter): 
    """ 
    This is a filter which injects contextual information into the log. 

    Rather than use actual contextual information, we just use random 
    data in this demo. 
    """ 

    USERS = ['jim', 'fred', 'sheila'] 
    IPS = ['123.231.231.123', '127.0.0.1', '192.168.0.1'] 

    def filter(self, record): 

     record.ip = choice(ContextFilter.IPS) 
     record.user = choice(ContextFilter.USERS) 
     return True 

if __name__ == '__main__': 
    levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL) 
    logging.basicConfig(level=logging.DEBUG, 
         format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s') 
    a1 = logging.getLogger('a.b.c') 
    a2 = logging.getLogger('d.e.f') 

    f = ContextFilter() 
    a1.addFilter(f) 
    a2.addFilter(f) 
    a1.debug('A debug message') 
    a1.info('An info message with %s', 'some parameters') 
    for x in range(10): 
     lvl = choice(levels) 
     lvlname = logging.getLevelName(lvl) 
     a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters') 

出力:

2010-09-06 22:38:15,292 a.b.c DEBUG IP: 123.231.231.123 User: fred  A debug message 
2010-09-06 22:38:15,300 a.b.c INFO  IP: 192.168.0.1  User: sheila An info message with some parameters 
2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 127.0.0.1  User: sheila A message at CRITICAL level with 2 parameters 
2010-09-06 22:38:15,300 d.e.f ERROR IP: 127.0.0.1  User: jim  A message at ERROR level with 2 parameters 
... 
関連する問題