web-dev-qa-db-fra.com

Python Journalisation - Désactive la journalisation à partir de modules importés

J'utilise le module de journalisation Python) et souhaite désactiver les messages de journalisation imprimés par les modules tiers que j'importe. Par exemple, j'utilise un des éléments suivants:

logger = logging.getLogger()
logger.setLevel(level=logging.DEBUG)
fh = logging.StreamHandler()
fh_formatter = logging.Formatter('%(asctime)s %(levelname)s %(lineno)d:%(filename)s(%(process)d) - %(message)s')
fh.setFormatter(fh_formatter)
logger.addHandler(fh)

Cela imprime mes messages de débogage lorsque je fais un logger.debug ("mon message!"), Mais aussi les messages de débogage de tout module que j'importe (par exemple, des requêtes et un certain nombre d'autres choses).

J'aimerais uniquement voir les messages de journalisation des modules qui m'intéressent. Est-il possible de faire en sorte que le module de journalisation le fasse?

Idéalement, j'aimerais pouvoir demander à l'enregistreur d'imprimer des messages à partir de "ModuleX, ModuleY" et d'ignorer tous les autres.

J'ai examiné les éléments suivants, mais je ne veux pas avoir à désactiver/activer la journalisation avant chaque appel d'une fonction importée: journalisation - comment ignorer les journaux de modules importés?

53
blindsnowmobile

Le problème est que l'appel getLogger sans arguments renvoie le logger racine donc lorsque vous définissez le niveau sur logging.DEBUG vous définissez également le niveau pour les autres modules qui utilisent cet enregistreur.

Vous pouvez résoudre ce problème simplement et non à l’aide du logger racine. Pour cela, il suffit de passer un nom en argument, par exemple le nom de votre module:

logger = logging.getLogger('my_module_name')
# as before

cela créera un nouvel enregistreur et ne modifiera donc pas par inadvertance le niveau de journalisation des autres modules.


Évidemment, vous devez utiliser logger.debug au lieu de logging.debug puisque cette dernière est une fonction pratique qui appelle la méthode debug du logger racine.

Ceci est mentionné dans le Didacticiel de journalisation avancée . Il vous permet également de savoir quel module a déclenché le message de journal de manière simple.

42
Bakuriu

Si vous utilisez le paquet python logging, il est courant de définir un journal dans chaque module qui l'utilise.

logger = logging.getLogger(__name__)

De nombreux packages python populaires) le font, notamment requests . Si un package utilise cette convention, il est facile d'activer/désactiver sa journalisation, car la nom du consignateur aura le même nom que le paquet (ou sera un enfant de ce consignateur). Vous pouvez même le consigner dans le même fichier que vos autres enregistreurs.

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

requests_logger = logging.getLogger('requests')
requests_logger.setLevel(logging.DEBUG)

handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
logger.addHandler(handler)
requests_logger.addHandler(handler)
30
Brendan Abel

Je ne sais pas si cela convient pour poster, mais je suis resté coincé pendant longtemps et je voulais aider quelqu'un avec le même problème, car je ne l'avais trouvé nulle part ailleurs!

J'obtenais les journaux de débogage de matplotlib malgré le suivi de la documentation assez simple du didacticiel avancé de journalisation et du dépannage . J'étais en train de lancer mon enregistreur dans main() d'un fichier et d'importer une fonction pour créer un tracé à partir d'un autre fichier (où j'avais importé matplotlib).

Ce qui a bien fonctionné pour moi, c’était de fixer le niveau de matplotlib avant de l’importer , plutôt que comme après pour les autres modules de mon fichier principal. Cela me semblait paradoxal, donc si quelqu'un a une idée de la façon de configurer la configuration d'un enregistreur qui n'a pas encore été importé, je serais curieux de savoir comment cela fonctionne. Merci!

Dans mon dossier principal:

import logging
import requests
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logging.getLogger('requests').setLevel(logging.DEBUG)

def main():
  ...

Dans mon plot.py fichier:

import logging
logging.getLogger('matplotlib').setLevel(logging.WARNING)
import matplotlib.pyplot as plt

def generatePlot():
  ...
18
Finn

@Bakuriu explique la fonction avec élégance. Inversement, vous pouvez utiliser la méthode getLogger() pour extraire et reconfigurer/désactiver les enregistreurs indésirables.

Je voulais aussi ajouter la méthode logging.fileConfig() accepte un paramètre appelé disable_existing_loggers qui désactivera tous les enregistreurs précédemment définis (c'est-à-dire dans les modules importés).

8
apex-meme-lord

Cela désactive tous les enregistreurs existants, tels que ceux créés par les modules importés, tout en utilisant l’enregistreur racine (et sans avoir à charger un fichier externe).

logging.config.dictConfig({
    'version': 1,
    'disable_existing_loggers': True,
})

Notez que vous devez importer tous les modules que vous ne voulez pas enregistrer en premier! Sinon, ceux-ci ne seront pas considérés comme des "enregistreurs existants". Il désactivera ensuite tous les enregistreurs de ces modules. Cela pourrait vous amener à rater d’importantes erreurs!

Pour des exemples plus détaillés utilisant des options connexes pour la configuration, voir https://Gist.github.com/st4lk/6287746 , et ici est un exemple (partiellement opérationnel) utilisant YAML pour config avec la bibliothèque coloredlog.

3
avv