Python中的每文件/模块记录器

Bob*_*ame 5 python logging

我有一些我需要添加日志记录的Python代码.

我总是喜欢漂亮的大C宏看起来语句,如"DEBUG()","ERROR()"等用于日志记录.我觉得当跟踪点在视觉上与实际代码区分开来时,它使代码更容易阅读(没有对象).

我还希望能够在每个模块级别设置日志记录级别.

我怎样才能创建一个名为"log"的模块,它能够做到这一点(同时使用Python标准库记录模块)?

例如:

文件:main.py

# This imports LOG_MODULE_NAME, DEBUG, WARN, etc
from log import *
import my_module

LOG_MODULE_NAME("main")

log.set_level("main", log.LVL_DEBUG)
log.set_level("my_module", log.LVL_WARN)

if __name__ == "__main__":
    foo = my_module.myFunc(2)

DEBUG("Exiting main.py")
Run Code Online (Sandbox Code Playgroud)

文件:my_module.py

from log import *

LOG_MODULE_NAME("my_module")


def myFunc(x):
    DEBUG("Entering function")
    if x != 1:
         WARN("I thought it would be 1")
    DEBUG("Exiting function")
    return x+1
Run Code Online (Sandbox Code Playgroud)

我希望输出看起来像:

[WARN:my_module - my_module.py:9] I thought it would be 1
[DEBUG:main - main.py:11] Exiting main.py
Run Code Online (Sandbox Code Playgroud)

msw*_*msw 6

这些答案似乎跳过了一个非常简单的想法,即函数是第一类对象,它允许:

def a_function(n):
    pass

MY_HAPPY_NAME = a_function
MY_HAPPY_NAME(15) # which is equivalent to a_function(15)
Run Code Online (Sandbox Code Playgroud)

除了我建议你不要这样做.PEP8编码约定被广泛使用,因为生命太短,不足以让我必须以COBOLy方式读取标识符.

其他一些答案也使用globalPython中几乎不需要的语句.如果您正在制作模块级记录器实例

import logging

log = logging.getLogger(__name__)

def some_method():
    ...
    log.debug(...)
Run Code Online (Sandbox Code Playgroud)

是一种使用模块级变量的完美可行,简洁的方法log.你甚至可以这样做

log = logging.getLogger(__name__)
DEBUG = log.debug

def some_method():
    ...
    DEBUG(...)
Run Code Online (Sandbox Code Playgroud)

但我保留称那丑陋的权利.


2rs*_*2ts 3

如果您想让记录器的名称指示使用它的模块,您可以使用logger.getLogger([name])module 函数,并__name__作为其(可选)参数传递,如此处所述

如果您想使用类似的名称,请在每个文件DEBUG()中执行类似的操作...

LOG_MODULE_NAME = logging.getLogger(__name__)

def DEBUG(msg):
    global LOG_MODULE_NAME
    LOG_MODULE_NAME.debug(msg)
Run Code Online (Sandbox Code Playgroud)

我不清楚全局命名空间在 Python 中实际工作的方式......这个答案

每个模块都有自己的“全局”名称空间。

所以我想你会那样的,因为LOG_MODULE_NAME模块之间不会发生冲突。

我相信这种方法将为您提供一个日志文件,其中各行如下所示:

DEBUG:my_module:Entering function
WARN:my_module:I thought it would be 1
DEBUG:my_module:Exiting function
DEBUG:root:Exiting main.py
Run Code Online (Sandbox Code Playgroud)

还不够内省吗?您需要该inpsect模块,它将在程序运行时为您提供大量有关程序的信息。例如,这将为您提供当前的行号。

您关于“在每个模块级别设置日志级别”的注释让我认为您想要类似getEffectiveLevel(). 你可以尝试像这样把它压碎:

LOG_MODULE_NAME = logging.getLogger(__name__)
MODULE_LOG_LEVEL = log.LVL_WARN

def DEBUG(msg):
    if MODULE_LOG_LEVEL = log.LVL_DEBUG:
        global LOG_MODULE_NAME
        LOG_MODULE_NAME.debug(msg)
Run Code Online (Sandbox Code Playgroud)

不过,我对该logging模块的经验还不够丰富,无法告诉您如何动态地更改每个模块的日志级别。