[Python] 3 types de bibliothèques qui améliorent un peu la sortie des journaux [logzero, loguru, pyrogrus]

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.

Exemple de code

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.

image.png

Comment utiliser logzero

Utiliser avec les paramètres par défaut

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")

Paramètre de niveau de journal de sortie de la console

logzero.loglevel(logging.INFO)

Paramètres de sortie du fichier journal

#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)

Format du journal

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

#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.

image.png

Comment utiliser loguru

Ajouter une destination de sortie de journal

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
)

Mise en page

Vous pouvez colorer le journal en l'écrivant sous la forme « ~~~ </ vert>». Vous pouvez changer la couleur en fonction de la gravité avec <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)

Ajouter une valeur non enregistrée au 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")

Sortie en JSON

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
)

Modifier le niveau de journalisation de l'exception

try:
    raise ValueError("error!")
except ValueError as e:
    logger.opt(exception=True).critical("Modifier le niveau de journalisation de l'exception")

Couleur d'une partie du journal

logger.remove()
logger.add(sys.stderr, format="{time} {level} {message}", level="INFO")
logger.opt(colors=True).info("Colorez le journal<blue>colors</blue>")

Ajouter les informations stockées dans l'enregistrement au journal

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]})")

Sortie de journal ignorant le format

logger.opt(raw=True).info("Sortie de journal ignorant le format\n")

Afficher les informations du parent (appelant) dans le journal

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()

Utiliser des variables uniquement pour le message

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",
        ...
    }
}

paresseux: contrôle l'exécution de fonctions lourdes

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.

image.png

Comment utiliser pylogrus

Sortie de base et sortie dans un fichier

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")

Ajouter un préfixe au message

# [2020-05-31T13:12:14.428Z]    DEBUG [API] DEBUG MESSAGE
#Est sortie comme
logger = logger.withPrefix("[API]")
logger.debug("DEBUG MESSAGE")

Ajouter un champ au message

# [2020-05-31T13:12:14.428Z]     INFO INFO MESSAGE; error_code=404
#Est sortie comme
logger.withFields({'error_code': 404}).info("INFO MESSAGE")

Sortie au format JSON

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")

Résumé

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

[Python] 3 types de bibliothèques qui améliorent un peu la sortie des journaux [logzero, loguru, pyrogrus]
[python] Créer une liste de différents types de caractères
Sortie sous la forme d'un tableau python
Comparaison simple des bibliothèques Python qui exploitent Excel
[Python] Un programme qui compte le nombre de vallées
Python qui fusionne beaucoup d'excellence en un seul Excel
Une comparaison rapide des bibliothèques de test Python et node.js
Super simple: une collection de shells qui produisent des dates
[Python] Un programme qui compare les positions des kangourous.
[python] [Gracenote Web API] Une petite personnalisation de pygn
Bases de python: sortie
[Python] Un programme qui trouve les types d'oiseaux les plus courants
Un ensemble de fichiers de script qui font wordcloud avec Python3
Script Python qui compare le contenu de deux répertoires
[Django] Un simple résumé de la fonction de sortie du journal afin que même les débutants puissent la comprendre.