Registro de Python: filtrar mensajes de registro para todos los registradores

8

Tengo un proyecto donde las herramientas subyacentes están registrando, y también estoy registrando (con diferentes instancias de registrador).

Sin embargo, a veces el registrador al que no tengo acceso expone información que me gustaría eliminar del registro (o reemplazar con un marcador de posición).

¿Hay alguna manera de usar un filtro para hacer eso para todos registradores de Python en un proyecto?

Aquí está mi configuración de registro en 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)

Realmente, mi objetivo final es evitar que ciertas cosas aparezcan en los registros reemplazándolos; si hay alguna otra forma de hacerlo, siéntase libre de compartirlo.

¡Gracias!

Oh Mad
fuente
¿Cómo inicializa / configura su registro?
Klaus D.
Actualicé la pregunta.
OhMad
Entonces, su pregunta es "cómo filtrar el evento de registro", ¿verdad?
pbacterio

Respuestas:

3

Si su objetivo principal es filtrar datos confidenciales, lea Ocultar datos confidenciales de registros con Python . Puede implementar una logging.Filterpara evitar el registro de algunos registros o implementar una loggingFormatterpara reducir solo las partes de registros específicos con una expresión regular.

Para aplicar las clases de filtros y formateadores a todos los registradores, defínalos en la configuración dict y agréguelos a todos los controladores que tenga. Además, considere eliminar cualquier controlador no descrito mediante la configuración disable_existing_loggers': True. Vea ejemplos de formateadores y filtros personalizados en los documentos de registro de Django .

Yann
fuente
2

Lo creas o no, ¡tienes acceso a los registradores de los proyectos subyacentes! Debido a que está en django, su configuración se puede cargar y el registro se puede inicializar, antes de que se instalen los registradores de los proyectos subyacentes.

Este es un proceso de dos pasos. El primer paso es identificar el registrador que es la fuente del mensaje que desea suprimir. Para hacer esto, agregue namea my_formatter:

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

Una vez que hayamos encontrado el nombre, podemos definir nuestro filtro.

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

Y ahora, ya que conoce el nombre del registrador que está produciendo el mensaje incorrecto, podemos adjuntar nuestro AwesomeFilteral registrador:

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)

Usamos el truco de encontrar el nombre del registrador para controlar la salida del registro para bibliotecas de terceros con bastante frecuencia. ¡Buena suerte!

2ps
fuente
1

Si desea propagar la misma configuración de registro a todos los trabajadores en su proyecto, sugiero hacer un archivo de registro en sus utilidades y luego importarlo a todas partes para usarlo en lugar de import logging

Si desea asegurarse de que su configuración no está en conflicto con otros controladores , puede hacer lo siguiente

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

Luego, simplemente importe este registrador en todos sus trabajadores en lugar de la biblioteca de registro

from utils.log import logger

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