LoginSignup
5
3

More than 5 years have passed since last update.

Pythonのloggingとjsonへのdump

Posted at

標準で入っている 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使わなくてもいいと思った。

5
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3