在我正在处理的Python应用程序中格式化我的记录器输出时遇到了一些麻烦。目前,我正在一个独立的文件中创建我的记录器,并将其存储在类变量中,如此...
import logging
class Logging():
FORMAT = '[%(levelname)s]: %(asctime)-15s'
logging.basicConfig(format=FORMAT)
logger = logging.getLogger('Mariner')
ch = logging.StreamHandler()
logger.addHandler(ch)
logger.setLevel(logging.INFO)
对于我需要记录功能的所有类,我只需导入我的记录器类:
import Logging from Logging
然后我继续在使用上引用logger类变量,如下所示:
Logging.logger.info("some message")
当记录消息出现在我的控制台中时,它们跨越两行,其中第一行包含格式化输出,第二行包含纯文本消息。例如:
[INFO]: 2017-07-16 19:28:47,888
writing book state to mongo db...
我还尝试过将message属性显式添加到我的格式化字符串中,但这会导致邮件被打印两次:第一行是w /格式化,第二行是没有。
我是Python日志的新手,并且已经看到其他用户确定他们的问题是由多个处理程序附加引起的。但是,我不认为在我的情况下这是正确的,因为我试图一次声明我的记录器并在各个类之间共享相同的实例。如果这确实是问题,我为提出一个重复的问题而道歉,并希望得到一些善意的指导。
* Side注意:我在运行在不同线程上的进程中使用相同的记录器,但是我已经阅读了一些关于python中的日志记录实现的内容,它似乎是线程安全的。
答案 0 :(得分:1)
您实际上正在遇到"多个处理程序附加问题"。您正在使用第一条消息点击某种默认处理程序,然后StreamHandler
打印出实际消息。如果您删除不要将StreamHandler
添加到记录器并将格式字符串更改为'[%(levelname)s]: %(asctime)-15s'
,则应在一行上打印日志。
顺便说一句,我不认为把你的记录员放在课堂上是有帮助的。我认为最好在启动时初始化它,然后让单独的线程按名称引用它(或者返回由getLogger
返回的记录器的包装器方法。也许该名称可以存储在常量中。 / p>
答案 1 :(得分:1)
您不需要添加另一个StreamHandler,因为logging.basicConfig会将StreamHandler添加到根记录器。 https://docs.python.org/2/library/logging.html#logging.basicConfig
将代码更改为以下代码应该有效。
FORMAT = '[%(levelname)s]: %(asctime)-15s %(message)s'
logging.basicConfig(format=FORMAT, level=logging.INFO)
logger = logging.getLogger('Mariner')
logger.info('some message')
应记录一行
[INFO]: 2017-07-16 23:35:49,721 some message