python3のloggingモジュールを使ってサイズ・時間別にログローテートする
概要
最近 Python3 のログ出力部分を書いていて、ログローテートに関連した日本語のエントリが少なかったので備忘録的に残しておく。
それと実際にログをプログラム中に仕込むときに --debug
オプションをつけてより詳細なログが出せるようにもしたのでメモしておく。
ファイルサイズベース・時間ベースのログローテート
ファイルサイズベースのときは RotatingFileHandler
、時間ベースのときは TimedRotatingFileHandler
を使用する。
import logging
import logging.handlers
import time
LOG_FILE = "/tmp/app.log"
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# サイズベースのローテーション
handler = logging.handlers.RotatingFileHandler(
LOG_FILE,
maxBytes=100,
backupCount=9
)
# 時間ベースのローテーション
# handler = logging.handlers.TimedRotatingFileHandler(
# LOG_FILE,
# when='S',
# interval=1,
# backupCount=10
# )
handler.suffix = '%Y%m%d%H%M%S'
logger.addHandler(handler)
while True:
logger.critical('critical')
logger.error('error')
logger.warning('warning')
logger.info('info')
logger.debug('debug')
time.sleep(2.5)
出力例
# サイズベース
$ python make_logs.py
$ ls -l /tmp/
total 24
-rw-r--r-- 1 root root 34 Aug 15 14:51 app.log
-rw-r--r-- 1 root root 93 Aug 15 14:51 app.log.1
-rw-r--r-- 1 root root 96 Aug 15 14:51 app.log.2
...
# 時間ベース
$ python make_logs.py
$ ls -l /tmp/
total 24
-rw-r--r-- 1 root root 34 Aug 15 15:01 app.log
-rw-r--r-- 1 root root 34 Aug 15 15:01 app.log.20200815150108
-rw-r--r-- 1 root root 34 Aug 15 15:01 app.log.20200815150110
...
オプション引数で DEBUG レベルのログまで出力する
普段は DEBUG レベルのログまで出しているとリソースがもったいないので、通常は INFO レベルまでのログを出力し --debug
引数があるときに debug レベルまでログを表示するときはこんな感じに書いた。
import argparse
import logging
import logging.handlers
LOG_FILE = "/tmp/app.log"
parser = argparse.ArgumentParser()
parser.add_argument('--debug', help='optional', action='store_true')
args = parser.parse_args()
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
formatter = logging.Formatter(
'%(asctime)s [%(filename)s:%(lineno)d] %(levelname)-8s %(message)s'
)
handler = logging.FileHandler(LOG_FILE)
handler.setFormatter(formatter)
logger.addHandler(handler)
if (args.debug):
logger.setLevel(logging.DEBUG)
logger.critical('critical')
logger.error('error')
logger.warning('warning')
logger.info('info')
logger.debug('debug')
logger.setLevel(logging.INFO)
で INFO ログまで出すようにし、argparser によって --debug
オプション受け取った際に logger.setLevel(logging.DEBUG)
でログレベルを再設定する。
出力例
$ python make_logs.py
$ cat /tmp/app.log
2020-08-15 14:30:47,526 [make_logs.py:23] CRITICAL critical
2020-08-15 14:30:47,526 [make_logs.py:24] ERROR error
2020-08-15 14:30:47,526 [make_logs.py:25] WARNING warning
2020-08-15 14:30:47,526 [make_logs.py:26] INFO info
$ python make_logs.py --debug
$ cat /tmp/app.log
2020-08-15 14:31:29,198 [make_logs.py:23] CRITICAL critical
2020-08-15 14:31:29,198 [make_logs.py:24] ERROR error
2020-08-15 14:31:29,198 [make_logs.py:25] WARNING warning
2020-08-15 14:31:29,198 [make_logs.py:26] INFO info
2020-08-15 14:31:29,198 [make_logs.py:27] DEBUG debug
参考
これ書いてて思ったけど参考にあるPython のロギングを覚えたでやっている Logger 名を引数で受けて Logger オブジェクトを返す関数、すごく便利そうだし他の箇所でも再利用できそう。 次回またログ出力部分を実装するときはメソッドかクラスで定義すると良さそうに思った。
おしまい(¦3[___]