標準で入っている logging パッケージ、気軽に使えてそれなりなのだけど、
どうもスクリプトが死ぬまでファイルハンドラが殺されないような気がする。
以下に個人的に想定外な動作をする簡単な例を挙げる。
(もしかしたらこれが正しい動作かもしれないんだけど・・・詳しい人教えて!)
sample_logging.py
from datetime import datetime as dt
import os, logging
def main():
for i in xrange(1,6):
log = logging.getLogger()
# i番目の繰り返し用のディレクトリ
dir_name = "dir_{0}".format(i)
os.makedirs(dir_name)
# i番目の繰り返し用のディレクトリのためにログファイル(作りたい)
log_file_name = "{0}/lg_index{1}.log".format(dir_name, i)
logging.basicConfig(level = logging.INFO,\
filename = log_file_name,\
format = "[%(name)s: %(levelname)s @ %(asctime)s] %(message)s")
# log
log.info('hoge')
log.info('foo')
log.info(dt.now().strftime('%Y%m%d%H%M%S))
気持ちとしてはdir_1, dir_2, ..., dir_5のそれぞれのディレクトリに
何らかの処理をした時のログを書き出したかったのだけど、これをすると
一番最初にloggingの設定をしたdir_1のログファイル(dir_1/lg_index1.log"に
全部のinfo(この場合level=logging.INFOなため)が書き出される。
(そもそもこの使い方が正しくない/イケてない可能性がある。)
対策1(ファイルハンドラを扱う/余りキレイじゃない?)
これを参考にした(※コピペでパクってきた)
- http://stackoverflow.com/questions/24816456/python-logging-wont-shutdown
sample_logging_new.py
from datetime import datetime as dt
import os, logging
def main():
for i in xrange(1,6):
log = logging.getLogger()
# i番目の繰り返し用のディレクトリ
dir_name = "dir_{0}".format(i)
os.makedirs(dir_name)
# i番目の繰り返し用のディレクトリのためにログファイル(作りたい)
log_file_name = "{0}/lg_index{1}.log".format(dir_name, i)
log.setLevel(logging.INFO)
fh = logging.FileHandler(filename = log_file_name)
formatter = logging.Formatter(
fmt='"[%(name)s: %(levelname)s @ %(asctime)s] %(message)s"',
datefmt='%Y-%m-%d %H:%M:%S')
fh.setFormatter(formatter)
log.addHandler(fh)
# log
log.info('hoge')
log.info('foo')
log.info(dt.now().strftime('%Y%m%d%H%M%S))
# close file handler
log.removeHandler(fh)
del log, fh
対策2(どうせファイルハンドラ使うなら直接書き出す)
@shima__shimaさんが教えてくれた。
- https://twitter.com/taki__taki__/status/602473227412054016
sample_logging_json.py
from datetime import datetime as dt
import os, json
def main():
for i in xrange(1,6):
# i番目の繰り返し用のディレクトリ
info = {} # データを入れる辞書
dir_name = "dir_{0}".format(i)
os.makedirs(dir_name)
# i番目の繰り返し用のディレクトリのためにログファイル(作りたい)
log_file_name = "{0}/lg_index{1}.log".format(dir_name, i)
info['hoge'] = 0
info['foo'] = 0
info['bar'] = dt.now().strftime('%Y%m%d%H%M%S)
# jsonファイル書き出し
with open(log_file_name, 'w') as f:
json.dump(info, f)
情報(パラメータとか時間とか)書き出すだけの用途なら、logging使わなくてもいいと思った。