私はlogging
モジュールをPython(3.6.0)で使用することを学び、Logging Cookbookの例から始めました。しかし、コードがループ内から実行されると、ログメッセージは複数回繰り返されます。何故ですか?この場合、ロガーを空にする方法はありますか?私はlogger.propagate
で遊んだりしようとしましたが、成功しませんでした。反復の空のlogger
スクリプトtestlog.py
での私のコード:
#!/usr/bin/env python3
import logging
def main():
t = (1,2,1,2,1)
logit('Log is fine here', '_logfile', logname='INFO', level='info')
for i,x in enumerate(t):
if x == 1:
logit('Warn at iter {}'.format(i), '_logfile', logname='INFO', level='info')
def logit(message, logfile, logname='LOG', level='info'):
'''https://docs.python.org/3.6/howto/logging-cookbook.html#logging-to-multiple-destinations'''
logformat = '%(asctime)-30s %(levelname)-8s %(name)s\t%(message)s'
dateformat = '[ %Y-%m-%d %H:%M:%S ]'
# set up logging to file
logging.basicConfig(level=logging.DEBUG,
format=logformat,
datefmt=dateformat,
filename=logfile,
filemode='a')
# define a Handler which writes INFO messages or higher to the sys.stderr
console = logging.StreamHandler()
console.setLevel(logging.DEBUG)
# set a format which is simpler for console use
formatter = logging.Formatter(logformat, datefmt=dateformat)
# tell the handler to use this format
console.setFormatter(formatter)
# add the handler to the root logger
logging.getLogger('').addHandler(console)
# Now, we can log to the logger
logger = logging.getLogger(logname)
console.propagate = False
if level.lower() == 'debug':
logger.debug(message)
elif level.lower() == 'info':
logger.info(message)
elif level.lower().startswith('warn'):
logger.warning(message)
else:
logger.error(message)
if __name__ == '__main__':
main()
出力:
> ./testlog.py
[ 2017-03-04 01:59:09 ] INFO INFO Log is fine here
[ 2017-03-04 01:59:09 ] INFO INFO Warn at iter 0
[ 2017-03-04 01:59:09 ] INFO INFO Warn at iter 0
[ 2017-03-04 01:59:09 ] INFO INFO Warn at iter 2
[ 2017-03-04 01:59:09 ] INFO INFO Warn at iter 2
[ 2017-03-04 01:59:09 ] INFO INFO Warn at iter 2
[ 2017-03-04 01:59:09 ] INFO INFO Warn at iter 4
[ 2017-03-04 01:59:09 ] INFO INFO Warn at iter 4
[ 2017-03-04 01:59:09 ] INFO INFO Warn at iter 4
[ 2017-03-04 01:59:09 ] INFO INFO Warn at iter 4
EDIT1:アイデアは、コンソールの両方に、ログファイルにログインすることです。 ログファイルでは、メッセージは繰り返されません。
[ 2017-03-04 01:59:09 ] INFO INFO Log is fine here
[ 2017-03-04 01:59:09 ] INFO INFO Warn at iter 0
[ 2017-03-04 01:59:09 ] INFO INFO Warn at iter 2
[ 2017-03-04 01:59:09 ] INFO INFO Warn at iter 4
私は知っていますが、新しいハンドラ(この場合はコンソール)をルートロガーに追加するにはどうすればよいでしょうか。明らかに、logging.basicConfig()でファイル名とハンドラを一緒に設定することはできません。 – PedroA
一般的に、ロガーを一度セットアップします。 'setup_logging'という別のメソッドを作ることができます。このメソッドは、ファイルをパラメータとして受け取り、ロガーを返します。次に、 'logit'メソッドはメッセージ、ロガー、レベルを取ります。あなたの 'main'メソッドは' logger = setup_logging( 'my_log.log') 'を持ち、' logit'へのあなたの呼び出しは 'logit(logger、 'my message'、 'info')'のようになります。しかし、あなたはおそらくあなたの 'logit'メソッドを必要とせず、単に' logger.info( '私のメッセージ') 'を直接呼び出すことができます。' – Stacktrace
具体的な例はありますか? – PedroA