LoginSignup
3
1

More than 5 years have passed since last update.

Python2.6でTimedRotatingFileHandlerのログローテートが効かない問題への対処

Posted at

TimedRotatingFileHandlerのログローテーション

RHEL6やCentOS6で標準のPythonのバージョンは2.6なのでPython2.6を使うことがあるのですが、2.7以降では見られない挙動がありました。

hoge.py
from logging import getLogger
from logging.handlers import TimedRotatingFileHandler

logger = getLogger(__name__)

handler = TimedRotatingFileHandler("hoge.log",'S')

logger.addHandler(handler)
logger.error("test")

上記のようなファイルを作って実行すると、Python2.7以降(3系含む)ならログローテートされてhoge.log.2018-01-31_02-04-27といったファイルが作られるかと思います。
しかし、Python2.6だとログローテートされずにhoge.logに追記され続けてしまいます。

ログローテートされない原因

原因を探ろうと公式サイトからソースコードを取ってみたら、TimedRotatingFileHandlerクラスのコンストラクタで設定されるrolloverAtの値に違いが有りました。

Python-2.6.9/Lib/logging/handlers.py
class TimedRotatingFileHandler(BaseRotatingHandler):
    def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=0, utc=0):
# 略
        self.rolloverAt = self.computeRollover(int(time.time()))
Python-2.7/Lib/logging/handlers.py
class TimedRotatingFileHandler(BaseRotatingHandler):
    def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=0, utc=0):
# 略
        if os.path.exists(filename):
            t = os.stat(filename)[ST_MTIME]
        else:
            t = int(time.time())
        self.rolloverAt = self.computeRollover(t)

computeRolloverは次にログローテートが必要な時刻を計算するメソッドです。
計算は引数の時刻にもとづいて行われます。
when="S",interval=5"ならtの5秒後、when="D",interval=5"ならtの5日後、when="MIDNIGHT"ならtの次の00:00、というように動作します。

2.6ではtの値がスクリプトを実行された時刻となるため、ログローテートする時間に達することがなかったということになります。
つまり、下記のようにsleepを入れるとログローテートしてくれそうです。

hoge_sleep.py
from logging import getLogger
from logging.handlers import TimedRotatingFileHandler
from time import sleep

logger = getLogger(__name__)

handler = TimedRotatingFileHandler("hoge.log",'S')

logger.addHandler(handler)
sleep(2)
logger.error("test")

解決策

1日毎にログローテートするために24時間sleepを入れるのは現実的ではないので、Python2.7のコードを移植したいと思います。
クラスを作らなくても直接書いても良い気もします。

hoge26.py
from logging import getLogger
from logging.handlers import TimedRotatingFileHandler
from time import sleep
from stat import ST_MTIME
import os

class TimedRotatingFileHandler26(TimedRotatingFileHandler):
    def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=0, utc=0):
        super().__init__(filename, when, interval, backupCount, encoding, delay, utc)
        if os.path.exists(filename):
            t = os.stat(filename)[ST_MTIME]
            self.rolloverAt = self.computeRollover(t)

logger = getLogger(__name__)

handler = TimedRotatingFileHandler26("hoge.log",'S')

logger.addHandler(handler)
logger.error("test")

これでPython2.6でもログローテートするようになるかと思います。

3
1
0

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
3
1