2010-07-28 4 views
10

J'ai un package qui contient plusieurs composants qui bénéficieraient grandement de l'utilisation de la journalisation et de la génération d'informations utiles.Méthode efficace de définition de la journalisation dans un module de package

Ce que je ne veux pas faire est de « setup » exploitation forestière appropriée pour chaque fichier avec quelque part le long de ces lignes:

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

J'ai essayé deux approches, l'un d'entre eux étant en ajoutant le passe-partout code dans une classe dans un module de service et essayer de faire quelque chose comme ceci:

from util import setlogging 
set_logging() 

Mais cette solution ne semble pas propre à moi et causerait des problèmes parce setLogger ne dispose pas d'une méthode __call__. Ce que j'ai aimé, c'est que ma classe "set_logging" lirait à partir d'un fichier de configuration et aurait des valeurs par défaut donc peu importe le niveau ou le type de format de journalisation que je voulais pour le configurer correctement.

Existe-t-il un moyen d'initialiser la consignation appropriée dans mon emballage? Peut-être dans le fichier __init__.py?

Et d'être aussi bavard que possible, c'est ce que setlogging (maintenant une fonction, pas une classe) ressemble à:

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) 

Répondre

11

Si vous voulez tout le code dans les différents modules de votre colis utiliser le même objet enregistreur, il vous suffit de (faire que l'enregistreur disponible - voir plus loin - et) appeler

mylogger.warning("Attenzione!") 

ou similaires, plutôt que logging.warning & c. Ainsi, le problème se réduit à créer un objet mylogger pour l'ensemble du paquet et le rendre disponible dans tous les modules du paquet. (Vous pouvez également utiliser des enregistreurs nommés avec des noms commençant par le nom du paquet suivi d'un point, mais bien que cela fasse partie des fonctionnalités du paquet logging, personnellement, je n'ai jamais trouvé que c'était une façon naturelle de fonctionner).

Ainsi, votre fonction util.setlogging pourrait simplement être suivie, par exemple,

mylogger = logging.getLogger(package_name) 

et tous les modules que les importations en util peuvent simplement utiliser

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

et similaires. Cela me semble être l'approche la plus simple, aussi longtemps que le concept que tout le code dans le paquet doit être enregistré de la même manière s'applique.

+0

n'aurais-je pas encore besoin d'appeler setlogging() pour pouvoir accéder à 'mylogger'? Même si j'essaye cela, je reçois toujours un attribut AttributeError attendu puisque l'objet 'function' n'a pas d'attribut 'mylogger'. Peut-être que je ne comprends pas complètement l'image ... – alfredodeza

+0

@alfredo, il doit être appelé une seule fois (à partir du paquet '__init __ .py' du paquet serait l'endroit le plus simple à utiliser, puisque vous savez qu'il s'exécute toujours avant tout code dans un module du paquet) et bien sûr vous pouvez ajouter à ce logger un gestionnaire, avec son formateur configuré comme vous le souhaitez, comme dans l'exemple de code fourni sur http://docs.python.org/library/logging.html?highlight=logging#configuring-logging. –

+0

Merci Alex, ça m'a vraiment aidé! Je vais vous acheter une bière l'année prochaine à PyCon :) – alfredodeza

1

La bonne façon pour un module à utiliser la journalisation est

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

et

logger.debug('help!') 

devient un no-op jusqu'à ce que quelqu'un appelle logging.basicConfig() (ou une variante).

Questions connexes