0

第一次玩日志模块。我真的有两个问题:

我在创建 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代替loginhandler = logging.FileHandler(log)会给我关于文件甚至没有被创建的错误。我做错了什么没有写入日志文件?是因为我试图对文件名过于聪明吗?

第二个问题可能以某种方式包含第一个问题。我真正想要的是一种同时写入控制台和日志文件的方法,因为这个脚本需要很长时间,我想衡量进度。我已经看到有关于如何做到这一点的答案,例如这里,但所有这些似乎都假设我想要两个不同输出的不同级别的日志记录;我不。顺便说一句,我确实意识到如果我的脚本没有动态生成日志文件的名称,我可以做一些事情python myscript.py | tee log.file来避免制作不同的处理程序。

由于第一个问题涉及的变量,我觉得我无法回答第二个问题,但由于疾病和随后的睡眠不足,我现在很迷茫。如果有人能像五岁的孩子一样向我解释如何以相同的输出同时写入控制台和日志文件,我将不胜感激。

非常感谢。

4

1 回答 1

2

您的代码正在配置一个名为“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__))

然后通过那个loggerself.logger对象做所有事情,而不是通过模块级函数。

那么,为什么还有模块级功能呢?主要是为了方便简单的程序。如果这听起来适合您,并且您想使用它们,您可以;您只需要配置根记录器而不是其他记录器。将第一行更改为:

logger = logging.getLogger()

现在,当您配置时logger,您也在配置模块级功能。

于 2013-02-28T21:55:58.140 回答