Python的日志模块没有将任何内容写入文件。

61

我正在尝试编写一个服务器,将异常记录到控制台和文件中。我从菜谱中提取了一些代码。以下是代码:

logger = logging.getLogger('server_logger')
logger.setLevel(logging.DEBUG)
# create file handler which logs even debug messages
fh = logging.FileHandler('server.log')
fh.setLevel(logging.DEBUG)
# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
ch.setFormatter(formatter)
fh.setFormatter(formatter)
# add the handlers to logger
logger.addHandler(ch)
logger.addHandler(fh)

这段代码可以在控制台上完美地记录,但是却无法向文件中写入任何内容。尽管文件已经被创建了,但它始终没有被写入过。我曾尝试关闭处理程序,但是那并没有什么作用。刷新也不起作用。我在互联网上搜索了一下,但显然只有我遇到了这个问题。请问有人知道问题出在哪里吗?感谢你们的回答。

你使用什么命令来记录日志?你只是调用 logging.debug() 吗? - Leopd
我正在使用 logging.error()。 - thePurpleMonkey
没有复现问题。你的代码按预期工作。 - wim
6个回答

48
尝试打电话。
logger.error('This should go to both console and file')

代替

logging.error('this will go to the default logger which you have not changed the config of')

1
哦,嘿!这完全让它工作了!你是个天才!虽然我不完全明白为什么它能工作... - thePurpleMonkey
8
调用logging.error会使用默认的日志记录器,但你尚未配置它。变量logger是你在第一行定义的具有所有已配置属性的记录器。 - Leopd
还是空的,我已经做过了。 - greendino

34

尝试将导入(import)和基本配置(basicConfig)放在脚本的最开始,像这样:

import logging
logging.basicConfig(filename='log.log', level=logging.INFO)
.
.
import ...
import ...

1
谢谢!我知道这不是回答这个问题的答案(OP的问题是使用logging.debug/info/error()而不是logger.debug/info/error()),但这解决了我遇到的一个问题。使用“import h2o”使我下面的logging.basicConfig()调用无效。我猜测h2o模块中的某些内容初始化了logging模块...聪明的决定,由决定这样做的人做出。 - Brent212
也修复了我的问题 - 我试图在单元测试中记录一些内容。它之前可以正常工作,然后我一定是弄坏了什么东西。将配置提升解决了这个问题。 - LogicOnAbstractions
这也解决了我的问题;我正在导入具有自己记录器的gensim。谢谢! - CharlesG
也解决了我的问题! - JoAnn Alvarez
这就是我的日志记录不起作用的原因 - 谢谢! - TCSGrad

13

把这个放置

for handler in logging.root.handlers[:]:
    logging.root.removeHandler(handler)

在前面

logging.basicConfig(...)

相关链接 Logging 模块不写入文件


这太完美了!不需要在其他导入之前初始化日志,并处理其他导入模块中创建的多余处理程序(处理事物的好方法!) - Chris Collett

5

我知道这个问题可能有点过时,但我认为上面的方法有些复杂了。我遇到了类似的问题,我通过以下方式解决:

import logging

logging.basicConfig(format = '%(asctime)s %(message)s',
                    datefmt = '%m/%d/%Y %I:%M:%S %p',
                    filename = 'example.log',
                    level=logging.DEBUG)

这将把所有级别为 debug 或更高的日志写入到 example.log 文件中。
调用 logging.debug("This is a debug message") 将会把 This is a debug message 写入到 example.log 中,但要注意日志级别必须正确设置。

2
我也认为原帖有点过于复杂了,不符合我的需求。我正在尝试让你提供的代码工作,但它没有为我创建任何文件,更不用说在其中写入数据了。 - Mymozaaa
@Mymozaaa - https://docs.python.org/2/howto/logging.html#logging-to-a-file。希望这能帮到你。 - Abass Sesay
@AbassSesay - 谢谢,我没有指定级别,所以它失败了。 - pnv
这种方法甚至没有创建文件,我很困惑。 - greendino

5
为了既能写入终端又能写入文件,您可以像下面这样操作:
import logging.config

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    handlers=[
        logging.FileHandler("log_file.log"),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

在代码中的使用:

logger.info('message')
logger.error('message')

3
如果 root.handlers 不为空,则不会创建日志文件。在调用 basicConfig() 方法之前,我们应该清空 root.handlers。source
代码片段:
for handler in logging.root.handlers[:]:
logging.root.removeHandler(handler)

完整的代码如下:
import logging
##loging
for handler in logging.root.handlers[:]:
    logging.root.removeHandler(handler)

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(message)s',
                    datefmt='%a, %d %b %Y %H:%M:%S',
                    filename= 'log.txt',
                    filemode='w')

console = logging.StreamHandler()
console.setLevel(logging.INFO)
# add the handler to the root logger
logging.getLogger().addHandler(console)
logging.info("\nParameters:")

for i in range(10):
    logging.info(i)

logging.info("end!")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接