-
每天轮换日志:使用TimedRotatingFileHandler
-
日志压缩:设置
encoding='bz2'参数。 (请注意,此“技巧”仅适用于 Python2。“bz2”不再被视为 Python3 中的编码。)
-
可选 - 删除最旧的日志文件以保留 X MB 可用空间。
您可以(间接地)使用RotatingFileHandler 来安排它。通过设置
maxBytes参数,日志文件在达到一定大小时会翻转。通过设置backupCount 参数,您可以控制保留多少翻转。这两个参数一起允许您控制日志文件占用的最大空间。您可能也可以将 TimeRotatingFileHandler 子类化以将此行为合并到其中。
只是为了好玩,这里是您可以继承TimeRotatingFileHandler 的方法。当您运行下面的脚本时,它会将日志文件写入/tmp/log_rotate*。
time.sleep 的值较小(例如 0.1),日志文件会很快填满,达到 maxBytes 限制,然后滚动。
对于较大的time.sleep(例如 1.0),日志文件填满缓慢,未达到 maxBytes 限制,但在达到定时间隔(10 秒)时它们仍然会滚动。
以下所有代码均来自logging/handlers.py。我只是以最直接的方式将 TimeRotatingFileHandler 与 RotatingFileHandler 相结合。
import time
import re
import os
import stat
import logging
import logging.handlers as handlers
class SizedTimedRotatingFileHandler(handlers.TimedRotatingFileHandler):
"""
Handler for logging to a set of files, which switches from one file
to the next when the current file reaches a certain size, or at certain
timed intervals
"""
def __init__(self, filename, maxBytes=0, backupCount=0, encoding=None,
delay=0, when='h', interval=1, utc=False):
handlers.TimedRotatingFileHandler.__init__(
self, filename, when, interval, backupCount, encoding, delay, utc)
self.maxBytes = maxBytes
def shouldRollover(self, record):
"""
Determine if rollover should occur.
Basically, see if the supplied record would cause the file to exceed
the size limit we have.
"""
if self.stream is None: # delay was set...
self.stream = self._open()
if self.maxBytes > 0: # are we rolling over?
msg = "%s\n" % self.format(record)
# due to non-posix-compliant Windows feature
self.stream.seek(0, 2)
if self.stream.tell() + len(msg) >= self.maxBytes:
return 1
t = int(time.time())
if t >= self.rolloverAt:
return 1
return 0
def demo_SizedTimedRotatingFileHandler():
log_filename = '/tmp/log_rotate'
logger = logging.getLogger('MyLogger')
logger.setLevel(logging.DEBUG)
handler = SizedTimedRotatingFileHandler(
log_filename, maxBytes=100, backupCount=5,
when='s', interval=10,
# encoding='bz2', # uncomment for bz2 compression
)
logger.addHandler(handler)
for i in range(10000):
time.sleep(0.1)
logger.debug('i=%d' % i)
demo_SizedTimedRotatingFileHandler()