2012-06-24 35 views
0

是否有可能在Python中实现以下(伪)代码的等价物?Python中可以使用C++风格的日志记录宏吗?

#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()等)

UPDATE

Lazy logger message string evaluation - 这个回答我的问题,所以我会投来关闭这个职位。

+2

哇,这是令人厌恶的C++宏,没有任何目的。 – Puppy

+0

你到底在问什么?这些定义可以很容易地以任何语言作为功能来实现。 –

+0

@Graeme:据我所知,你不仅要求一个很好的日志记录模块(而且内置的python很棒),而且对于不评估日志消息的系统(如果构建日志消息的计算量很大)if日志记录被禁用。我错了吗? –

回答

0

我想出了一个解决方案,允许日志消息的懒惰评估,同时仍允许我来封装小日志代理类中自定义格式和处理程序。

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

@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") 
1

如何使用lambda表达式的消息:

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

而且具有日志功能只有在呼叫日志记录是否启用传递的功能。

9

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 string formatting templates;

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

上述消息将与'Warning message: the %s is missing %i frobnars' % (systemname, count)相当于仅在日志消息实际到达的处理程序中记录:当消息的日志级别实际超过正在记录的日志记录级别额外的参数进行插值仅

+0

这很有道理,但我在自己的类中包装了记录器,所以我可以在其他方面添加一些额外的级别(例如TRACE)。通过调用我的函数,我不会从底层日志库(我正在使用)的懒惰评估中受益。 – Graeme

+0

@Graeme:在罗马时,像罗马人那样做。您可以自定义本地'logging'模块来完成您想要的任何事情。也许你可以使用你的自定义类作为'Handler',它将被'logging'调用? – ereOn

+0

@格雷梅:水平是数字;只需调用'log.log(yourlevel,msg)'。 'logging.DEBUG'是10,所以'TRACE = 5'完全可以接受。 –

相关问题