web-dev-qa-db-fra.com

Comment configurer la connexion Python

Je suis nouveau sur Python et je commence juste un projet. J'ai l'habitude d'utiliser log4j in Java et je voudrais enregistrer tous les modules et classes dans Python comme je le fais en Java.

Dans Java J'ai un fichier de configuration de journal dans le dossier src nommé log4j.properties comme ci-dessous:

log4j.rootLogger=DEBUG, Console, fileout

log4j.appender.Console=org.Apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.Apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss} %5p [%t] (%F:%L) - %m%n

log4j.appender.fileout=org.Apache.log4j.RollingFileAppender
log4j.appender.fileout.File=servidor.log
log4j.appender.fileout.layout=org.Apache.log4j.PatternLayout
log4j.appender.fileout.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss} (%F:%L) %p %t %c - %m%n

Il se connecte à la console et à un fichier.

Dans mes cours, je n'ai qu'à importer log4j et ajoutez un attribut statique pour récupérer le log4j logger avec config chargé alors toutes les classes se connecteront dans la console et le fichier. Le fichier de configuration est chargé automatiquement par le nom. Par exemple:

import org.Apache.log4j.Logger;

public class Main {
    public static Logger logger = Logger.getLogger(Main.class);
    public static void main(String[] args) {
        logger.info("Hello");
    }
}

Maintenant, j'ai du mal à configurer la journalisation en Python, j'ai lu la documentation mais je n'ai pas trouvé de moyen de l'utiliser dans de nombreux modules/classes. Comment pourrais-je configurer Python se connecter de manière simple pour enregistrer mes modules et classes sans code beaucoup dans chaque module/classe? Est-il possible de reproduire le même code que j'ai écrit en Python?

31
dextervip

En fait, en Python cela ressemble à peu près. Il existe différentes façons de le faire. Je crée généralement une classe de journalisation qui est très simple:

import os
import logging 
import settings   # alternativly from whereever import settings  

class Logger(object):

    def __init__(self, name):
        name = name.replace('.log','')
        logger = logging.getLogger('log_namespace.%s' % name)    # log_namespace can be replaced with your namespace 
        logger.setLevel(logging.DEBUG)
        if not logger.handlers:
            file_name = os.path.join(settings.LOGGING_DIR, '%s.log' % name)    # usually I keep the LOGGING_DIR defined in some global settings file
            handler = logging.FileHandler(file_name)
            formatter = logging.Formatter('%(asctime)s %(levelname)s:%(name)s %(message)s')
            handler.setFormatter(formatter)
            handler.setLevel(logging.DEBUG)
            logger.addHandler(handler)
        self._logger = logger

    def get(self):
        return self._logger

Ensuite, si je veux enregistrer quelque chose dans une classe ou un module, j'importe simplement l'enregistreur et crée une instance. La transmission du nom de classe créera un fichier pour chaque classe. L'enregistreur peut ensuite enregistrer des messages dans son fichier via le débogage, les informations, les erreurs, etc.:

from module_where_logger_is_defined import Logger

class MyCustomClass(object):

    def __init__(self):
        self.logger = Logger(self.__class__.__name__).get()   # accessing the "private" variables for each class

    def do_something():
        ...
        self.logger.info('Hello')

    def raise_error():
        ...
        self.logger.error('some error message')

Réponse mise à jour

Au fil des ans, j'ai changé la façon dont j'utilise Python journalisation un peu. Sur la base des bonnes pratiques, je configure la journalisation de l'ensemble de l'application une fois dans le module chargé en premier lors du démarrage de l'application et puis utilisez des enregistreurs individuels dans chaque fichier. Exemple:


# app.py (runs when application starts)

import logging
import os.path

def main():
    logging_config = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {
                'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
            },
        },
        'handlers': {
            'default_handler': {
                'class': 'logging.handlers.FileHandler',
                'level': 'DEBUG',
                'formatter': 'standard',
                'filename': os.path.join('logs', 'application.log'),
                'encoding': 'utf8'
            },
        },
        'loggers': {
            '': {
                'handlers': ['default_handler'],
                'level': 'DEBUG',
                'propagate': False
            }
        }
    }
    logging.config.dictConfig(logging_config)
    # start application ...

if __name__ == '__main__':
    main()

# submodule.py (any application module used later in the application)

import logging

# define top level module logger
logger = logging.getLogger(__name__)

def do_something():
    # application code ...
    logger.info('Something happended')
    # more code ...
    try:
        # something which might break
    except SomeError:
        logger.exception('Something broke')
        # handle exception
    # more code ...

Ce qui précède est la méthode recommandée pour ce faire. Chaque module définit son propre enregistreur et peut facilement s'identifier en fonction du __name__ attribut quel message a été connecté dans quel module lorsque vous inspectez les journaux. Cela supprime le passe-partout de ma réponse d'origine et utilise à la place le logging.config module de la bibliothèque standard Python.

38
Torsten Engelbrecht

Les documents fournissent un assez bon exemple d'utilisation de votre enregistreur dans plusieurs modules . Fondamentalement, vous configurez la journalisation une fois au début de votre programme. Ensuite, vous importez le module de journalisation où vous voulez avoir la journalisation et l'utilisez.

myapp.py

import logging
import mylib

def main():
    logging.basicConfig(filename='myapp.log', level=logging.INFO)
    logging.info('Started')
    mylib.do_something()
    logging.info('Finished')

if __name__ == '__main__':
    main()

mylib.py

import logging

def do_something():
    logging.info('Doing something')

Cet exemple montre une configuration d'enregistreur très simpliste, mais vous pouvez très facilement utiliser différentes façons de configurer la journalisation pour configurer des scénarios plus avancés.

12
Mark Hildreth