Registro em Python - filtre mensagens de log para todos os registradores

8

Eu tenho um projeto em que as ferramentas subjacentes estão registrando e também estou registrando (com diferentes instâncias do registrador).

No entanto, às vezes o criador de logs ao qual não tenho acesso expõe informações que eu gostaria de extrair do log (ou substituir por um espaço reservado).

Existe uma maneira de usar um filtro para fazer isso para todos os criadores de logs python em um projeto?

Aqui está minha configuração de log no 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, meu objetivo final é apenas impedir que certas coisas apareçam nos logs, substituindo-as - se houver alguma outra maneira de fazer isso, fique à vontade para compartilhá-lo.

Obrigado!

OhMad
fonte
Como você inicializa / configura seu log?
Klaus D.
Eu atualizei a pergunta.
Ohmad
Então, sua pergunta é 'como filtrar evento de log ", certo?
pbacterio 23/01

Respostas:

3

Se seu objetivo principal é filtrar dados confidenciais, leia Ocultando dados confidenciais de logs com Python . Você pode implementar a logging.Filterpara impedir o log de alguns registros ou a loggingFormatterpara reduzir apenas partes de registros específicos com uma regex.

Para aplicar as classes de filtros e formatadores a todos os criadores de logs, defina-as na configuração dict e adicione a todos os manipuladores que você possui. Além disso, considere remover qualquer manipulador não descrito, definindo disable_existing_loggers': True. Veja exemplos de formatadores e filtros personalizados nos documentos de registro do Django .

Yann
fonte
2

Acredite ou não, você tem acesso aos loggers dos projetos subjacentes! Como você está no django, Suas configurações podem ser carregadas e o log pode ser inicializado antes que os loggers dos projetos subjacentes sejam instanciados.

Este é um processo de duas etapas. A primeira etapa é identificar o criador de logs que é a fonte da mensagem que você deseja suprimir. Para fazer isso, adicione namea my_formatter:

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

Depois de encontrarmos o nome, podemos definir nosso 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

E agora, como você sabe o nome do criador de logs que está produzindo a mensagem incorreta, podemos anexar o nosso AwesomeFilterao criador de logs:

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 o truque de encontrar o nome do criador de logs para controlar a saída do registro para bibliotecas de terceiros com bastante frequência. Boa sorte!

2ps
fonte
1

Se você deseja propagar a mesma configuração de log para todos os trabalhadores em seu projeto, sugiro criar um arquivo de log em seus utils e depois importá-lo para qualquer lugar para usá-lo em vez de import logging

Se você quiser ter certeza de que sua configuração não está em conflito com outros manipuladores, faça o seguinte

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

Em seguida, basta importar esse logger em todos os seus trabalhadores, em vez de na biblioteca de log

from utils.log import logger

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