【发布时间】:2011-02-28 16:25:38
【问题描述】:
我正在编写 python 包/模块,并希望日志消息提及它们来自什么模块/类/函数。 IE。如果我运行这段代码:
将 mymodule.utils.worker 导入为 worker w = worker.Worker() w.run()我要记录的消息如下所示:
2010-06-07 15:15:29 信息 mymodule.utils.worker.Worker.run我怎样才能做到这一点?
谢谢。
【问题讨论】:
我正在编写 python 包/模块,并希望日志消息提及它们来自什么模块/类/函数。 IE。如果我运行这段代码:
将 mymodule.utils.worker 导入为 worker w = worker.Worker() w.run()我要记录的消息如下所示:
2010-06-07 15:15:29 信息 mymodule.utils.worker.Worker.run我怎样才能做到这一点?
谢谢。
【问题讨论】:
我倾向于在我的包/模块中使用日志记录模块,如下所示:
import logging
log = logging.getLogger(__name__)
log.info("Whatever your info message.")
这会将您的记录器的名称设置为模块的名称,以便包含在日志消息中。您可以通过在格式字符串中找到%(name)s 的位置来控制名称的位置。类似地,您可以使用%(process)d 放置pid,使用%(thread)d 放置线程ID。 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
【讨论】:
__name__,但它只有当前模块的名称,而不是完整的<package>.<subpackage>.<subsubpackage>.<module> 字符串。你知道我怎样才能得到这样的字符串吗?顺便说一句,%(process)d 是很好的提示,谢谢!
__name__ 是导入时的全名,而不仅仅是最后一部分(假设标准导入机制)。一定要试一试。
这是我从这次讨论中得出的解决方案。感谢大家的建议。
用法:
>>> 导入日志 >>> logging.basicConfig(level=logging.DEBUG) >>> 从 hierlogger 导入 hierlogger 作为记录器 >>> 定义主(): ...记录器()。调试(“测试”) ... >>> 主要() 调试:主要:测试默认情况下,它会将记录器命名为...您还可以通过提供参数来控制深度:
3 - module.class.method 默认
2 - 模块.class
1 - 仅模块
Logger 实例也被缓存以防止在每次调用时计算记录器名称。 我希望有人会喜欢它。
代码:
导入日志 进口检验 类 NullHandler(logging.Handler): def 发射(自我,记录):通过 def hierlogger(级别= 3): callerFrame = 检查.stack()[1] 来电者 = callerFrame[0] lname = '__heirlogger'+str(level)+'__' 如果 lname 不在 caller.f_locals 中: 记录器名称 = str() 如果级别 >= 1: 尝试: loggerName += inspect.getmodule(inspect.stack()[1][0]).__name__ 除了:通过 如果 caller.f_locals 中的“自我”和(级别 >= 2): loggerName += ('.' if len(loggerName) > 0 else '') + caller.f_locals['self'].__class__.__name__ 如果 callerFrame[3] != '' 并且级别 >= 3: loggerName += ('.' if len(loggerName) > 0 else '') + callerFrame[3] caller.f_locals[lname] = logging.getLogger(loggerName) caller.f_locals[lname].addHandler(NullHandler()) 返回 caller.f_locals[lname]【讨论】: