2013-07-16 57 views
33

比方說,我有以下代碼:python日誌處理程序中setLevel的要點是什麼?

import logging 
import logging.handlers 

a = logging.getLogger('myapp') 
h = logging.handlers.RotatingFileHandler('foo.log') 
h.setLevel(logging.DEBUG) 
a.addHandler(h) 

# The effective log level is still logging.WARN 
print a.getEffectiveLevel() 
a.debug('foo message') 
a.warn('warning message') 

我希望在處理器中設置logging.DEBUG會導致調試級消息被寫入日誌文件。但是,這將打印30的有效級別(等於logging.WARNING,默認值),並且僅將日誌文件記錄到日誌文件中,而不是調試消息。

看起來處理程序的日誌級別被丟棄在地板上,例如,它被無聲地忽略了。這讓我想知道,爲什麼在處理程序上有setLevel

+0

好問題,但一致的緣故,如果你正在測試'a.getEffectiveLevel','a.setLevel'更有感覺比'h.setLevel'。 –

+0

在這種情況下處理程序不具有'getEffectiveLevel'命令 –

回答

34

它允許更好的控制。默認情況下,根記錄器的電平設置爲WARNING,這意味着它不會打印較低級別的消息(不管處理程序的級別如何設置!)。但是,如果設置了根記錄的水平DEBUG,確實該消息被髮送到日誌文件:

import logging 
import logging.handlers 

a = logging.getLogger('myapp') 
a.setLevel(logging.DEBUG) # set root's level 
h = logging.handlers.RotatingFileHandler('foo.log') 
h.setLevel(logging.DEBUG) 
a.addHandler(h) 
print a.getEffectiveLevel() 
a.debug('foo message') 
a.warn('warning message') 

現在,您要添加一個新的處理程序,它不記錄調試信息的圖像。 您可以通過簡單的設置處理日誌記錄級別做到這一點:

import logging 
import logging.handlers 

a = logging.getLogger('myapp') 
a.setLevel(logging.DEBUG) # set root's level 

h = logging.handlers.RotatingFileHandler('foo.log') 
h.setLevel(logging.DEBUG) 
a.addHandler(h) 

h2 = logging.handlers.RotatingFileHandler('foo2.log') 
h2.setLevel(logging.WARNING) 
a.addHandler(h2) 

print a.getEffectiveLevel() 
a.debug('foo message') 
a.warn('warning message') 

現在,日誌文件foo.log將包含郵件,而文件foo2.log將僅包含警告消息。您可能會對只有錯誤級別消息的日誌文件感興趣,然後只需添加Handler並將其級別設置爲logging.ERROR,所有內容均使用相同的Logger

對於給定的記錄器及其處理程序,您可能會認爲Logger日誌記錄級別是一個全侷限制條件。記錄器之後將發送給處理程序的消息會執行它們自己的過濾和記錄過程。

+3

所以最好的做法是設置根記錄和通過處理程序電平記錄控制一個較低的水平。我對麼? – laike9m

+0

這不是「最佳實踐」,只是做其他事情都是無用的。如果處理程序的級別是DEBUG,但記錄程序只發送ERROR,則處理程序當然只會收到(並傳遞)ERROR。 – hmijail

14

在Python日誌中有兩個不同的概念:日誌記錄的級別和處理程序實際激活的級別。

當由記錄電話,有什麼基本情況是:

if self.level <= loglevel: 
    for handler in self.handlers: 
     handler(loglevel, message) 

雖然每個這些處理程序將隨後致電:

if self.level <= loglevel: 
    # do something spiffy with the log! 

如果你想要一個真實世界演示這個,你可以看看Django's config settings。我會在這裏包含相關的代碼。

LOGGING = { 
    #snip 
    'handlers': { 
     'null': { 
      'level': 'DEBUG', 
      'class': 'logging.NullHandler', 
     }, 
     'console':{ 
      'level': 'DEBUG', 
      'class': 'logging.StreamHandler', 
      'formatter': 'simple' 
     }, 
     'mail_admins': { 
      'level': 'ERROR', 
      'class': 'django.utils.log.AdminEmailHandler', 
      'filters': ['special'] 
     } 
    }, 
    'loggers': { 
     #snip 
     'myproject.custom': { 
      # notice how there are two handlers here! 
      'handlers': ['console', 'mail_admins'], 
      'level': 'INFO', 
      'filters': ['special'] 
     } 
    } 
} 

所以,在上面的配置中,僅記錄到getLogger('myproject.custom').info以上將得到處理,以便記錄。當發生這種情況時,控制檯將輸出所有結果(它會輸出所有內容,因爲它設置爲DEBUG級別),而mail_admins記錄器將會發生在所有ERROR s,FATAL s和CRITICAL s之間。

我想一些代碼,是不是Django的效果也會有所幫助:

import logging.handlers as hand 
import logging as logging 

# to make things easier, we'll name all of the logs by the levels 
fatal = logging.getLogger('fatal') 
warning = logging.getLogger('warning') 
info = logging.getLogger('info') 

fatal.setLevel(logging.FATAL) 
warning.setLevel(logging.WARNING) 
info.setLevel(logging.INFO)  

fileHandler = hand.RotatingFileHandler('rotating.log') 

# notice all three are re-using the same handler. 
fatal.addHandler(fileHandler) 
warning.addHandler(fileHandler) 
info.addHandler(fileHandler) 

# the handler should log everything except logging.NOTSET 
fileHandler.setLevel(logging.DEBUG) 

for logger in [fatal,warning,info]: 
    for level in ['debug','info','warning','error','fatal']: 
     method = getattr(logger,level) 
     method("Debug " + logger.name + " = " + level) 

# now, the handler will only do anything for *fatal* messages... 
fileHandler.setLevel(logging.FATAL) 

for logger in [fatal,warning,info]: 
    for level in ['debug','info','warning','error','fatal']: 
     method = getattr(logger,level) 
     method("Fatal " + logger.name + " = " + level) 

導致:

Debug fatal = fatal 
Debug warning = warning 
Debug warning = error 
Debug warning = fatal 
Debug info = info 
Debug info = warning 
Debug info = error 
Debug info = fatal 
Fatal fatal = fatal 
Fatal warning = fatal 
Fatal info = fatal 

再次,注意如何info東西記錄在infowarningerror,和fatal當日志處理程序設置爲DEBUG,但是當處理器被設置爲FATAL突然只FATAL消息使其ŧ o文件。

9

處理程序代表了記錄事件不同觀衆。上處理水平被用於控制由特定觀衆看到輸出的詳細程度,此外對記錄器設置的任何水平起作用。記錄器級別用於控制從應用程序或庫的不同部分進行日誌記錄的總體詳細程度。

this diagram,瞭解更多有關記錄事件的處理方式:

enter image description here

相關問題