FileHandler未向我想要的任何位置发送输出
这是我第一次玩日志模块。我有两个问题:
我找到的所有关于创建文件处理器的例子都用的是一个假文件名,但我想让我的日志文件有一个特定的标题格式。
log = time.strftime('./logs/'+'%H:%M:%S %d %b %Y', time.localtime())+'.log'
logger = logging.getLogger('myproject')
formatter = logging.Formatter('%(asctime)s %(message)s', '%H:%M:%S %d %b %Y')
handler = logging.FileHandler(log)
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
一开始这看起来是有效的,因为日志文件确实被创建了,但当我结束脚本并检查它时,里面什么都没有。在你建议我使用 with open(log) as f:
之前,使用 f
替代 log
在 handler = logging.FileHandler(log)
中会给我错误,提示文件根本没有被创建。我到底做错了什么,导致日志文件没有写入?是因为我在文件名上想得太复杂了吗?
第二个问题可能和第一个有点关系。我真正想要的是能够同时写入控制台和日志文件,因为这个脚本运行时间很长,我想了解进度。我看到有一些关于如何做到这一点的答案,比如这里,但这些似乎都假设我想为两个不同的输出设置不同的日志级别;其实我并不想。顺便说一下,我确实意识到如果我的脚本没有动态生成日志文件的名字,我可以用 python myscript.py | tee log.file
来避免创建不同的处理器。
我觉得我在回答第二个问题时遇到困难,是因为第一个问题涉及的变量,但现在我因为生病和缺乏睡眠而感到迷糊。如果有人能像对五岁小孩一样解释给我听,如何将相同的输出写入控制台和日志文件,我将非常感激。
非常感谢。
1 个回答
你的代码正在设置一个名为 'myproject' 的日志记录器:
logger = logging.getLogger('myproject')
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
如果你在这个日志记录器上使用方法,所有功能都会正常工作:
logger.info('foo bar')
logging.getLogger('myproject').info('foo bar')
但是如果你只是使用模块级别的函数,那就不行:
logging.info('foo bar')
为什么呢?因为模块级别的函数使用的是默认的根日志记录器,而不是你配置的那个。想了解更多,可以查看文档。
通常,你可以通过为每个模块创建一个模块级别的 logger
对象来解决这个问题,像这样:
logger = logging.getLogger(__name__)
…或者创建一个类或实例属性 logger
,像这样:
self.logger = logging.getLogger('{}.{}'.format(__name__, cls.__name__))
然后通过这个 logger
或 self.logger
对象来完成所有操作,而不是通过模块级别的函数。
那么,模块级别的函数为什么还存在呢?主要是为了方便在简单程序中使用。如果这对你来说合适,并且你想使用它们,可以这样做;你只需要配置根日志记录器,而不是其他的。把第一行改成这样:
logger = logging.getLogger()
现在当你配置 logger
时,你也在配置模块级别的函数。