0

以下代码会产生一些意外行为logging.handlers.TimedRotatingFileHandler

logger1 = logging.getLogger("One")
logger2 = logging.getLogger("Two")

handler1 = TimedRotatingFileHandler(
    "service.log",
    when="M",
    backupCount=2,
    utc=True
)
handler2 = TimedRotatingFileHandler(
    "service.log",
    when="M",
    backupCount=2,
    utc=True
)

formatter = logging.Formatter("%(asctime)s - %(name)s - %(message)s")

handler1.setFormatter(formatter)
handler2.setFormatter(formatter)

logger1.addHandler(handler1)
logger2.addHandler(handler2)

while True:
    sleep(0.5)
    logger1.error("ONE")
    logger2.error("TWO")

我让它运行几分钟,第一次运行结束时一切正常。我知道存在某种非一的行为,即文件不会在预期的那一刻翻转,但我对此表示满意:

-rw-rw-r-- 1 dave dave 3.8K Sep 24 16:11 service.log
-rw-rw-r-- 1 dave dave 3.8K Sep 24 16:11 service.log.2019-09-24_09-09
-rw-rw-r-- 1 dave dave 4.3K Sep 24 16:10 service.log.2019-09-24_09-08

但是,如果我在不删除现有 service.log* 文件的情况下再次在同一目录中启动脚本之前等待几分钟,现在logger1开始按预期写入service.log.2019-09-24_09-11logger2写入。注意nextservice.log的最后修改时间。16:17service.log.2019-09-24_09-11

-rw-rw-r-- 1 dave dave  540 Sep 24 16:17 service.log
-rw-rw-r-- 1 dave dave  540 Sep 24 16:17 service.log.2019-09-24_09-11
-rw-rw-r-- 1 dave dave 3.8K Sep 24 16:11 service.log.2019-09-24_09-09

这对我来说似乎是一个错误,因为logger1从几分钟前开始通过不同的调用继续写入文件logger.error- 这不仅仅是重新启动脚本时的第一个条目。

dave:~$ cat service.log.2019-09-24_09-11

2019-09-24 16:16:55,390 - One - ONE
2019-09-24 16:16:55,892 - One - ONE
2019-09-24 16:16:56,393 - One - ONE
2019-09-24 16:16:56,894 - One - ONE
2019-09-24 16:16:57,395 - One - ONE
2019-09-24 16:16:57,896 - One - ONE
2019-09-24 16:16:58,397 - One - ONE
2019-09-24 16:16:58,898 - One - ONE
...

我正在使用 Python 3.7.4。


编辑:可以在不停止和启动脚本的情况下重现警报行为,只要几分钟没有写入日志即可。

sleep(180)如果我们更换,观察日志文件的状态(每个都被清除到 36 字节大小!)

while True:
    sleep(0.5)
    logger1.error("ONE")
    logger2.error("TWO")

...和...

for _ in range(60):
    sleep(1)
    logger1.error("ONE")
    logger2.error("TWO")

sleep(180)  # blocking, no logs written but log files are in eroded state

for _ in range(60):
    sleep(1)
    logger1.error("ONE")
    logger2.error("TWO")
4

1 回答 1

0

基本上,错误的根源在于有多个 TimedRotatingFileHandlers 实例。我猜翻滚不能很好地处理这种不寻常的情况。似乎在几乎所有情况下都可以避免这种情况,因为我们可以在两个处理程序上设置相同的格式化程序对象,并将相同的处理程序实例添加到多个记录器对象。

于 2019-09-24T12:31:26.423 回答