我有腳本的集合,我想他們產生最小的改動統一日誌消息模塊做記錄的實際信息。
我寫了一個小模塊'custom_logger',我打算從主應用程序調用一次,讓它返回一個記錄器,然後我將繼續使用。
我會導入到應用程序的子模塊只能(或者更確切地說,我希望他們)
- 只能「進口記錄日誌」 - 這樣沒有具體到我的網站需要做如果有人發現它們有用,它們就會運行。
- 應該只是記錄與log.info/error('message消息「),而不添加任何特定的站點到他們
- 應該使用已配置‘與所有的格式和左撇子,而不是根’記錄影響根記錄的配置
* custom_logger.py *
import logging
import logging.handlers
import os
import sys
def getLogger(name='root', loglevel='INFO'):
logger = logging.getLogger(name)
# if logger 'name' already exists, return it to avoid logging duplicate
# messages by attaching multiple handlers of the same type
if logger.handlers:
return logger
# if logger 'name' does not already exist, create it and attach handlers
else:
# set logLevel to loglevel or to INFO if requested level is incorrect
loglevel = getattr(logging, loglevel.upper(), logging.INFO)
logger.setLevel(loglevel)
fmt = '%(asctime)s %(filename)-18s %(levelname)-8s: %(message)s'
fmt_date = '%Y-%m-%dT%T%Z'
formatter = logging.Formatter(fmt, fmt_date)
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger.addHandler(handler)
if logger.name == 'root':
logger.warning('Running: %s %s',
os.path.basename(sys.argv[0]),
' '.join(sys.argv[1:]))
return logger
然後是它有什麼不的什麼作品例子幾個測試消息的子模塊。
submodule.py
import sys
import custom_logger
import logging
class SubClass(object):
def __init__(self):
# NOK (no idea why since by default (no name parameter), it should return the root logger)
#log = logging.getLogger()
#log.info('message from SubClass/__init__')
# OK (works as expected)
#log = logging.getLogger('root')
#log.info('message from SubClass/__init__')
# OK (works as expected)
log = custom_logger.getLogger('root')
log.info('message from SubClass/__init__')
def SomeMethod(self):
# OK but I'd have to define `log` for every method, which is unacceptable
# Please see question below all code snippets
log = custom_logger.getLogger('root')
log.info('message from SubClass/SomeMethod')
和主要應用:app.py這裏沒有什麼特別的:
#!/usr/bin/python
import custom_logger
import submodule
log = custom_logger.getLogger('root', loglevel='DEBUG')
log.debug('debug message')
log.info('info message')
log.warning('warning message')
log.error('error message')
a = submodule.SubClass() # this should produce a log message
a.SomeMethod() # so should this
輸出,我以後和我得到我,只是以極其醜陋的方式:
% ./app.py
2013-04-08T03:07:46BST custom_logger.py WARNING : Running: app.py
2013-04-08T03:07:46BST app.py DEBUG : debug message
2013-04-08T03:07:46BST app.py INFO : info message
2013-04-08T03:07:46BST app.py WARNING : warning message
2013-04-08T03:07:46BST app.py ERROR : error message
2013-04-08T03:07:46BST submodule.py INFO : message from SubClass/__init__
2013-04-08T03:07:46BST submodule.py INFO : message from SubClass/SomeMethod
我希望能夠在app.py中定義一個記錄器,然後在子模塊中只使用標準的Python日誌記錄庫來使用app.py中已配置的記錄器。
此外,一個醜陋的解決方法:如果我把下面的代碼在submodule.py進口後:
log = custom_logger.getLogger('root')
之前我在記錄器被app.py配置,有效地使子模塊將被執行,不是我的應用程序配置日誌
另一個解決辦法我認爲是:子類的constuctor內,我可以定義
self.log = custom_logger.getLogger('root')
然後用self.log.error( '一些錯誤')。必須有更好的方法 - 如果您能提出有用的建議或指出我誤解了文檔的地方,我會非常感激!
PS。我花了很多時間閱讀Python日誌記錄howto(basic和advanced)和cookbook,如果我錯過了某些有用的東西,請指出。
謝謝!
謝謝米哈伊。我想我會有更多的時間來看看它,但我需要等待週末。到目前爲止,我已經能夠通過在submodule.py中將日誌定義爲getLogger對象來使我的類可以完成所有工作(附加格式器,處理程序和設置日誌級別)。我希望這可以在不將事物放在類定義之外的情況下完成。 我的問題更多的是「爲什麼我所做的某些方法沒有按預期工作,因爲我想了解其背後的原因,而不是將代碼交給我,但我非常感謝您的幫助: ) – 2013-04-10 01:27:35
我更新了我的答案,除此之外,您可以查看模塊的代碼。您可以看到根記錄器在導入過程中被實例化了,我也不明白爲什麼getLogger(「root」)不能正常工作在所有情況下(你可以在app.py中執行getLogger(),在submodule.py中執行getLogger(「root」),你將得到你所需要的東西,但是反之亦然) – Mihai 2013-04-10 14:15:47
如何使用stdout重定向到文件例如python ./app.py >> file.log? – 2016-04-14 11:37:45