Python中的日志记录链

6 投票
2 回答
3879 浏览
提问于 2025-04-15 23:39

我正在写一个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

我该怎么做才能实现这个呢?

谢谢。

2 个回答

2

这是我在讨论中得出的解决方案。感谢大家的建议。

使用方法:

>>> import logging
>>> logging.basicConfig(level=logging.DEBUG)
>>> from hierlogger import hierlogger as logger
>>> def main():
...     logger().debug("test")
...
>>> main()
DEBUG:main:test

默认情况下,它会将记录器命名为... 你也可以通过提供参数来控制深度:
3 - 模块.类.方法(默认)
2 - 模块.类
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]
8

我通常在我的包或模块中这样使用日志记录模块:

import logging
log = logging.getLogger(__name__)
log.info("Whatever your info message.")

这样做会把你的日志记录器的名字设置为模块的名字,这样在日志信息中就能看到。你可以通过在格式字符串中放置 %(name)s 来控制名字的位置。同样,你可以用 %(process)d 来放置进程ID,用 %(thread)d 来放置线程ID。想了解更多选项,可以查看文档

格式化示例:

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

撰写回答