如何调试Python日志配置文件错误
我在代码中添加了Python的日志模块,想要摆脱一堆乱七八糟的打印语句,但现在遇到了配置错误,错误信息也不太好理解。
Traceback (most recent call last):
File "HDAudioSync.py", line 19, in <module>
logging.config.fileConfig('../conf/logging.conf')
File "/usr/lib64/python2.6/logging/config.py", line 84, in fileConfig
handlers = _install_handlers(cp, formatters)
File "/usr/lib64/python2.6/logging/config.py", line 162, in _install_handlers
h = klass(*args)
TypeError: __init__() takes at most 5 arguments (21 given)
我的配置文件里没有任何内容给出21个参数。
这是我的配置文件:
[loggers]
keys=root,main, sftp, jobapi
[handlers]
keys=console, logfile, syslog
[formatters]
keys=simple, timestamp
[logger_root]
level=NOTSET
handlers=logfile
[logger_main]
level=DEBUG
handlers=console, logfile, syslog
propagate=1
qualname=main
[logger_sftp]
level=DEBUG
handlers=console, logfile, syslog
propagate=1
qualname=sftp
[logger_jobapi]
level=DEBUG
handlers=console, logfile, syslog
propagate=1
qualname=jobapi
[handler_console]
class=StreamHandler
level=DEBUG
formatter=simple
args=(sys.stdout,)
[handler_logfile]
class=FileHandler
level=DEBUG
formatter=timestamp
args=('../log/audiosync.log')
[handler_syslog]
class=FileHandler
level=WARN
formatter=timestamp
args=('../log/audiosync.sys.log')
[formatter_simple]
format=%(levelname)s - %(message)s
[formatter_timestamp]
format=%(asctime)s - %(name)s -%(levelname)s - %(message)s
这是我在主模块中的日志初始化代码:
import logging
import logging.config
import logging.handlers
logging.config.fileConfig('../conf/logging.conf')
logger = logging.getLogger('main')
我并不是特别想知道我哪里做错了(虽然知道了也不错),我更想要的是一种调试这个问题的方法。
谢谢。
2 个回答
寻找关键词
错误信息的最后两行提到了 handler
这个词(handler = ...
和 _install_handlers
)。这给了你一个起点,可以去查看配置文件中的处理器定义。
到处寻找匹配的值 无处不在
如果一个函数需要5个参数,但你给了它超过4倍的参数,那就说明某些东西没有按照你预期的方式解析。尤其是当你快速查看配置文件时,根本没有看到接近那个数字的东西。
我发现这种不一致的一个主要原因是,当函数期待一个列表、元组或对象时,你却传入了一个字符串。底层代码可能会把这个字符串拆分成字符,然后用这些字符作为参数。
在你的情况下,我能找到的第一个选项是在配置文件的这个部分:
[handler_syslog]
class=FileHandler
level=WARN
formatter=timestamp
args=('../log/audiosync.sys.log')
这里没有单独的21个字符的字符串,但如果你把参数前面的 ../
去掉,就剩下 log/audiosync.sys.log
,这正好是一个21个字符的字符串。
使用调试工具
这就是它们存在的目的。使用 pdb,或者像 PyCharm 或 PyDev 这样的可视化调试工具。这样,你可以逐行查看代码,并检查变量的值。
改变日志级别
一些模块允许你设置它们的日志级别。你可以把它设置为 DEBUG
,这样就能看到开发者记录的所有信息。这可以帮助你跟踪应用程序运行时的流程。我觉得这在 ConfigParser 模块中可能不可用,但在某些情况下是可以的。
如果一切都失败了,就看看源代码
Python 的源代码可以在网上找到。如果你遇到一些半模糊的错误信息,觉得很难理解上下文,你可以下载源代码,手动查看代码。
你可以查看Python的源代码来研究这些问题。大部分库都是用Python写的,读起来相对简单,不需要了解解释器的内部细节。hg.python.org提供了一个方便的网页界面,可以让你浏览代码库。我没找到2.6版本的分支,但在当前版本的第147行有相关的代码。
你会看到args
是通过eval生成的,它从配置文件中每个handler_*
部分的args
键获取值。然后,这个args变量通过展开操作(*)被转换成klass()函数的参数。
在你的配置文件中,有这一行:
args=('../log/audiosync.log')
这是一串20个字符的字符串,它被展开成一个包含单个字符的元组。再加上传给__init__
的self
对象,就形成了错误信息中的21个参数。你缺少一个结尾的逗号,这样才能形成一个只有1个元素的元组:
args=('../log/audiosync.log',)
^-- missing
在handler_syslog
部分也有同样的错误。