Python 使用日志中的模块名称登录多个类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23386290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
logging in multiple classes with module name in log
提问by uloco
I want to use the logging module instead of printing for debug information and documentation. The goal is to print on the console with DEBUG level and log to a file with INFO level.
我想使用日志记录模块而不是打印调试信息和文档。目标是以 DEBUG 级别在控制台上打印并以 INFO 级别登录到文件。
I read through a lot of documentation, the cookbook and other tutorials on the logging module but couldn't figure out, how I can use it the way I want it. (I'm on python25)
我阅读了大量关于日志记录模块的文档、食谱和其他教程,但不知道如何以我想要的方式使用它。(我在 python25 上)
I want to have the names of the modules in which the logs are written in my logfile.
我想要在我的日志文件中写入日志的模块的名称。
The documentation says I should use logger = logging.getLogger(__name__)
but how do I declare the loggers used in classes in other modules / packages, so they use the same handlers like the main logger? To recognize the 'parent' I can use logger = logging.getLogger(parent.child)
but where do I know, who has called the class/method?`
文档说我应该使用logger = logging.getLogger(__name__)
但我如何声明在其他模块/包中的类中使用的记录器,以便它们使用与主记录器相同的处理程序?要识别我可以使用的“父”,logger = logging.getLogger(parent.child)
但我在哪里知道,谁调用了类/方法?`
The example below shows my problem, if I run this, the output will only have the __main__
logs in and ignore the logs in Class
下面的例子显示了我的问题,如果我运行这个,输出将只有__main__
登录并忽略登录Class
This is my Mainfile:
这是我的主文件:
# 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:
模块:
# 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)
Output in console:
控制台输出:
- __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"
Besides: Is there a way to get the module names were the logs ocurred in my logfile, without declaring a new logger in each class like above? Also like this way I have to go for self.logger.info()
each time I want to log something. I would prefer to use logging.info()
or logger.info()
in my whole code.
此外:有没有办法在我的日志文件中获取模块名称,而不像上面那样在每个类中声明一个新的记录器?也像这样,self.logger.info()
每次我想记录一些东西时,我都必须去。我更愿意在我的整个代码中使用logging.info()
或logger.info()
。
Is a global logger perhaps the right answer for this? But then I won't get the modules where the errors occur in the logs...
全球记录器可能是这个问题的正确答案吗?但是我不会得到日志中发生错误的模块......
And my last question: Is this pythonic? Or is there a better recommendation to do such things right.
我的最后一个问题:这是pythonic吗?或者有更好的建议来正确地做这些事情。
采纳答案by sirfz
In your main module, you're configuring the logger of name '__main__'
(or whatever __name__
equates to in your case) while in module.py you're using a different logger. You either need to configure loggers per module, or you can configure the root logger (by configuring logging.getLogger()
) in your main module which will apply by default to all loggers in your project.
在您的主模块中,您正在配置名称记录器'__main__'
(或任何__name__
等同于您的情况),而在 module.py 中您正在使用不同的记录器。您需要为每个模块配置记录器,或者您可以logging.getLogger()
在主模块中配置根记录器(通过配置),默认情况下它将应用于项目中的所有记录器。
I recommend using configuration files for configuring loggers. This link should give you a good idea of good practices: http://victorlin.me/posts/2012/08/26/good-logging-practice-in-python
我建议使用配置文件来配置记录器。此链接应该让您对良好做法有一个很好的了解:http: //victorlin.me/posts/2012/08/26/good-logging-practice-in-python
EDIT: use %(module) in your formatter to include the module name in the log message.
编辑:在格式化程序中使用 %(module) 在日志消息中包含模块名称。
回答by goncalopp
You should have one global logger with your handlers:
你的处理程序应该有一个全局记录器:
logger= logging.getLogger("myapp")
#configure handlers
Then, on each module:
然后,在每个模块上:
logger= logging.getLogger("myapp."+__name__)
logger= logging.getLogger("myapp."+__name__)
Whether you need per-class loggers is up to you - most projects I've seen have (at most) one logger per module. My advice is, if you don't need different handlers for different classes, stick with one logger per module, or even one logger per project - if the project is small.
您是否需要每类记录器取决于您 - 我见过的大多数项目(最多)每个模块一个记录器。我的建议是,如果您不需要为不同的类使用不同的处理程序,请坚持每个模块一个记录器,甚至每个项目一个记录器 - 如果项目很小。
If you need more context on your logs, note you can print the current function name using %(funcName)s
on the formatter
如果您需要有关日志的更多上下文,请注意您可以使用%(funcName)s
格式化程序打印当前函数名称