Python:日志记录模块 - 全局
我想知道如何实现一个可以通过您自己的设置在任何地方使用的全局记录器:
我目前有一个自定义记录器类:
class customLogger(logging.Logger):
...
该类位于一个单独的文件中,其中包含一些格式化程序和其他内容。 记录器本身可以完美工作。
我在我的主 python 文件中导入这个模块并创建一个像这样的对象:
self.log = logModule.customLogger(arguments)
但显然,我无法从代码的其他部分访问这个对象。 我使用了错误的方法吗?有更好的方法吗?
I was wondering how to implement a global logger that could be used everywhere with your own settings:
I currently have a custom logger class:
class customLogger(logging.Logger):
...
The class is in a separate file with some formatters and other stuff.
The logger works perfectly on its own.
I import this module in my main python file and create an object like this:
self.log = logModule.customLogger(arguments)
But obviously, I cannot access this object from other parts of my code.
Am i using a wrong approach? Is there a better way to do this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用
logging.getLogger(name)
创建一个命名的全局记录器。main.py
log.py
子模块.py
输出
Use
logging.getLogger(name)
to create a named global logger.main.py
log.py
submodule.py
Output
由于我还没有找到满意的答案,我想详细说明一下问题的答案,以便深入了解
logging
库的工作原理和意图,该库附带Python 的标准库。与 OP(原始海报)的方法相反,该库清楚地将记录器的接口与记录器本身的配置分开。
这意味着您不应该创建自定义记录器类并通过添加任何配置或其他方式在该类中配置记录器。
logging
库引入了四个组件:记录器、处理程序、过滤器和格式化程序 。常见的项目结构如下所示:
在代码中(例如在 module.py 中),您引用模块的记录器实例来记录特定级别的事件。
特殊变量
__name__
引用模块的名称,看起来像project.package.module
取决于您的应用程序的代码结构。module.py(以及任何其他类)本质上可能如下所示:
每个模块中的记录器都会将任何事件传播到父记录器,而父记录器又将信息传递给其附加的处理程序嗯>!与 python 包/模块结构类似,父记录器由使用“点模块名称”的命名空间确定。这就是为什么使用特殊的
__name__
变量初始化记录器是有意义的(在上面的示例中,name 匹配字符串“project.package.module”)。有两个选项可以全局配置记录器:
在 project.py 中实例化一个记录器,名称为
__package__
,等于“project”在此示例中,因此是所有子模块的记录器的父记录器。只需要向此记录器添加适当的处理程序和格式化程序即可。在执行脚本(如 main.py)中使用最顶层包的名称设置带有处理程序和格式化程序的记录器。
执行脚本(例如 main.py)最终可能看起来像这样:
方法调用
log.setLevel(...)
指定最低严重性的日志消息记录器将处理但不一定输出!它只是意味着只要消息的严重性级别高于(或等于)设置的级别,消息就会传递到处理程序。但是处理程序负责处理日志消息(例如通过打印或存储它)。因此,
logging
库提供了一种结构化和模块化的方法,只需根据需要进行利用即可。日志记录文档
replit.com 上的完整可执行示例
Since I haven't found a satisfactory answer, I would like to elaborate on the answer to the question a little bit in order to give some insight into the workings and intents of the
logging
library, that comes with Python's standard library.In contrast to the approach of the OP (original poster) the library clearly separates the interface to the logger and configuration of the logger itself.
That means you should not create a custom logger class and configure the logger inside that class by adding any configuration or whatsoever.
The
logging
library introduces four components: loggers, handlers, filters, and formatters.A common project structure looks like this:
Inside your code (like in module.py) you refer to the logger instance of your module to log the events at their specific levels.
The special variable
__name__
refers to your module's name and looks something likeproject.package.module
depending on your application's code structure.module.py (and any other class) could essentially look like this:
The logger in each module will propagate any event to the parent logger which in return passes the information to its attached handler! Analogously to the python package/module structure, the parent logger is determined by the namespace using "dotted module names". That's why it makes sense to initialize the logger with the special
__name__
variable (in the example above name matches the string "project.package.module").There are two options to configure the logger globally:
Instantiate a logger in project.py with the name
__package__
which equals "project" in this example and is therefore the parent logger of the loggers of all submodules. It is only necessary to add an appropriate handler and formatter to this logger.Set up a logger with a handler and formatter in the executing script (like main.py) with the name of the topmost package.
The executing script, like main.py for example, might finally look something like this:
The method call
log.setLevel(...)
specifies the lowest-severity log message a logger will handle but not necessarily output! It simply means the message is passed to the handler as long as the message's severity level is higher than (or equal to) the one that is set. But the handler is responsible for handling the log message (by printing or storing it for example).Hence the
logging
library offers a structured and modular approach which just needs to be exploited according to one's needs.Logging documentation
Full executable example on replit.com
python 日志记录模块作为全局记录器已经足够好了,您可能只是寻找这个:
main.py
将上面的代码放入您的执行脚本中,然后您可以在任何地方使用具有相同配置的此记录器您的项目:
module.py
对于更复杂的配置,您可以使用带有日志记录的配置文件 logging.conf
The python logging module is already good enough as global logger, you might simply looking for this:
main.py
Put the codes above into your executing script, then you can use this logger with the same configs anywhere in your projects:
module.py
For more complicated configs you may use a config file logging.conf with logging
在日志模块中创建一个
customLogger
实例并将其用作单例 - 只需使用导入的实例,而不是类。Create an instance of
customLogger
in your log module and use it as a singleton - just use the imported instance, rather than the class.您只需向其传递一个在第一个句点之前带有公共子字符串的字符串即可。字符串中用句点(“.”)分隔的部分可用于不同的类/模块/文件/等。如下所示(特别是 logger =logging.getLogger(loggerName) 部分):
You can just pass it a string with a common sub-string before the first period. The parts of the string separated by the period (".") can be used for different classes / modules / files / etc. Like so (specifically the
logger = logging.getLogger(loggerName)
part):