配置第三方脚本的日志记录

gue*_*tli 17 python logging

我有一个第三方python控制台脚本,我不想修改该源代码.

但我想配置由脚本及其库完成的日志记录.该脚本使用标准的python日志记录,但不支持它的配置.

该脚本使用此模式:

import logging
logger=logging.getLogger(__name__)
Run Code Online (Sandbox Code Playgroud)

用例:

  • 我想要忽略文件foo.py的INFO消息.
  • 我想在记录消息中包含PID.

如果我不想修改控制台脚本的来源,我该如何配置日志记录?

该脚本通过调用cron.

如果此脚本如何配置日志记录?

重要

这个答案中创建一个包装器脚本对我来说不是一个解决方案.

linux进程层次结构如下所示:

Cron -> third_party_script
Run Code Online (Sandbox Code Playgroud)

在cron和third_party_script.之间应该有任何"胶水","包装"或"脏黑客"脚本.

为什么突兀/ netpicking?

我想练习"关注点分离".我希望能够在一个地方配置一次记录.这个配置应该被virtualenv的所有python代码使用.编写包装器将是一种解决方法.我想要一个解决方案.

Vin*_*jip 7

库不应该配置日志记录 - 这取决于应用程序开发人员.Inbar Rose的回答并不完全正确.如果调用您所指的模块foo,则__name__getLogger调用中的引用将被传入foo.因此,在您的配置代码中,您需要执行相应的操作

logging.getLogger('foo').setLevel(logging.WARNING)
Run Code Online (Sandbox Code Playgroud)

要在日志中包含PID,只需确保为Formatters使用适当的格式字符串,即包含的格式%(process)d.一个简单的例子是:

logging.basicConfig(format='%(process)d %(message)s')
Run Code Online (Sandbox Code Playgroud)

请注意,您无法同时从多个进程写入同一日志文件 - 如果要执行此操作,可能需要考虑其他方法.

更新:应用程序开发人员是编写Python代码的人,该代码不是库,而是由用户或其他脚本通过命令行或其他创建Python进程的方式调用.

要使用上面发布的代码,只要它是一个库,就不需要包装或修改第三方代码.例如,在调用第三方库的主脚本中:

if __name__ == '__main__':
    # configure logging here
    # sets the third party's logger to do WARNING or greater
    # replace 'foo' with whatever the top-level package name your
    # third party package uses
    logging.getLogger('foo').setLevel(logging.WARNING)
    # set any other loggers to use INFO or greater,
    # unless otherwise configured explicitly
    logging.basicConfig(level=logging.INFO, format='%(process)d %(message)s')
    # now call the main function (or else inline code here)
    main()
Run Code Online (Sandbox Code Playgroud)

如果第三方代码通过cron运行,那么它不是库代码 - 它是一个应用程序,你可能运气不好.


gue*_*tli 6

几个月前我问过这个问题.不幸的是,我没有得到满意的答案.

使用日志记录和设置它之间的区别对我来说很重要.

这是我的解决方案:在我们的上下文中,我们设置了一个被调用的方法中的日志记录usercustomize.py.

这样,可选插件可以使用日志记录而无需进行设置.

这几乎解决了我的所有需求.

到目前为止,我发现没有比这更好的方法usercustomize.py.我完美的解决方案是我会调用的virtualenvcustomize.py:如果解释器加载virtualenv,则会运行一些初始化代码.到目前为止,我找不到这样的钩子.如果您有解决方案,请告诉我.


Toc*_*Toc 5

几种可能性:

包装纸

如果您可以编辑您的cron表,您可以在python中创建一个小脚本来获取lib记录器,删除现有的日志处理程序并在其上挂钩您的自定义处理程序:

# Assumes the lib defines a logger object
from third_party_lib import *

# Note this assumes only one handler was defined by the lib
logger.removeHandler(logger.handlers[0])

# Then we can hook our custom format handler
custom_handler = logging.StreamHandler(sys.stdout)
custom_handler.setFormatter(logging.Formatter(format = '%(asctime)s %(levelname)s %(name)s %(process)d: %(message)s', None))
logger.addHandler(custom_handler)
logger.setLevel(logging.WARNING)
Run Code Online (Sandbox Code Playgroud)

另外请记住,假设lib没有在路上重新声明记录器.

动态代码编辑

如果您无法修改cron调用,则可以进行动态代码编辑,但这相当于手动编辑文件(hacky):

  • 获取包含记录器配置的第三方文件
  • 修改并保存修改后的版本
  • cron作业使用第三方代码启动任务
  • 执行cron作业后,将文件还原到其原始状态.