我正在编写python包/模块,并希望日志消息提到它们来自哪个模块/类/函数。即如果我运行此代码:
import mymodule.utils.worker as worker w = worker.Worker() w.run()
我想记录消息如下:
2010-06-07 15:15:29 INFO mymodule.utils.worker.Worker.run <pid/threadid>: Hello from worker
我该如何做到这一点?
感谢。
答案 0 :(得分:8)
我倾向于在我的包/模块中使用日志记录模块,如下所示:
import logging
log = logging.getLogger(__name__)
log.info("Whatever your info message.")
这会将记录器的名称设置为模块的名称以包含在日志消息中。您可以在格式字符串中找到%(name)s
的位置,控制名称的位置。同样,您可以将pid放置%(process)d
,将线程ID放置%(thread)d
。所有选项均为See the docs。
格式化示例:
import logging
logging.basicConfig(format="%(asctime)s %(levelname)s %(name)s %(process)d/%(threadName)s: %(message)s")
logging.getLogger('this.is.the.module').warning('Testing for SO')
给我:
2010-06-07 08:43:10,494 WARNING this.is.the.module 14980/MainThread: Testing for SO
答案 1 :(得分:2)
以下是我在讨论中提出的解决方案。感谢大家的建议。
用法:
>>> import logging >>> logging.basicConfig(level=logging.DEBUG) >>> from hierlogger import hierlogger as logger >>> def main(): ... logger().debug("test") ... >>> main() DEBUG:main:test
默认情况下,它会将记录器命名为...您还可以通过提供参数来控制深度:
3 - module.class.method默认
2 - module.class
1 - 仅模块
还会缓存记录器实例,以防止在每次调用时计算记录器名称。 我希望有人会喜欢它。
代码:
import logging import inspect class NullHandler(logging.Handler): def emit(self, record): pass def hierlogger(level=3): callerFrame = inspect.stack()[1] caller = callerFrame[0] lname = '__heirlogger'+str(level)+'__' if lname not in caller.f_locals: loggerName = str() if level >= 1: try: loggerName += inspect.getmodule(inspect.stack()[1][0]).__name__ except: pass if 'self' in caller.f_locals and (level >= 2): loggerName += ('.' if len(loggerName) > 0 else '') + caller.f_locals['self'].__class__.__name__ if callerFrame[3] != '' and level >= 3: loggerName += ('.' if len(loggerName) > 0 else '') + callerFrame[3] caller.f_locals[lname] = logging.getLogger(loggerName) caller.f_locals[lname].addHandler(NullHandler()) return caller.f_locals[lname]