Python 多文件日志记录

6 投票
1 回答
8250 浏览
提问于 2025-04-15 17:49

我看过日志模块的文档,虽然可能有些明显的地方我没注意到,但我写的代码似乎没有按预期工作。我使用的是Python 2.6.4。

我的程序由几个不同的Python文件组成,我想把日志信息发送到一个文本文件里,可能还想显示在屏幕上。我想这应该是个常见的需求,所以我可能在某个地方搞错了。

现在我的代码在文本文件里记录日志是对的,算是有点效果。但在屏幕上的输出却出现了重复,一部分是按照我指定的格式,另一部分则没有。而且,当我关闭屏幕输出时,文本仍然会打印一次,这我不想要——我只希望它记录到文件里。

总之,这里有一些代码:

#logger.py
import logging
from logging.handlers import RotatingFileHandler
import os

def setup_logging(logdir=None, scrnlog=True, txtlog=True, loglevel=logging.DEBUG):        
    logdir = os.path.abspath(logdir)

    if not os.path.exists(logdir):
        os.mkdir(logdir)

    log = logging.getLogger('stumbler')
    log.setLevel(loglevel)

    log_formatter = logging.Formatter("%(asctime)s - %(levelname)s :: %(message)s")

    if txtlog:
        txt_handler = RotatingFileHandler(os.path.join(logdir, "Stumbler.log"), backupCount=5)
        txt_handler.doRollover()
        txt_handler.setFormatter(log_formatter)
        log.addHandler(txt_handler)
        log.info("Logger initialised.")

    if scrnlog:
        console_handler = logging.StreamHandler()
        console_handler.setFormatter(log_formatter)
        log.addHandler(console_handler)

这里没有什么特别的。

#core.py
import logging
corelog = logging.getLogger('stumbler.core')  # From what I understand of the docs, this should work :/

class Stumbler:
    [...]

    corelog.debug("Messages and rainbows...")

屏幕输出显示了重复的情况:

2010-01-08 22:57:07,587 - DEBUG :: SCANZIP: Checking zip contents, file: testscandir/testdir1/music.mp3
DEBUG:stumbler.core:SCANZIP: Checking zip contents, file: testscandir/testdir1/music.mp3
2010-01-08 22:57:07,587 - DEBUG :: SCANZIP: Checking zip contents, file: testscandir/testdir2/subdir/executable.exe
DEBUG:stumbler.core:SCANZIP: Checking zip contents, file: testscandir/testdir2/subdir/executable.exe

虽然文本文件得到了正确格式的输出,但在logger.py里关闭屏幕日志输出后,错误格式的输出仍然会显示。

根据我对文档的理解,调用corelog.debug()时,因为corelog是“stumbler”日志记录器的子类,它应该使用那个格式并按此输出日志。

抱歉对这样一个小问题写了这么多。

总结一下:我该如何从多个文件进行日志记录?

1 个回答

12

你确定在你引入的任何东西中没有其他的日志设置吗?

你在控制台看到的错误输出看起来像是一个日志记录器的默认配置,所以可能有其他地方在设置这个。

运行这个简单的测试脚本:

import logging
from logging.handlers import RotatingFileHandler
import os

def setup_logging(logdir=None, scrnlog=True, txtlog=True, loglevel=logging.DEBUG):
    logdir = os.path.abspath(logdir)

    if not os.path.exists(logdir):
        os.mkdir(logdir)

    log = logging.getLogger('stumbler')
    log.setLevel(loglevel)

    log_formatter = logging.Formatter("%(asctime)s - %(levelname)s :: %(message)s")

    if txtlog:
        txt_handler = RotatingFileHandler(os.path.join(logdir, "Stumbler.log"), backupCount=5)
        txt_handler.doRollover()
        txt_handler.setFormatter(log_formatter)
        log.addHandler(txt_handler)
        log.info("Logger initialised.")

    if scrnlog:
        console_handler = logging.StreamHandler()
        console_handler.setFormatter(log_formatter)
        log.addHandler(console_handler)



setup_logging('/tmp/logs')
corelog = logging.getLogger('stumbler.core')
corelog.debug("Messages and rainbows...")

会得到这样的结果:

2010-01-08 15:39:25,335 - DEBUG :: 消息和彩虹...

而在我的 /tmp/logs/Stumbler.log 文件中:

2010-01-08 15:39:25,335 - INFO :: 日志记录器已初始化。2010-01-08 15:39:25,335 - DEBUG :: 消息和 彩虹...

在我运行这个脚本时,它在 python 2.4、2.5 和 2.6.4 中的表现都很正常。

撰写回答