Nouvelles annonces sur les technologies sans serveur et réseau ainsi que sur le RUM (Real-User Monitoring) dévoilées à la conférence Dash ! Nouvelles annonces dévoilées à la conférence Dash !

Collecte de logs avec Python

Présentation

Utilisez votre enregistreur Python préféré pour écrire des logs dans un fichier sur votre host. Surveillez ensuite le fichier avec l’Agent Datadog pour envoyer vos logs vers Datadog.

Implémentation

Les logs Python sont assez complexes à gérer, principalement à cause des tracebacks. Ils sont divisés en plusieurs lignes, ce qui les rend difficiles à associer à l’événement de log d’origine. Pour répondre à ce cas de figure, nous vous conseillons d’utiliser un formateur JSON lors de l’écriture des logs afin de :

  • Garantir que chaque paramètre stack_trace est correctement associé au bon log
  • Vous assurer que tous les attributs d’un événement de log sont correctement extraits (sévérité, nom de l’enregistreur, nom du thread, etc.)

Vous trouverez ci-dessous des exemples de configuration pour les bibliothèques de journalisation suivantes :

Ajouter des identifiants de trace à vos logs

Si l’APM est activé pour cette application, améliorez la corrélation entre les traces et les logs d’application afin d’ajouter automatiquement des identifiants de trace et de span à vos logs.

Une fois cette opération terminée, le log doit avoir le format suivant :

2019-01-07 15:20:15,972 DEBUG [flask.app] [app.py:100] [dd.trace_id=5688176451479556031 dd.span_id=4663104081780224235] – Il s'agit d'un exemple

Configurez ensuite l’Agent Datadog de façon à collecter les logs Python à partir du fichier.

Écrire les logs dans un fichier

Exemple d’utilisation avec JSON-log-formatter :

import logging

import json_log_formatter

formatter = json_log_formatter.JSONFormatter()

json_handler = logging.FileHandler(filename='/var/log/mon-log.json')
json_handler.setFormatter(formatter)

logger = logging.getLogger('my_json')
logger.addHandler(json_handler)
logger.setLevel(logging.INFO)

logger.info('Sign up', extra={'referral_code': '52d6ce'})

Le fichier de log comprend l’entrée de log suivante (sur une ligne) :

{
    "message": "Sign up",
    "time": "2015-09-01T06:06:26.524448",
    "referral_code": "52d6ce"
}

Exemple d’utilisation avec Python-json-logger :

    import logging
    from pythonjsonlogger import jsonlogger

    logger = logging.getLogger()

    logHandler = logging.StreamHandler()
    formatter = jsonlogger.JsonFormatter()
    logHandler.setFormatter(formatter)
    logger.addHandler(logHandler)

Une fois le gestionnaire configuré, le fichier de log comprend l’entrée de log suivante (sur une ligne) :

{
    "threadName": "MainThread",
    "name": "root",
    "thread": 140735202359648,
    "created": 1336281068.506248,
    "process": 41937,
    "processName": "MainProcess",
    "relativeCreated": 9.100914001464844,
    "module": "tests",
    "funcName": "testFormatKeys",
    "levelno": 20,
    "msecs": 506.24799728393555,
    "pathname": "tests/tests.py",
    "lineno": 60,
    "asctime": ["12-05-05 22:11:08,506248"],
    "message": "testing logging format",
    "filename": "tests.py",
    "levelname": "INFO",
    "special": "value",
    "run": 12
}

Configurer l’Agent Datadog

Créez un fichier conf.yaml dans le répertoire conf.d/python.d/ de l’Agent avec le contenu suivant :

init_config:

instances:

##Section log
logs:

    ## - type (obligatoire) : type de fichier de la source d'entrée de log (tcp/udp/file).
    ##   port / path (obligatoire) : définit le type tcp ou udp du port. Choisit le chemin si le type est défini sur file.
    ##   service (obligatoire) : nom du service propriétaire du log.
    ##   source (obligatoire) : attribut qui définit l'intégration qui envoie les logs.
    ##   sourcecategory (facultatif) : un attribut à valeur multiple. Il peut être utilisé pour préciser l'attribut source.
    ##   tags (facultatif) : ajoute des tags à chaque log recueilli.

  - type: file
    path: <CHEMIN_VERS_LOG_PYTHON>.log
    service: <VOTRE_APPLICATION>
    source: python
    sourcecategory: sourcecode
    # Pour les logs multiligne, s'ils commencent par la date au format aaaa-mm-jj, supprimez la mise en commentaire de la règle de traitement suivante.
    #log_processing_rules:
    #  - type: multi_line
    #    name: new_log_start_with_date
    #    pattern: \d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01])

Redémarrez l’Agent pour prendre en compte les changements de configuration.

Pour aller plus loin