2010-06-07 82 views
4

我正在編寫python包/模塊,並希望日誌消息提及它們來自哪個模塊/類/函數。即如果我運行此代碼:python中的記錄器鏈

 
import mymodule.utils.worker as worker 

w = worker.Worker() 
w.run() 

我想記錄的消息是這樣的:

 
2010-06-07 15:15:29 INFO mymodule.utils.worker.Worker.run <pid/threadid>: Hello from worker 

我怎樣才能做到這一點?

謝謝。

回答

7

我傾向於使用日誌模塊在我的包/模塊,像這樣:

import logging 
log = logging.getLogger(__name__) 
log.info("Whatever your info message.") 

此功能可設置記錄儀列入日誌信息的模塊名稱的名稱。您可以通過格式字符串中的%(name)s來控制名稱的位置。同樣,您可以將012id和線程ID與%(thread)d放置在pid。所有選項均爲See the docs

格式化例如:

import logging 
logging.basicConfig(format="%(asctime)s %(levelname)s %(name)s %(process)d/%(threadName)s: %(message)s") 
logging.getLogger('this.is.the.module').warning('Testing for SO') 

給我:

2010-06-07 08:43:10,494 WARNING this.is.the.module 14980/MainThread: Testing for SO 
+0

是的,我想過'__name__',但它目前的模塊的只有名稱,沒有完整的''字符串。你知道我怎麼能得到這樣的字符串? 順便說一句,'%(process)d'是很棒的提示,謝謝! – 2010-06-07 13:25:05

+0

@Zaar:'__name__'是導入的全名,而不僅僅是最後一部分(假設是標準導入機制)。請嘗試一下。 – 2010-06-07 14:21:22

+0

是的,我明白了!現在我全部定下來了。謝謝! – 2010-06-07 14:43:03

2

這裏是我的解決方案,來到我們的討論中。感謝大家的建議。

用法:

 
>>> import logging 
>>> logging.basicConfig(level=logging.DEBUG) 
>>> from hierlogger import hierlogger as logger 
>>> def main(): 
...  logger().debug("test") 
... 
>>> main() 
DEBUG:main:test 

默認情況下,將其命名爲記錄儀的...你也可以通過提供參數控制的深度:
3 - module.class.method默認
2 - module.class
1 - 僅模塊

記錄器實例也被緩存以防止在每次調用時計算記錄器名稱。 我希望有人會喜歡它。

代碼:

 
import logging 
import inspect 

class NullHandler(logging.Handler): 
     def emit(self, record): pass 

def hierlogger(level=3): 
    callerFrame = inspect.stack()[1] 
    caller = callerFrame[0] 
    lname = '__heirlogger'+str(level)+'__' 
    if lname not in caller.f_locals: 
     loggerName = str() 
     if level >= 1: 
      try: 
       loggerName += inspect.getmodule(inspect.stack()[1][0]).__name__ 
      except: pass 
     if 'self' in caller.f_locals and (level >= 2): 
      loggerName += ('.' if len(loggerName) > 0 else '') + 
          caller.f_locals['self'].__class__.__name__ 
     if callerFrame[3] != '' and level >= 3: 
      loggerName += ('.' if len(loggerName) > 0 else '') + callerFrame[3] 
     caller.f_locals[lname] = logging.getLogger(loggerName) 
     caller.f_locals[lname].addHandler(NullHandler()) 
    return caller.f_locals[lname] 
+0

這段代碼非常有用,在調試過程中爲我節省了很多打字時間。謝謝。 – Marcin 2013-08-29 15:54:01

+0

你值得成爲聖人! 無論如何,我想建議您對代碼進行一些改進: - 將return語句移回一個製表符,以避免在失敗時返回任何內容(但可能是格式問題) - 刪除NullHandler類定義你也可以使用logging.NullHandler) 再次感謝,非常有用的代碼! – mrnfrancesco 2014-11-20 23:40:46

+0

謝謝。 「return ...」的確是一個格式錯誤。 NullHandler被添加到Python 2中。7,而這個代碼是4年前爲Python 2.5編寫的 – 2014-11-23 16:12:46