当前位置: 首页 > 知识库问答 >
问题:

从多个包层次结构进行Python日志记录(不使用根记录器)

司马奇希
2023-03-14

我需要为一个相当具体的设置设置日志记录。简而言之,我想在两个不同的“父”模块中处理来自一段通用库代码的日志记录。

  app_one \
     app_one_main.py
  app_two \
     app_two_main.py
  lib_package \
     lib_module.py

app_one_main和app_two_main都导入lib_module(代码如下)。

这些模块显然不共享相同的包结构,因此默认情况下,如果我使用getlogger(__name__),来自lib_module的日志记录消息不会传播到app_one或app_two

  • app_one和app_two将在同一个Python会话中运行,因此我无法全局操作lib_module中的记录器的层次结构。
  • 我无法操作全局根记录器,因为我的代码集成到一个更大的系统中的方式。
  • app_one和app_two具有不同的处理程序。例如,他们将日志写入不同的文件
  1. 这个答案建议将父记录器传递到库代码的函数中。我想这是可行的,但它会破坏我现有的几乎所有代码,我并不喜欢用这种方式传递记录器。
  2. 我可以子类logging.logger并重写logger.parent以便它在其封闭范围中找到任何记录器。我在过去实现过类似的东西,但它看起来有点过度设计,会破坏默认日志记录系统的许多功能。

(这段代码甚至没有假装工作,只是一个粗糙的起始处。)

# app_one_main.py

import logging
from lib_package import lib_module

logger = logging.getLogger(__name__)

stream_handler = logging.StreamHandler()
stream_handler.setFormatter(logging.Formatter("APP ONE: %(message)s"))
logger.addHandler(stream_handler)

def log_app_one():
    logger.warning("hello from app_one_main")
    lib_module.do_the_thing()
# app_two_main.py

import logging
from lib_package import lib_module

logger = logging.getLogger(__name__)

stream_handler = logging.StreamHandler()
stream_handler.setFormatter(logging.Formatter("APP TWO: %(message)s"))
logger.addHandler(stream_handler)

def log_app_two():
    logger.warning("hello from app_two_main")
    lib_module.do_the_thing()
# lib_module.py

import logging

logger = logging.getLogger(__name__)

def do_the_thing():
    logger.warning("hello from library code")

app_one和app_two最终将运行在Maya这样的另一个平台上,它提供了单个python会话。这两个模块都将导入到同一会话中。

因此,如果运行app_one_main.log_app_one(),我希望:

APP ONE: hello from app_one_main
APP ONE: hello from library code

app_two_main.log_app_two():

APP TWO: hello from app_two_main
APP TWO: hello from library code

共有1个答案

云宜人
2023-03-14

主要问题是,您是直接实例化Logger对象,而不是使用GetLogger为您获取这些对象。Logger objects文档说记录器永远不应该直接实例化,而应该始终通过模块级函数logging.getLogger(name)来实例化。当getlogger创建记录器时,它还将其插入日志层次结构中,以便其他人可以配置它们。您只有自由浮动的logger对象。

您的库记录器称为lib_package.lib_module。移动到getlogger之后,任何其他模块都可以获得包记录器lib_package并对其进行配置,然后它的任何子记录器也将工作。

App_One_Main.py

import logging
from lib_package import lib_module

# setup logging output for this module
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(logging.Formatter("APP ONE: %(message)s"))
logger = logging.getLogger(__name__)
#logger.setLevel(logging.INFO)
logger.addHandler(stream_handler)

# add handler other modules / packages
pkg_logger = logging.getLogger('lib_package')
pkg_logger.addHandler(stream_handler)
#pkg_logger.setLevel(logging.INFO)
del pkg_logger

logger.warning("hello from app_one_main")
lib_module.do_the_thing()

lib_package/lib_module.py

# lib_module.py

import logging

logger = logging.getLogger(__name__)

def do_the_thing():
    logger.warning("hello from library code")
 类似资料:
  • 我想在我的应用程序中使用SLF4J+logback用于两个目的--日志和审计。 14:41:57.978[main]信息AUDIT_LOGGER-110欢迎使用main 如何确保审核消息在审核记录器下只出现一次?

  • 从docker容器中将结构化日志写入journald的最佳方式是什么? 例如,我有一个使用sd_journal_send而不是更改应用程序的应用程序,我尝试通过 -v/var/log/systemd/journal:/var/log/systemd/journal docker journald输出日志记录选项有哪些限制?它似乎不支持应用程序编写不仅仅是消息字段。 -- 所以我发现我需要 C程序可

  • 问题内容: 我正在编写一个服务器应用程序,该应用程序应该能够在控制台和日志文件上以不同级别登录。 问题是,如果设置了logging.basicConfig(),它将登录到控制台,但是必须在主线程中进行设置。 也可以使用logging.basicConfig(filename =’logger.log’)进行设置以写入文件。 设置用于控制台日志记录(logging.StreamHandler())或

  • 问题内容: 我正在迁移一个曾经使用log4j进行logback / slf4j的应用程序,并且已经出现问题约2周了……我做了一个小项目来测试logback / slf4j,它的工作效果很好,但是由于某种原因,在应用它时到实际的应用程序,它只是不想工作。 我正在使用JBoss 6.2,将EAR部署到standalone / deployments目录并启动服务器(除了我得到这个异常的事实,这一切都很

  • 现在,问题是,当我以以下方式进行日志记录时: 尽管根记录器级别被设置为“错误”,但日志条目仍然存在于两个日志文件中。然而,当我去掉“it.pkg.testpkg.service”记录器(通过注释或删除它)时,条目停止进入根记录器。我不太清楚这是怎么回事。 目前,我已经找到了一个临时解决方案,方法是在“root_file_appender”中添加以下条目: 谢了。