我想使用日志记录模块而不是打印调试信息和文档。 目标是使用DEBUG级别在控制台上打印,并使用INFO级别登录到文件。
我阅读了很多关于日志记录模块的文档,食谱和其他教程,但无法弄清楚,我怎么能按照我想要的方式使用它。 (我在python25上)
我希望在日志文件中包含日志的模块名称。
文档说我应该使用logger = logging.getLogger(__name__)
但是如何声明其他模块/包中的类中使用的记录器,因此它们使用与主记录器相同的处理程序?为了识别'父母',我可以使用logger = logging.getLogger(parent.child)
但我在哪里知道谁调用了这个类/方法?`
下面的示例显示了我的问题,如果我运行此选项,输出将只有__main__
登录并忽略Class
中的日志
这是我的主文件:
# main.py
import logging
from module import Class
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# create file handler which logs info messages
fh = logging.FileHandler('foo.log', 'w', 'utf-8')
fh.setLevel(logging.INFO)
# create console handler with a debug log level
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# creating a formatter
formatter = logging.Formatter('- %(name)s - %(levelname)-8s: %(message)s')
# setting handler format
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# add the handlers to the logger
logger.addHandler(fh)
logger.addHandler(ch)
if __name__ == '__main__':
logger.info('Script starts')
logger.info('calling class Class')
c = Class()
logger.info('calling c.do_something()')
c.do_something()
logger.info('calling c.try_something()')
c.try_something()
模块:
# module.py
imnport logging
class Class:
def __init__(self):
self.logger = logging.getLogger(__name__) # What do I have to enter here?
self.logger.info('creating an instance of Class')
self.dict = {'a':'A'}
def do_something(self):
self.logger.debug('doing something')
a = 1 + 1
self.logger.debug('done doing something')
def try_something(self):
try:
logging.debug(self.dict['b'])
except KeyError, e:
logging.exception(e)
控制台输出
- __main__ - INFO : Script starts
- __main__ - INFO : calling class Class
- __main__ - INFO : calling c.do_something()
- __main__ - INFO : calling c.try_something()
No handlers could be found for logger "module"
此外:有没有办法让模块名称在我的日志文件中显示日志,而不像上面那样在每个类中声明一个新的记录器?也像这样我每次想记录东西时都要去self.logger.info()
。我希望在我的整个代码中使用logging.info()
或logger.info()
。
全球记录器或许是正确答案吗?但是,我不会得到日志中出现错误的模块......
我的最后一个问题:这是pythonic吗?或者是否有更好的建议来做正确的事情。
答案 0 :(得分:12)
在您的主模块中,您在module.py中配置了名为'__main__'
的记录器(或者__name__
等同于您的记录器),而您正在使用不同的记录仪。您需要为每个模块配置记录器,或者您可以在主模块中配置根记录器(通过配置logging.getLogger()
),默认情况下将应用于项目中的所有记录器。
我建议使用配置文件来配置记录器。此链接应该让您对良好做法有所了解:http://victorlin.me/posts/2012/08/26/good-logging-practice-in-python
编辑:在格式化程序中使用%(module)将模块名称包含在日志消息中。
答案 1 :(得分:5)
您的处理程序应该有一个全局记录器:
logger= logging.getLogger("myapp")
#configure handlers
然后,在每个模块上:
logger= logging.getLogger("myapp."+__name__)
您是否需要每类记录器取决于您 - 我见过的大多数项目(最多)每个模块有一个记录器。我的建议是,如果你不需要不同类别的不同处理程序,每个模块只需要一个记录器,或者每个项目都需要一个记录器 - 如果项目很小的话。
如果您需要更多日志上下文,请注意您可以使用格式化程序上的%(funcName)s
打印当前函数名称