禁用根日志输出

14 投票
3 回答
20282 浏览
提问于 2025-04-18 13:21

我在一个叫做 'logger.py' 的文件里写了以下代码

import logging

format = '%(asctime)s - %(name)-30s - %(levelname)-8s - %(message)s'
logging.basicConfig(level=logging.DEBUG,
                    format=format)

formatter = logging.Formatter(format)

fh = logging.FileHandler('test.log')
fh.setFormatter(formatter)
fh.setLevel(logging.DEBUG)

ch = logging.StreamHandler()
ch.setFormatter(formatter)
ch.setLevel(logging.INFO)

logging.getLogger().addHandler(fh)
logging.getLogger().addHandler(ch)

然后在另一个文件里

import logging
import logger

logger = logging.getLogger(__name__)
logger.info('Staring Scheduler')

我在控制台上看到的输出是这样的

2014-07-14 22:27:10,915 - __main__                       - INFO     - Staring Scheduler
2014-07-14 22:27:10,915 - __main__                       - INFO     - Staring Scheduler

我无法关闭重复的输出。我想用额外的流处理器来定制打印到控制台的日志级别。将来我还想用 RotatingFileHandler 来替代简单的文件处理器。

有没有人知道怎么做到这一点,同时保持第二个文件里的简单日志设置?我搜索过,但似乎没有找到合适的解决方案。

更新 1(已解决)

文件 logger.py

import logging

logging.getLogger().setLevel(logging.DEBUG)

formatter = logging.Formatter('%(asctime)s - %(name)-30s - %(levelname)-8s - %(message)s')

fh = logging.FileHandler('test.log')
fh.setFormatter(formatter)
fh.setLevel(logging.DEBUG)

ch = logging.StreamHandler()
ch.setFormatter(formatter)
ch.setLevel(logging.ERROR)

logging.getLogger().addHandler(fh)
logging.getLogger().addHandler(ch)

文件 test.py

import logging
import logger

logger = logging.getLogger(__name__)
logger.debug('Debug message')
logger.info('Info message')
logger.warning('Warning message')
logger.error('Error message')
logger.critical('Critical message')

控制台输出:

2014-07-15 09:47:58,171 - __main__                       - ERROR    - Error message
2014-07-15 09:47:58,171 - __main__                       - CRITICAL - Critical message

Test.log 的内容:

2014-07-15 09:47:58,171 - __main__                       - DEBUG    - Debug message
2014-07-15 09:47:58,171 - __main__                       - INFO     - Info message
2014-07-15 09:47:58,171 - __main__                       - WARNING  - Warning message
2014-07-15 09:47:58,171 - __main__                       - ERROR    - Error message
2014-07-15 09:47:58,171 - __main__                       - CRITICAL - Critical message

3 个回答

1

所以你可以先去掉你已经添加了一个 StreamHandler 的基本配置,这样你实际上就有了两个 StreamHandler:

logging.getLogger().addHandler(fh)
logging.getLogger().addHandler(ch)
print logging.getLogger().handlers

[<logging.StreamHandler object at 0x7f3f57c4d050>, <logging.FileHandler object at 0x7f3f57c091d0>, <logging.StreamHandler object at 0x7f3f57c09250>]

接下来,你需要自己做一些基本配置之前为你做的事情:

logging.getLogger().setLevel(logging.INFO)
2

你正在调用 logging.basicConfig(),这个函数默认会使用一个 StreamHandler。不过,你应该手动设置日志的级别。

>>> import logging

>>> format = '%(asctime)s - %(name)-30s - %(levelname)-8s - %(message)s'
>>> formatter = logging.Formatter(format)
>>> fh = logging.FileHandler('test.log')
>>> fh.setFormatter(formatter)
>>> fh.setLevel(logging.DEBUG)
>>> ch = logging.StreamHandler()
>>> ch.setFormatter(formatter)
>>> ch.setLevel(logging.INFO)
>>> logging.getLogger().addHandler(fh)
>>> logging.getLogger().addHandler(ch)
>>> l = logging.getLogger(__name__)
>>> l.setLevel(logging.INFO)
>>> l.info("HI")
2014-07-15 08:46:50,000 - __main__                       - INFO     - HI

文件的内容是:

msvalkon@lunkwill:~$ cat test.log
2014-07-15 08:46:50,000 - __main__                       - INFO     - HI

另外,你在覆盖你的 logger。在你的 另一个文件 中:

import logging
import logger # <-- importing logger.py

logger = logging.getLogger(__name__) # <-- overwriting the logger name, nothing from logger.py is now availabe
logger.info('Staring Scheduler') # This is just a logging object

在这个情况下,你的日志配置已经完成,因为导入会遍历你的代码。但在其他情况下可能并不成立。你可以通过更改变量名或者完全更改配置方式来解决这个问题。

14

你看到输出重复的原因是因为在你的第一个文件logger.py中设置了两个 StreamHandler。

一个是在这一行明确设置的:

ch = logging.StreamHandler()

另一个是在这一行:

logging.basicConfig(level=logging.DEBUG,

根据logging.basicConfig的文档:

这个方法会为日志系统做基本配置,创建一个带默认格式的StreamHandler,并将其添加到根日志记录器。

所以你应该删除basicConfig那一行。

不过,删除之后你需要把根日志记录器的级别设置为DEBUG,因为你在basicConfig那一行做了这个设置:

logging.getLogger().setLevel(logging.DEBUG)

撰写回答