Python-Protokollierung - Filterprotokollnachrichten für alle Protokollierer

8

Ich habe ein Projekt, in dem die zugrunde liegenden Tools protokolliert werden, und ich protokolliere auch (mit verschiedenen Logger-Instanzen).

Manchmal macht der Logger, auf den ich keinen Zugriff habe, Informationen verfügbar, die ich aus dem Protokoll entfernen (oder durch einen Platzhalter ersetzen möchte).

Gibt es eine Möglichkeit, einen Filter zu verwenden, um dies für alle Python-Logger in einem Projekt zu tun ?

Hier ist meine Protokollierungskonfiguration in Django:

LOGGING_CONFIG = None
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "my_formatter": {
            "format": "[%(asctime)s] %(message)s",
            "datefmt": "%d/%b/%Y %H:%M:%S",
        },
    },
    "handlers": {
        "console": {
            "level": "DEBUG",
            "class": "logging.StreamHandler",
            "formatter": "my_formatter",
        },
    },
    "loggers": {
        "my_logger": {
            "handlers": ["console"],
            "level": "DEBUG"
        },
    },
}

logging.config.dictConfig(LOGGING)

Mein Endziel ist es, zu verhindern, dass bestimmte Dinge in Protokollen auftauchen, indem ich sie ersetze. Wenn es eine andere Möglichkeit gibt, können Sie sie gerne teilen.

Vielen Dank!

OhMad
quelle
Wie initialisieren / konfigurieren Sie Ihre Protokollierung?
Klaus D.
Ich habe die Frage aktualisiert.
OhMad
Ihre Frage lautet also "Wie
filtere ich ein

Antworten:

3

Wenn Ihr Hauptziel darin besteht, vertrauliche Daten zu filtern, lesen Sie Ausblenden vertraulicher Daten aus Protokollen mit Python . Sie können entweder a implementieren logging.Filter, um die Protokollierung einiger Datensätze zu verhindern, oder a implementieren loggingFormatter, um nur die Teile bestimmter Datensätze mit einem regulären Ausdruck zu reduzieren.

Um die Filter- und Formatierungsklassen auf alle Logger anzuwenden, definieren Sie sie in der dict-Konfiguration und fügen Sie sie zu allen vorhandenen Handlern hinzu. Ziehen Sie auch in Betracht, unbeschriebene Handler durch Festlegen zu entfernen disable_existing_loggers': True. Beispiele für benutzerdefinierte Formatierer und Filter finden Sie in den Django-Protokollierungsdokumenten .

Yann
quelle
2

Ob Sie es glauben oder nicht, Sie haben Zugriff auf die Logger der zugrunde liegenden Projekte! Da Sie sich in Django befinden, können Ihre Einstellungen geladen und die Protokollierung initialisiert werden, bevor die Protokollierer dieser zugrunde liegenden Projekte instanziiert werden.

Dies ist ein zweistufiger Prozess. Der erste Schritt besteht darin, den Logger zu identifizieren, der die Quelle der Nachricht ist, die Sie unterdrücken möchten. Um dies zu tun, fügen Sie namean my_formatter:

    "formatters": {
        "my_formatter": {
            "format": "[%(asctime)s] [%(name)s] %(message)s",
            "datefmt": "%d/%b/%Y %H:%M:%S",
        },
    },

Sobald wir den Namen gefunden haben, können wir unseren Filter definieren.

import logging


class AwesomeFilter(logging.Filter):
    def filter(self, rec):
        if 'sensitive' in rec.msg:
            return 0
        # you may need to filter based on `getMessage()` if
        # you can't find the information in the pre-formatted msg field
        return 1

Und jetzt, da Sie den Namen des Loggers kennen, der die fehlerhafte Nachricht erzeugt, können wir unsere AwesomeFilteran den Logger anhängen :

LOGGING_CONFIG = None
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "my_formatter": {
            "format": "[%(asctime)s] [%(name)s] %(message)s",
            "datefmt": "%d/%b/%Y %H:%M:%S",
        },
    },
    "handlers": {
        "console": {
            "level": "DEBUG",
            "class": "logging.StreamHandler",
            "formatter": "my_formatter",
        },
    },
    "loggers": {
        "my_logger": {
            "handlers": ["console"],
            "level": "DEBUG"
        },
        "name_of_logger_producing_bad_messages": {
            "filters": [ "app.filters.AwesomeFilter", ],
        },
    },
}

logging.config.dictConfig(LOGGING)

Wir verwenden den Trick, den Namen des Loggers zu finden, um die Ausgabe der Protokollierung für Bibliotheken von Drittanbietern ziemlich häufig zu steuern. Viel Glück!

2ps
quelle
1

Wenn Sie dieselbe Protokollierungskonfiguration an alle Mitarbeiter in Ihrem Projekt weitergeben möchten, empfehle ich, eine Protokollierungsdatei in Ihren Dienstprogrammen zu erstellen und diese dann überall zu importieren, um sie stattdessen zu verwenden import logging

Wenn Sie sicherstellen möchten, dass Ihre Konfiguration nicht mit anderen Handlern in Konflikt steht , können Sie wie folgt vorgehen

Datei utils / log.py.

import logging
import os

root = logging.getLogger()
if root.handlers:
    for handler in root.handlers:
        root.removeHandler(handler)]
LOGGING_CONFIG=[your config]
logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger()

Importieren Sie dann einfach diesen Logger in alle Ihre Mitarbeiter, anstatt die Bibliothek zu protokollieren

from utils.log import logger

logger.info("Hello world")
SARA E.
quelle