在 Python 中是否可以使用C++样式的日志记录宏?

Are C++ style logging macros possible in Python?

本文关键字:日志 记录 样式 C++ Python 是否 可以使      更新时间:2023-10-16

是否可以在Python中实现以下(伪)代码的等效代码?

#define DEBUG(topic, msg) LOG_IMPL(Logger.DEBUG, topic, msg)
#define INFO(topic, msg) LOG_IMPL(Logger.INFO, topic, msg)
#define LOG_IMPL(level, topic, msg) if(Logger.level() <= level) { Logger.log(level, topic, msg); }
DEBUG("MyComponent", "What you logging at?")

这样做的好处是你不必计算字符串日志消息,例如连接字符串、调用 .format() 等。

更新:

懒惰的记录器消息字符串评估 - 这回答了我的问题,所以我将投票关闭这篇文章。

Python附带电池,logging module是stdlib的一部分:

from logging import getLogger
log = getLogger('my.module')
log.debug('Debug level messages')
log.warning('Warning!')
log.info('Informative message')
log.error('Error messages')
log.exception('Use this in an exception handler, the exception will be included automatically')

上面一组方法是log.log(level, msg)方法的快捷方式,该方法采用任意(整数)级别,logging模块定义DEBUGWARNING和其他级别。

这些方法支持 python 字符串格式模板的延迟计算;仅当消息的日志级别实际超过正在记录的日志记录级别时,才会插入额外的参数:

log.warning('Warning message: the %s is missing %i frobnars', systemname, count)

仅当日志消息实际到达处理程序时,才会以等效的 'Warning message: the %s is missing %i frobnars' % (systemname, count) 记录上述消息。

如何对消息使用 lambda:

log( lambda : (string1 + string2 + "%d %d" % (val1, val2)) )

并且让日志函数仅在启用日志记录时调用传入的函数。

你试过logging模块吗?例:

import logging
logging.basicConfig(filename='example.log',level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')

来源: http://docs.python.org/howto/logging.html#logging-basic-tutorial

我想出了一个解决方案,允许对日志消息进行延迟评估,同时仍然允许我将自定义格式化程序和处理程序封装在一个小型日志记录代理类中。

除非写入日志消息(日志记录处理此消息),否则不会评估格式字符串;这是通过单独传递格式字符串和参数来实现的。

@classmethod 
def info(cls, component, msg, *args):     
    """Log an info message"""     
    cls.__log(cls.Level.INFO, component, msg, (args)  
@classmethod 
def __log(cls, level, component, msg, *args):    
    """Log a message at the requested level"""     
    logging.getLogger("local").log(level, " - ".join([component, msg.format(*args)])) 
Logger.info("MyComponent", "My message with arg '{0}'", "TestArg")