J'utilise le module de journalisation de Python pour consigner des chaînes de débogage dans un fichier qui fonctionne plutôt bien. De plus, j'aimerais utiliser ce module pour imprimer également les chaînes sur la sortie standard. Comment puis-je faire cela? Afin de connecter mes chaînes dans un fichier, j'utilise le code suivant:
import logging
import logging.handlers
logger = logging.getLogger("")
logger.setLevel(logging.DEBUG)
handler = logging.handlers.RotatingFileHandler(
LOGFILE, maxBytes=(1048576*5), backupCount=7
)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
puis appelez une fonction logger comme
logger.debug("I am written to the file")
Merci pour l'aide ici!
Il suffit d’obtenir une poignée pour le logger racine et d’ajouter le StreamHandler
. La StreamHandler
écrit dans stderr. Vous ne savez pas vraiment si vous avez vraiment besoin de stdout sur stderr, mais c’est ce que j’utilise lorsque j’installe le consignateur Python et que j’ajoute également le FileHandler
. Ensuite, tous mes journaux vont aux deux endroits (ce qui ressemble à ce que vous voulez).
import logging
logging.getLogger().addHandler(logging.StreamHandler())
Si vous voulez générer stdout
au lieu de stderr
, il vous suffit de l'indiquer dans le constructeur StreamHandler
.
import sys
# ...
logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))
Vous pouvez également ajouter un Formatter
afin que toutes vos lignes de journal aient un en-tête commun.
c'est à dire:
import logging
logFormatter = logging.Formatter("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s")
rootLogger = logging.getLogger()
fileHandler = logging.FileHandler("{0}/{1}.log".format(logPath, fileName))
fileHandler.setFormatter(logFormatter)
rootLogger.addHandler(fileHandler)
consoleHandler = logging.StreamHandler()
consoleHandler.setFormatter(logFormatter)
rootLogger.addHandler(consoleHandler)
Imprime au format de:
2012-12-05 16:58:26,618 [MainThread ] [INFO ] my message
logging.basicConfig()
peut prendre un argument de mot clé handlers
depuis Python 3.3, ce qui simplifie beaucoup la configuration de la journalisation, en particulier lors de la configuration de plusieurs gestionnaires avec le même formateur:
handlers
- Si spécifié, il doit s'agir d'une liste de gestionnaires déjà créés à ajouter à l'enregistreur racine. Tous les gestionnaires qui ne possèdent pas déjà un ensemble de formateurs se verront attribuer le formateur par défaut créé dans cette fonction.
Le code d'exemple assez long et détaillé de la réponse acceptée devient alors simplement ceci:
import logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s",
handlers=[
logging.FileHandler("{0}/{1}.log".format(logPath, fileName)),
logging.StreamHandler()
])
(Ou avec import sys
+ StreamHandler(sys.stdout)
selon les exigences de la question d'origine.)
Pour obtenir l'enregistreur, utilisez
logger = logging.getLogger()
Plus tard dans votre script, utilisez logger.info()
pour générer des messages de journalisation utiles.
Ajouter un StreamHandler sans argument va dans stderr au lieu de stdout. Si un autre processus a une dépendance sur le vidage de stdout (c'est-à-dire lors de l'écriture d'un plug-in NRPE), assurez-vous de spécifier explicitement stdout, sinon vous pourriez rencontrer des problèmes inattendus.
Voici un exemple rapide en réutilisant les valeurs supposées et LOGFILE de la question:
import logging
from logging.handlers import RotatingFileHandler
from logging import handlers
import sys
log = logging.getLogger('')
log.setLevel(logging.DEBUG)
format = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
ch = logging.StreamHandler(sys.stdout)
ch.setFormatter(format)
log.addHandler(ch)
fh = handlers.RotatingFileHandler(LOGFILE, maxBytes=(1048576*5), backupCount=7)
fh.setFormatter(format)
log.addHandler(fh)
Lancez basicConfig
avec stream=sys.stdout
comme argument avant de configurer d’autres gestionnaires ou de consigner des messages, ou ajoutez manuellement un StreamHandler
qui envoie les messages à stdout dans le logger racine (ou tout autre enregistreur que vous voulez, d'ailleurs).
Après avoir utilisé le code de Waterboy à plusieurs reprises dans plusieurs packages Python, je l'ai finalement jeté dans un minuscule package autonome Python, que vous pouvez trouver ici:
https://github.com/acschaefer/duallog
Le code est bien documenté et facile à utiliser. Il suffit de télécharger le fichier .py
et de l’inclure dans votre projet ou d’installer le package complet via pip install duallog
.