记录装饰器不输出 DEBUG 级别消息

Logging decorator not outputting DEBUG level messages

我创建了一个记录函数,它用作参数化记录装饰器。

from functools import wraps
import logging

def logged(level, name=None, message=None):
    '''
    Add logging to a function.  
    - level is the logging level.
    - name is the logger
    - message is the log message
    If name and mesage are not provided, the module and function name are used by default.
    '''
    
    def decorate(func):
        logname = name if name else func.__module__
        log = logging.getLogger(logname)
        logmsg = message if message else func.__name__
        ch = logging.StreamHandler()
               
        # create formatter
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

        # add formatter to ch
        ch.setFormatter(formatter)

        # add ch to logger
        log.addHandler(ch)
        
        @wraps(func)
        def wrapper(*args, **kwargs):
            log.log(level,logmsg)
            return(func(*args, **kwargs))
        
        return wrapper
    return decorate

当我用 logging.CRITICAL 调用它时,我得到一个日志输出到控制台。

@logged(logging.CRITICAL,'example')
def spam():
    print('SPAM....!')

spam()

这输出:

2021-07-14 16:10:11,699 - example - CRITICAL - spam

但是这个returns根本没有输出到控制台:

@logged(logging.DEBUG)
def add(x,y):
    return x + y

add(1,2)    

您需要致电log.setLevel。默认为 logging.WARNING.

>>> log.getEffectiveLevel()
30
>>> logging.WARNING
30
>>> log.isEnabledFor(logging.WARNING)
True
>>> log.isEnabledFor(logging.INFO)
False
>>> log.isEnabledFor(logging.DEBUG)
False
>>>

既然你不相信,我将你的代码保存为 orig.py 并将 .setLevel 调用添加到副本中,然后将其保存为 modified.py

这是我机器上打印的内容。


>py orig.py

>py modified.py
2021-07-14 17:11:04,202 - __main__ - DEBUG - add

>fc /n orig.py modified.py
Comparing files orig.py and MODIFIED.PY
***** orig.py
   15:          log = logging.getLogger(logname)
   16:          logmsg = message if message else func.__name__
***** MODIFIED.PY
   15:          log = logging.getLogger(logname)
   16:          log.setLevel(level)
   17:          logmsg = message if message else func.__name__
*****


>

这是完整的修改代码

from functools import wraps
import logging

def logged(level, name=None, message=None):
    '''
    Add logging to a function.  
    - level is the logging level.
    - name is the logger
    - message is the log message
    If name and mesage are not provided, the module and function name are used by default.
    '''
    
    def decorate(func):
        logname = name if name else func.__module__
        log = logging.getLogger(logname)
        log.setLevel(level)
        logmsg = message if message else func.__name__
        ch = logging.StreamHandler()
               
        # create formatter
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

        # add formatter to ch
        ch.setFormatter(formatter)

        # add ch to logger
        log.addHandler(ch)
        
        @wraps(func)
        def wrapper(*args, **kwargs):
            log.log(level,logmsg)
            return(func(*args, **kwargs))
        
        return wrapper
    return decorate
    
@logged(logging.DEBUG)
def add(x,y):
    return x + y

add(1,2)