Python日志记录非侵入式方法,用于测试Twiggy或Loguru等替代记录器?

2024-06-28 10:50:20 发布

您现在位置:Python中文网/ 问答频道 /正文

这不是关于logging备选方案建议的问题

然而,我想尝试一些替代的伐木者,比如Twiggy或Loguru。或者别的什么。问题是,虽然logging配置是集中的,但记录器的采集却遍布整个代码库

获取代码

import logging  #👈 I'd like to import an alternative here.
logger = logging.getLogger(__name__)

有多少实例

(基本上,使用日志记录的每个.py文件都有这两行代码)

ack -l --python logging.getLogger | wc -l
193

在调用logging.getLogger时,有哪些好的方法可以在后台绕过stdlib日志记录并返回Loguru或Twiggy日志记录程序

我可以想到几个:

  • 将自定义logging.py放在比stdlib版本更早的Python路径项中

  • 使用导入模拟修饰符返回与stdlib不同的模块

  • monkeypatchinglogging通过在早期导入它并将logging.getLogger设置为自定义工厂函数,返回Loguru或任何替代值

  • 自定义site.py,站点初始化模块

是否有人试图在不修改每个logging调用的情况下调出logging?你是怎么做到的

此外,这是在Django web应用程序的上下文中实现的。然而,我不想和settings.LOGGING为难

作为参考,这是一个Loguru logger采集,我绝对希望在发现Loguru不适合我的需要之前避免分发超过200个文件

from loguru import logger  #❌ I don't want to have to this 200 times!!!

logger.debug("That's it, beautiful and simple logging!")

在一天结束时,理想的情况是,我可以找到一个好的替代方法来登录一段时间,如果我修复了stdlib logging的配置,以后甚至可以恢复到stdlib。但是,这不需要接触所有这些文件。我可以先试试洛古鲁,然后是特维奇,再试试别的

基本上,如何将日志功能的实际提供者与所有应用程序文件断开连接

另外,需要明确的是,我使用的任何日志提供程序都必须支持或可以调整以支持记录器API,如logger.info(), logger.debug()等。。。因此,这个问题与应用程序代码无关,例如:

logger.info("this is your info")


Tags: 文件to方法代码pyimportinfologging
2条回答

我使用usercustomize.py来替换记录器。这很管用,但不管用的是芹菜和django都因为看不到完整的stdlibloggingAPI而大吃一惊

但是,只要芹菜和django不参与,这种方式修补日志效果非常好

usercustomize.py:

位置/Users/myuser/Library/Python/3.8/lib/Python/site-packages/usercustomize.py。Python对这个位置非常挑剔,它可以让您看到

$ python -m site

USER_SITE: '/Users/myuser/Library/Python/3.8/lib/python/site-packages'

您只需在该位置放置指向usercustomize.py的符号链接即可。但是,这也意味着Python代码的所有都会受到日志记录的影响(尽管您可以使用环境变量调用原始logging.getLogger)

这基本上满足了我的要求(实际的代码有点复杂,但只是因为loguru不喜欢在早期初始化),所以我不得不使用一个属性

import logging

from loguru import logger

stdlib_getLogger = logging.getLogger

# configuration goes into an endless loop if done "too early"
# and `asyincio needs to be imported first for some reason
# I ended up using a class and @property
# but that has more to do with loguru than the core idea of replacement

# logger.configure(
# handlers=[
#     dict(sink=sys.stderr, format="[{time}] {message}"),
#     dict(sink="mylog.log", enqueue=True, serialize=True),
# ])




def custom_getLogger(name, *args, **kwargs):

    #loguru's
    return logger        

    #if you want to revert to stdlib conditionally
    return stdlib_getLogger(name, *args, **kwargs)

logging.getLogger = custom_getLogger




因为您计划更改记录器,所以首先集中代码是有意义的,这样以后就可以很容易地进行更改

因此,您可以创建一个新的日志模块,其行为与内置的logging类似,并用

import my.logging.module

然后在需要实现不同的记录器时修改my.logging.module

在那里,在my.logging.module中,您可以选择使用一些特殊的逻辑实现自己的功能(在不同的记录器之间切换等),或者只需对默认行为执行hackyfrom logging import *;)

相关问题 更多 >