2010-07-28 8 views
10

Possiedo un pacchetto con componenti diversi che trarrebbero grande vantaggio dall'utilizzo della registrazione e dall'esportazione di informazioni utili.Modalità di impostazione efficiente Registrazione su un modulo pacchetto

Quello che non voglio fare è quello di 'setup' corretta registrazione per ogni singolo file con qualche parte lungo queste linee:

import logging 
logging.basicConfig(level=DEBUG) 
my_function = logging.getLogger("my_function") 
my_class = logging.getLogger("my_class") 

Ho provato un paio di approcci, uno dei quali è l'aggiunta del boilerplate codice in una classe all'interno di un modulo di utilità e cercare di fare qualcosa di simile:

from util import setlogging 
set_logging() 

Ma anche la soluzione di cui sopra non ha un aspetto pulito per me e causerebbe problemi a causa setLogger non ha un metodo __call__. Quello che mi è piaciuto è che la mia classe "set_logging" leggeva un file di configurazione e aveva alcuni valori predefiniti, quindi non avrebbe importanza quale livello o quale tipo di formato di registrazione volevo che lo impostasse correttamente.

C'è un modo per inizializzare la corretta registrazione attraverso la scheda nel mio pacchetto? Forse nel file __init__.py?

E proprio per essere il più verbose possibile, questo è ciò che setlogging (ora una funzione, non una classe) si presenta come:

def setlogging(config=None): 
    if config == None: 
     config = config_options() # sets default values 
    levels = { 
     'debug': DEBUG, 
     'info': INFO 
     } 

    level = levels.get(config['log_level']) 
    log_format = config['log_format'] 
    datefmt = config['log_datefmt'] 

    basicConfig(
     level = level, 
     format = log_format, 
     datefmt = datefmt) 

risposta

11

Se si desidera che tutto il codice nei diversi moduli del vostro pacchetto a utilizzare lo stesso oggetto logger, è sufficiente (fare quel logger disponibili - vedi in seguito - e) chiamare

mylogger.warning("Attenzione!") 

o simili, piuttosto che logging.warning & c. Quindi, il problema si riduce a creare un oggetto mylogger per l'intero pacchetto e renderlo disponibile in tutti i moduli del pacchetto. (In alternativa, è possibile utilizzare i logger denominati con nomi che iniziano con il nome del pacchetto seguito da un punto, ma mentre questo è parte integrante della funzionalità del pacchetto logging, personalmente non ho mai trovato un modo naturale per funzionare).

Così, la vostra funzione util.setlogging potrebbe semplicemente essere seguito da, diciamo,

mylogger = logging.getLogger(package_name) 

ed ogni modulo che importa util può semplicemente utilizzare

util.mylogger.warning('Watch out!') 

e simili. Questo mi sembra l'approccio più semplice, purché si applichi il concetto secondo cui tutto il codice nel pacchetto deve essere registrato allo stesso modo.

+0

non avrei ancora bisogno di chiamare setlogging() per poter accedere a "mylogger"? Anche se ci provo, ottengo comunque un AttributeError atteso poiché l'oggetto 'function' non ha attributo 'mylogger'. Forse non sto ottenendo completamente l'immagine ... – alfredodeza

+0

@alfredo, deve essere chiamato solo una volta (dal pacchetto '__init __. Py' sarebbe il posto più semplice da usare per lo scopo, dal momento che sai che viene eseguito sempre prima di qualsiasi codice in qualsiasi modulo nel pacchetto) e, naturalmente, è possibile aggiungere a quel logger un gestore, con il formattatore configurato come si desidera, come nel codice di esempio fornito su http://docs.python.org/library/logging.html?highlight=logging#configuring-logging. –

+0

Grazie Alex, mi ha davvero aiutato! Ti offrirò una birra l'anno prossimo a PyCon :) – alfredodeza

1

Il modo corretto per un modulo per utilizzare la registrazione è

import logging 
logger = logging.getLogger('my_module_name') 

e

logger.debug('help!') 

diventa un no-op fino a quando qualcuno chiama logging.basicConfig() (o una sua variante).

Problemi correlati