Python の logging 、TimedRotatingFileHandler では、日替わりローテーションの場合、
ログファイル名=test.log に対して、
test.log.%Y-%m-%d
がデフォルトのローテーションファイル名である。
これを
test_%Y-%m-%d.log
に変える方法は、、
handler の namer を以下のようにする。
handler.namer = lambda x: re.sub(r"\.([^.]+)\.(\d{4})-(\d{2})-(\d{2})$", r"_\2-\3-\4.\1", x)
でも、handler.extMatch で、ローテーションで削除する時の suffix とマッチするパターンを
変えれば対応できると思ったが、namer を変更した場合、削除対象とマッチするパターンを
うまく表現できなくなってしまう。→ いつまでもログが残ってしまう。
仕方ないので、Logger インスタンス生成時にローテーションで古くなるログファイルを
削除するようにする。
以下を差し込む。
from datetime import datetime, timedelta import os delfile = datetime.strftime((lambda x=datetime.now(): x - timedelta(days=7))(), '/var/log/test_%Y-%m-%d.log') if os.path.exists(delfile): os.remove(delfile)
最終的に logger.py を以下のようにする。
# -*- coding: UTF-8 -*- from logging import Formatter, handlers, StreamHandler, getLogger, DEBUG, WARN, INFO import inspect import re from datetime import datetime, timedelta import os class Logger: def __init__(self, name=__name__): if name=="blue.logger": fsplits = inspect.stack()[1].filename.split('/') name = fsplits[len(fsplits)-1] # ロガー生成 self.logger = getLogger(name) self.logger.setLevel(DEBUG) formatter = Formatter(fmt="%(asctime)s.%(msecs)03d %(levelname)7s %(message)s [%(name)s %(processName)s - %(threadName)s]", datefmt="%Y/%m/%d %H:%M:%S") # 時刻ローテーション handler = handlers.TimedRotatingFileHandler(filename='/var/log/test.log', encoding='UTF-8', when='D', backupCount=7 ) handler.namer = lambda x: re.sub(r"\.([^.]+)\.(\d{4})-(\d{2})-(\d{2})$", r"_\2-\3-\4.\1", x) # old log delete delfile = datetime.strftime((lambda x=datetime.now(): x - timedelta(days=7))(), '/var/log/test_%Y-%m-%d.log') if os.path.exists(delfile): os.remove(delfile) # サイズローテーション ''' handler = handlers.RotatingFileHandler(filename='/var/log/test.log', encoding='UTF-8', maxBytes=1048576, backupCount=3) ''' # ログファイル設定 handler.setLevel(INFO) handler.setFormatter(formatter) self.logger.addHandler(handler) # 標準出力用 設定: DEBUG レベルまで標準出力する sthandler = StreamHandler() sthandler.setLevel(DEBUG) sthandler.setFormatter(formatter) self.logger.addHandler(sthandler) def debug(self, msg): self.logger.debug(msg) def info(self, msg): self.logger.info(msg) def warn(self, msg): self.logger.warning(msg) def error(self, msg, exc_info=False): self.logger.error(msg, exc_info=exc_info) def critical(self, msg): self.logger.critical(msg)
この中の logger.error は、
def error(self, msg, exc_info=False): self.logger.error(msg, exc_info=exc_info)
True 指定でスタックトレースも出るようにしている
import traceback
print(traceback.format_exc(), file=sys.stderr)