Python logging - фильтровать сообщения журнала для всех регистраторов - PullRequest
8 голосов
/ 15 января 2020

У меня есть проект, в котором основные инструменты ведут журнал, и я также веду журнал (с разными экземплярами регистратора).

Однако иногда регистратор, к которому у меня нет доступа, предоставляет информацию, которую я ' Я хотел бы удалить из журнала (или заменить на заполнитель).

Есть ли способ, которым я могу использовать фильтр, чтобы сделать это для все python loggers в проекте?

Вот моя конфигурация регистрации в 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)

Действительно, моя конечная цель - просто предотвратить появление некоторых вещей в журналах, заменив их - если есть какой-то другой способ сделать это, не стесняйтесь поделиться им.

Спасибо!

Ответы [ 3 ]

3 голосов
/ 24 января 2020

Если вашей основной целью является фильтрация конфиденциальных данных, прочитайте Скрытие конфиденциальных данных из журналов с помощью Python. Вы можете либо внедрить logging.Filter для предотвращения регистрации некоторых записей, либо внедрить loggingFormatter для сокращения только определенных c записей записей с помощью регулярного выражения.

Чтобы применить классы фильтров и форматеров ко всем регистраторам, определите их в config dict и добавьте ко всем имеющимся у вас обработчикам. Также рассмотрите возможность удаления любых неописанных обработчиков, установив disable_existing_loggers': True. См. Примеры пользовательских форматеров и фильтров в документации Django .

2 голосов
/ 25 января 2020

Верьте или нет, у вас есть доступ к регистраторам этих базовых проектов! Поскольку вы находитесь в django, ваши настройки могут быть загружены, и регистрация может быть инициализирована, прежде чем будут созданы экземпляры регистраторов этих базовых проектов.

Это двухэтапный процесс. Первый шаг - определить регистратор, который является источником сообщения, которое вы хотите подавить. Чтобы сделать это, добавьте name к my_formatter:

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

Как только мы нашли имя, мы можем определить наш фильтр.

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

И теперь, когда вы знаете имя логгера, который выдает плохое сообщение, мы можем присоединить наш AwesomeFilter к логгеру:

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)

Мы используем способ нахождения имени логгера, чтобы контролировать вывод логирования для сторонние библиотеки довольно часто. Удачи!

1 голос
/ 23 января 2020

Если вы хотите распространить одну и ту же конфигурацию журналирования на всех работников вашего проекта, я предлагаю создать файл регистратора в ваших утилитах, а затем импортировать его везде, чтобы использовать его вместо import logging

Если вы хотите Убедитесь, что ваша конфигурация не конфликтует с другими обработчиками . Вы можете сделать следующее:

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

Затем просто импортируйте этот регистратор во все ваши работники вместо логирования библиотеки

from utils.log import logger

logger.info("Hello world")
...