Nella registrazione Python ci sono due concetti diversi: il livello al quale il logger accede e il livello effettivamente attivato dal gestore.
Quando una chiamata per accedere è fatto, ciò che sta accadendo è fondamentalmente:
if self.level <= loglevel:
for handler in self.handlers:
handler(loglevel, message)
Mentre ciascuno di questi gestori saranno quindi chiamare:
if self.level <= loglevel:
# do something spiffy with the log!
Se vuoi un mondo reale dimostrazione di questo, è possibile guardare Django's config settings. Includerò qui il codice pertinente
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']
}
}
}
Così, nella configurazione di cui sopra, registra solo per getLogger('myproject.custom').info
e soprattutto andranno trattati per la registrazione. Quando ciò accade, la console emetterà tutti i risultati (verrà emesso tutto perché è impostato sul livello DEBUG
), mentre il logger mail_admins
si verificherà per tutti gli ERROR
s, FATAL
s e CRITICAL
s.
suppongo po 'di codice che non è Django potrebbe aiutare anche:
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)
che si traduce in:
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
Anche in questo caso, si noti come info
registrato qualcosa al info
, warning
, error
, e fatal
quando il gestore di registri era impostato su DEBUG
, ma quando il gestore era impostato su all'improvviso solo i messaggi lo rendevano t o il file.
Buona domanda, ma per motivi di coerenza, se si sta testando 'a.getEffectiveLevel',' a.setLevel' ha più senso di 'h.setLevel'. –
In questo caso il gestore non ha un comando 'getEffectiveLevel' –