382 votes

Utilisation de la connexion python dans plusieurs modules

J'ai un petit projet de python qui a la structure suivante -

Project 
 -- pkg01
   -- test01.py
 -- pkg02
   -- test02.py
 -- logging.conf

J'ai l'intention d'utiliser la journalisation par défaut un module pour imprimer les messages sur la sortie standard, et un fichier journal. Pour utiliser le module de journalisation, certains d'initialisation est nécessaire -

import logging.config

logging.config.fileConfig('logging.conf')
logr = logging.getLogger('pyApp')

logr.info('testing')

À l'heure actuelle, j'ai effectuer cette initialisation dans chaque module avant de commencer la journalisation des messages. Est-il possible d'effectuer cette initialisation qu'une seule fois à un endroit, que les mêmes paramètres sont réutilisés par l'exploitation forestière à travers tout le projet?

414voto

Vinay Sajip Points 41286

La meilleure pratique est, dans chaque module, d'avoir un enregistreur définie comme ceci:

import logging
logger = logging.getLogger(__name__)

près de la partie supérieure du module, puis dans un autre code dans le module n'par exemple

logger.debug('My message with %s', 'variable data')

Si vous avez besoin de subdiviser les activités d'exploitation forestière à l'intérieur d'un module, utilisez par exemple

loggerA = logging.getLogger(__name__ + '.A')
loggerB = logging.getLogger(__name__ + '.B')

et le journal d' loggerA et loggerB selon le cas.

Dans votre programme principal ou de programmes, de faire par exemple:

def main():
    "your program code"

if __name__ == '__main__':
    import logging.config
    logging.config.fileConfig('/path/to/logging.conf')
    main()

ou

def main():
    import logging.config
    logging.config.fileConfig('/path/to/logging.conf')
    # your program code

if __name__ == '__main__':
    main()

Voir ici pour la connexion de plusieurs modules, et ici pour la configuration de la journalisation pour le code qui sera utilisé comme un module de la bibliothèque par un autre code.

Mise à jour: Lors de l'appel d' fileConfig(), vous pouvez spécifier disable_existing_loggers=False si vous utilisez Python 2.6 ou version ultérieure (voir la documentation pour plus d'informations). La valeur par défaut est True pour des raisons de compatibilité ascendante, ce qui provoque tous les enregistreurs être désactivée par fileConfig() , à moins qu'ils ou leur ancêtre sont explicitement nommées dans la configuration. Avec la valeur de la valeur False, existant, les bûcherons sont laissés seuls. Si à l'aide de Python 2.7 et Python 3.2 ou version ultérieure, vous pouvez envisager l' dictConfig() API qui est mieux que fileConfig() car il donne plus de contrôle sur la configuration.

243voto

Stanislav Prokop Points 518

En fait, tous les logger est un enfant de parents module logger, de sorte que tous vous avez besoin à faire est de configurer la racine de l'enregistreur. Configurer la journalisation dans votre module d'initialisation dans le package racine:

# package/__init__.py
import logging.config

logging.config.fileConfig('logging.conf')
log = logging.getLogger(__name__)

et puis créer chaque enregistreur à l'aide de:

# package/submodule.py
# or
# package/subpackage/submodule.py
from logging
log = logging.getLogger(__name__)

Pour plus d'informations, voir enregistrement Avancé Tutoriel.

Edit: Bien sûr, vous pouvez définir votre enregistrement à tout autre endroit approprié, vous n'êtes pas limité à module d'initialisation. Voir enregistrement à partir de plusieurs modules en très peu de documentation. Mais en fait, il devrait être le point d'entrée de votre application principale ou init modules sont très bien.

18voto

Yarkee Points 1378

Je le fais toujours comme ci-dessous.

Utilisez un seul fichier python pour configurer mon journal en tant que modèle singleton nommé ' log_conf.py '

 #-*-coding:utf-8-*-

import logging.config

def singleton(cls):
    instances = {}
    def get_instance():
        if cls not in instances:
            instances[cls] = cls()
        return instances[cls]
    return get_instance()

@singleton
class Logger():
    def __init__(self):
        logging.config.fileConfig('logging.conf')
        self.logr = logging.getLogger('root')
 

Dans un autre module, il suffit d'importer la configuration.

 from log_conf import Logger

Logger.logr.info("Hello")
 

Il s'agit d'un modèle de singleton à consigner, simplement et efficacement.

5voto

deeshank Points 336

@ La solution de Yarkee semblait meilleure. J'aimerais ajouter quelque chose à cela -

 class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances.keys():
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]


class LoggerManager(object):
    __metaclass__ = Singleton

    _loggers = {}

    def __init__(self, *args, **kwargs):
        pass

    @staticmethod
    def getLogger(name=None):
        if not name:
            logging.basicConfig()
            return logging.getLogger()
        elif name not in LoggerManager._loggers.keys():
            logging.basicConfig()
            LoggerManager._loggers[name] = logging.getLogger(str(name))
        return LoggerManager._loggers[name]    


log=LoggerManager().getLogger("Hello")
log.setLevel(level=logging.DEBUG)
 

Donc, LoggerManager peut être connecté à l’ensemble de l’application. J'espère que cela a du sens et de la valeur.

5voto

deeshank Points 336

Vous pouvez aussi trouver quelque chose comme ça!

 def get_logger(name=None):
    default = "__app__"
    formatter = logging.Formatter('%(levelname)s: %(asctime)s %(funcName)s(%(lineno)d) -- %(message)s',
                              datefmt='%Y-%m-%d %H:%M:%S')
    log_map = {"__app__": "app.log", "__basic_log__": "file1.log", "__advance_log__": "file2.log"}
    if name:
        logger = logging.getLogger(name)
    else:
        logger = logging.getLogger(default)
    fh = logging.FileHandler(log_map[name])
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    logger.setLevel(logging.DEBUG)
    return logger
 

Vous pouvez maintenant utiliser plusieurs enregistreurs dans le même module et sur l'ensemble du projet si ce qui précède est défini dans un module séparé et importé dans d'autres modules si la journalisation est requise.

 a=get_logger("__app___")
b=get_logger("__basic_log__")
a.info("Starting logging!")
b.debug("Debug Mode")
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X