日志轮换 - python 和 windows

Posted

技术标签:

【中文标题】日志轮换 - python 和 windows【英文标题】:Log rotation - python and windows 【发布时间】:2016-09-21 00:36:28 【问题描述】:

(我已经搜索过这个问题,但没有找到重复的问题,但很高兴得到证明)。

我需要在一些 Python 代码中轮换日志。代码在 Windows (Server 2008 R2) 上运行。

最初我使用了TimedRotatingFileHandler(来自 Python 的 logging.handlers 包),但这并不像我们需要的那样工作,因为我知道它与多处理有关(subprocess.check_call 用于启动另一个应用程序)。

我查看了 ConcurrentLogHandler ,它看起来可能可以完成这项工作,但我有点担心它自 2013 年以来一直没有更新(尽管最近出现了一些问题)。

更新:open bug(自 2013 年起)表示 ConcurrentLogHandler 不适用于 Python 2.7/Windows。在记录时,代码只是挂起。

是否有我应该使用的最佳实践 Windows 解决方案?

【问题讨论】:

看起来您所指的错误是针对第 3 方包,而不是 Python 中包含的包 我找到了一个正在使用日志服务器来使其工作的人:huyng.com/posts/python-logging-from-multiple-processes 这可能也有用 - plumberjack.blogspot.com/2010/09/… 是的 - ConcurrentLogHandler 有一个错误,但 TimedRotatingFileHandler 似乎也有问题(请参阅bugs.python.org/issue4749 - 非常长的讨论,其中引用了其他问题)。我可能会继续使用队列来管理这个(水管工)。令人沮丧,因为我没有尝试从我的第二个进程中登录。 【参考方案1】:

也许我遗漏了什么,但 Python 的日志记录模块带有 RotatingFileHandler

import logging
import time

from logging.handlers import RotatingFileHandler

#----------------------------------------------------------------------
def create_rotating_log(path):
    """
    Creates a rotating log
    """
    logger = logging.getLogger("Rotating Log")
    logger.setLevel(logging.INFO)

    # add a rotating handler
    handler = RotatingFileHandler(path, maxBytes=20,
                                  backupCount=5)
    logger.addHandler(handler)

    for i in range(10):
        logger.info("This is test log line %s" % i)
        time.sleep(1.5)

#----------------------------------------------------------------------
if __name__ == "__main__":
    log_file = r"c:\path\to\test.log"
    create_rotating_log(log_file)

这对我在 Windows 7 上使用 Python 2.7 很有效。这里有几个更详细的链接:

http://www.blog.pythonlibrary.org/2014/02/11/python-how-to-create-rotating-logs/ https://docs.python.org/2/library/logging.handlers.html#rotatingfilehandler

【讨论】:

是的 - 这(和 TimedRotatingFileHandler,这是我使用的原始 reqt 用于每天滚动日志)工作得非常好,直到您将多个进程混合在一起。类似的问题在 2008 年被记录为一个错误(随后作为非错误关闭)(bugs.python.org/issue4749)。就我而言,我的额外进程并未尝试写入日志,但我们看到了相同的行为。我将更新我的问题以澄清这一点!【参考方案2】:

好的,这就是我最终要做的。

因为就日志记录而言,事情只是多线程的(其他进程不会写入我的日志),我最终手动启动了这个。我对这种方法并不感到兴奋 - 创建一个线程锁定对象,关闭日志记录(logging.shutdown - 也不对此感到兴奋,因为 doco 说在程序退出时调用它......),移动文件并启动再次登录。然后释放锁。

这一切都在一个 try/except 块中,所以如果出现问题,锁就会被释放。

测试表明这可以满足要求。

在这种情况下调用 logging.shutdown 是否会产生一些我不知道的影响?!

【讨论】:

【参考方案3】:

QueueHandler,在原始问题的评论中得到解决,可从 Python 3.2 获得。

https://docs.python.org/ko/3/library/logging.handlers.html#queuehandler https://docs.python.org/3/howto/logging-cookbook.html#logging-to-a-single-file-from-multiple-processes

Python 文档还建议使用SocketHandler 将所有日志发送到专用于文件写入过程的套接字服务器。

https://docs.python.org/3/howto/logging-cookbook.html#network-logging

【讨论】:

以上是关于日志轮换 - python 和 windows的主要内容,如果未能解决你的问题,请参考以下文章

Ruby on Rails 中的多个日志文件和日志轮换

Weblogic 日志轮换未按预期工作

如何将我自己的日志添加到 Amazon Elastic Beanstalk 上的日志轮换/S3 备份?

什么是 Ansible 日志轮换周期?

使用 Flask 和 RotatingFileHandler 进行原子日志文件轮换

启用 Fluentd 日志轮换