Ceci est une introduction de la bibliothèque pour la sortie de journal de python. Présentation de trois types d'exemples de code et comment les utiliser, à savoir les bibliothèques logzero, loguru et pyrogrus qui peuvent gérer la sortie du journal plus facilement et plus facilement que la journalisation standard.
Nous avons préparé un exemple de code pour chaque bibliothèque. Veuillez vous y référer avec l'utilisation décrite plus loin.
logzero
Documentation: https://github.com/metachris/logzero, https://logzero.readthedocs.io/en/latest/
Une bibliothèque qui peut être utilisée à la place de la journalisation. Une version facile à utiliser de la journalisation.
from logzero import logger
logger.trace("sample trace level log message")
logger.debug("sample debug level log message")
logger.info("sample info level log message")
logger.warning("sample warn level log message")
logger.error("sample error level log message")
logger.critical("sample critical level log message")
logzero.loglevel(logging.INFO)
#Paramètres de sortie
logzero.logfile(
'/var/log/logzero.log', #Chemin du fichier journal
loglevel=logging.ERROR, #Sortie du niveau de journalisation dans un fichier
maxBytes=1e6, #Taille maximale du fichier
backupCount=3 #Nombre de générations d'anciens fichiers à conserver
)
#Désactiver les paramètres de sortie
logzero.logfile(None)
La partie de % (color) s
à% (end_color) s
est colorée en fonction du niveau de journalisation.
log_format = '%(color)s[%(levelname)1.1s %(asctime)s %(name)s %(module)s %(funcName)s:%(lineno)d]%(end_color)s %(message)s'
formatter = logzero.LogFormatter(fmt=log_format)
logzero.formatter(formatter)
#Créer une instance de journalisation
log_format = '%(color)s[%(levelname)1.1s %(asctime)s %(name)s %(module)s %(funcName)s:%(lineno)d]%(end_color)s %(message)s'
formatter = logzero.LogFormatter(fmt=log_format)
custom_logger = logzero.setup_logger(
name=__name__,
logfile="/var/log/logzero.log",
formatter=formatter,
maxBytes=1000000,
backupCount=3,
level=logging.INFO,
fileLoglevel=logging.ERROR,
disableStderrLogger=False,
)
#Sortie de journal
custom_logger.debug("sample class custom logger debug level log message")
custom_logger.info("sample class custom logger info level log message")
custom_logger.warning("sample class custom logger warn level log message")
custom_logger.error("sample class custom logger error level log message")
loguru
Documentation: https://github.com/Delgan/loguru, https://loguru.readthedocs.io/en/stable/index.html
Il est différent de la journalisation, mais son utilisation est simple et intuitive.
Par défaut, il n'est envoyé qu'à stderr. Si vous voulez sortir dans un fichier, faites logger.add
comme suit.
logger.add("/var/log/loguru_sample2.log")
Paramètres tels que la rotation des journaux
logger.add("file_1.log", rotation="500 MB") #Rotation par taille de fichier
logger.add("file_2.log", rotation="12:00") #Rotation à une heure précise tous les jours
logger.add("file_3.log", rotation="1 week") #Rotation hebdomadaire
logger.add("file_A.log", retention=3) #Détenir 3 générations
logger.add("file_B.log", retention="10 days") #Tenir pendant 10 jours
logger.add("file_Y.log", compression="zip") #Compresser avec zip
Pour les autres paramètres, voir https://loguru.readthedocs.io/en/stable/api/logger.html#file.
Ce logger.add
a des paramètres configurables tels que le niveau de journalisation. Veuillez consulter https://loguru.readthedocs.io/en/stable/api/logger.html?highlight=logger.add#loguru._logger.Logger.add pour plus de détails. * Il est recommandé de définir False pour le diagnostic et la trace arrière.
logger.add(
"/var/log/sample.log",
rotation="12:00",
format=log_format,
diagnose=False,
backtrace=False,
level=LOG_LEVEL
)
Vous pouvez colorer le journal en l'écrivant sous la forme «<level>
.
Les messages du journal sont associés à l'enregistrement. record est un type de dictionnaire, et en incorporant la clé dans le format comme {message}
Il peut être intégré au journal. Quel genre de clé vous avez
https://loguru.readthedocs.io/en/stable/api/logger.html
Voir "The record dict" dans.
log_format = "<green>{time:YYYY-MM-DDTHH:mm:ss}</green> <level>{level} {message}</level>"
#Si vous souhaitez définir la sortie de la console, vous devez d'abord désactiver le paramètre par défaut.
#Ancien enregistreur.Notez que celui ajouté disparaîtra également.
logger.remove()
logger.add(sys.stderr, format=log_format)
Vous pouvez le définir comme un dict supplémentaire au format, comme {extra [extra_value]}
, et le passer comme argument de liaison ou de message.
logger.remove()
log_format = "<green>{time}</green>: <level>{level} {message}</level>: {extra[extra_value]}"
logger.add(
sys.stdout,
format=log_format,
serialize=True
)
logger.bind(extra_value="some_extra_value").info("serialize message 01")
logger.info("serialize message 02", extra_value="some_extra_value")
La sortie peut être json comme serialize = True
.
logger.remove()
log_format = "<green>{time}</green>: <level>{level} {message}</level>"
logger.add(
sys.stdout,
format=log_format,
serialize=True
)
try:
raise ValueError("error!")
except ValueError as e:
logger.opt(exception=True).critical("Modifier le niveau de journalisation de l'exception")
logger.remove()
logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
logger.opt(colors=True).info("Colorez le journal<blue>colors</blue>")
Les messages du journal sont associés à «record». record
est un type de dictionnaire et quel type de clé il a
https://loguru.readthedocs.io/en/stable/api/logger.html
Voir "The record dict" dans.
logger.opt(record=True).info("Ajouter les informations stockées dans l'enregistrement au journal(eg. {record[thread]})")
logger.opt(raw=True).info("Sortie de journal ignorant le format\n")
Les informations d'enregistrement utilisées dans le message du journal sont celles du parent (appelant).
Dans le cas de l'exemple suivant, le journal est généré dans child_func ()
, mais {function" like parent_func
qui affiche les informations du parent dans le journal. `2020-05-30T18: 54: 32.505956 + 0000 INFO } ʻEntrez parent_func.
logger.remove()
logger.add(sys.stderr, format="{time} {level} {message} {function}", level="INFO")
def child_func():
logger.opt(depth=1).info("Afficher les informations relatives aux parents dans le journal")
def parent_func():
child_func()
parent_func()
Normalement, lorsqu'une variable est utilisée dans un message de journal, sa valeur est stockée dans record ['extra']
. Si capture = False
est défini, il ne sera pas stocké.
logger.remove()
logger.add(sys.stderr, format="{time} {level} {message} {function}", level="INFO", serialize=True)
logger.opt(capture=False).info("{dest}Utiliser des variables uniquement pour le message", dest="extra")
Exemple de sortie
# capture=Si faux
{
...
"record": {
...
"extra": {},
...
"message": "Keyword arguments not added to extra dict",
...
}
}
# capture=Si vrai
{
...
"record": {
...
"extra": {"dest": "extra"},
...
"message": "Keyword arguments not added to extra dict",
...
}
}
N'exécutez la fonction que lorsque le loglebel est approprié.
def test_lazy():
print('exec test_razy')
return 'exec test_razy'
logger.remove()
logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
#Le niveau de journal à afficher est réglé sur INFO.
#En ce moment paresseux=False(Défaut), Le journal de niveau DEBUG suivant n'est pas affiché, mais teste_lazy()La fonction sera exécutée.
logger.opt(lazy=False).debug("DEBUG LEVEL LOG: {x}", x=test_lazy())
# lazy=Définissez sur True et utilisez lambda comme suit.
#Dans ce cas, aucun journal n'est sorti et testé_lazy()N'est pas exécuté non plus.
logger.opt(lazy=True).debug("DEBUG LEVEL LOG: {x}", x=lambda: test_lazy())
#Lorsque vous passez au niveau DEBUG et exécutez la même chose que ci-dessous
#Le résultat de l'exécution de lambda est stocké dans x
logger.remove()
logger.add(sys.stderr, format="{time} {level} {message}", level="DEBUG")
logger.opt(lazy=True).debug("DEBUG LEVEL LOG: {x}", x=lambda: test_lazy())
pylogrus
Documentation: https://github.com/vmig/pylogrus
Une bibliothèque qui étend la journalisation afin qu'elle puisse être utilisée comme [logrus] de golang (https://github.com/sirupsen/logrus). L'utilisation de base est la même que le lgging.
Identique à la journalisation sauf que logging.setLoggerClass (PyLogrus)
est exécuté en premier et le TextFormatter de pylogrus est utilisé.
import logging
from pylogrus import PyLogrus, TextFormatter
logging.setLoggerClass(PyLogrus)
logger = logging.getLogger(__name__) # type: PyLogrus
logger.setLevel(logging.DEBUG)
formatter = TextFormatter(datefmt='Z', colorize=True)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)
logger.addHandler(ch)
ch = logging.FileHandler('/var/log/py_logrus_sample2.log')
ch.setLevel(logging.ERROR)
ch.setFormatter(formatter)
logger.addHandler(ch)
logger.debug("DEBUG MESSAGE")
logger.info("INFO MESSAGE")
logger.warning("WARNING MESSAGE")
logger.error("ERROR MESSAGE")
# [2020-05-31T13:12:14.428Z] DEBUG [API] DEBUG MESSAGE
#Est sortie comme
logger = logger.withPrefix("[API]")
logger.debug("DEBUG MESSAGE")
# [2020-05-31T13:12:14.428Z] INFO INFO MESSAGE; error_code=404
#Est sortie comme
logger.withFields({'error_code': 404}).info("INFO MESSAGE")
Utilisez JsonFormatter avec les champs à activer.
enabled_fields = [
('name', 'logger_name'),
('asctime', 'service_timestamp'),
('levelname', 'level'),
('threadName', 'thread_name'),
'message',
('exception', 'exception_class'),
('stacktrace', 'stack_trace'),
'module',
('funcName', 'function')
]
formatter = JsonFormatter(datefmt='Z', enabled_fields=enabled_fields, indent=2, sort_keys=True)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)
logger.addHandler(ch)
logger.debug("DEBUG MESSAGE")
Nous avons introduit trois types: logzero, loguru et pyrogrus. Il existe une journalisation standard en python, mais je pense que vous devriez les utiliser lorsque vous souhaitez facilement générer un bon journal. Personnellement, j'ai trouvé loguru facile à gérer, mais si vous êtes habitué à la journalisation, je vous recommande d'utiliser logzero et pyrogrus.
Recommended Posts