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'完全可以接受。 –