Как подавить или суммировать непоследовательные *дубликаты* сообщения журнала из функции библиотеки Python, вызываемой вPython

Программы на Python
Ответить
Anonymous
 Как подавить или суммировать непоследовательные *дубликаты* сообщения журнала из функции библиотеки Python, вызываемой в

Сообщение Anonymous »

Я использую библиотеку Python, которая регистрирует сообщения с помощью стандартного модуля регистрации. Код библиотеки включает в себя следующее в верхней части модулей:

Код: Выделить всё

import logging
logger = logging.getLogger(__name__)
В своем скрипте я также настроил ведение журнала таким же образом:

Код: Выделить всё

import logging
logger = logging.getLogger(__name__)
Я вызываю библиотечную функцию в цикле. Функция является частью класса и выглядит примерно так:

Код: Выделить всё

class MathOperations:
@classmethod
def square_number(cls, n):
logger.info("You want to square a number.")
logger.warning("Squaring Number")
result = n * n
logger.info(f"Result: {result}")
return result
Когда я запускаю этот метод в цикле в своем скрипте:

Код: Выделить всё

for i in range(5):
MathOperations.square_number(i)
Я получаю много сообщений журнала, которые по сути являются дубликатами по содержанию. Из-за этого журналы становятся многословными и трудными для чтения.

Код: Выделить всё

[29/Nov/2024 12:32:27] INFO [library.module_name:9] You want to square a number.
[29/Nov/2024 12:32:27] WARNING [library.module_name:10] Squaring Number
[29/Nov/2024 12:32:27] INFO [library.module_name:12] Result: 0
[29/Nov/2024 12:32:28] INFO [library.module_name:9] You want to square a number.
[29/Nov/2024 12:32:28] WARNING [library.module_name:10] Squaring Number
[29/Nov/2024 12:32:28] INFO [library.module_name:12] Result: 1
[29/Nov/2024 12:32:29] INFO [library.module_name:9] You want to square a number.
[29/Nov/2024 12:32:29] WARNING [library.module_name:10] Squaring Number
[29/Nov/2024 12:32:29] INFO [library.module_name:12] Result: 4
[29/Nov/2024 12:32:30] INFO [library.module_name:9] You want to square a number.
[29/Nov/2024 12:32:30] WARNING [library.module_name:10] Squaring Number
[29/Nov/2024 12:32:30] INFO [library.module_name:12] Result: 9
[29/Nov/2024 12:32:31] INFO [library.module_name:9] You want to square a number.
[29/Nov/2024 12:32:31] WARNING [library.module_name:10] Squaring Number
[29/Nov/2024 12:32:31] INFO [library.module_name:12] Result: 16
Сообщения «Вы хотите возвести число в квадрат». и «Квадратное число» дублируются каждый раз, когда функция вызывается в цикле.
Желаемый вывод журнала:
Я бы хотел, чтобы журналы были суммируются, чтобы уменьшить количество дублирующихся сообщений. В идеале результат должен выглядеть примерно так:

Код: Выделить всё

[29/Nov/2024 12:32:27] INFO [library.module_name:9] You want to square a number.
-- The above message repeated 4 more times --
[29/Nov/2024 12:32:27] WARNING [library.module_name:10] Squaring Number
-- The above message repeated 4 more times --
[29/Nov/2024 12:32:27] INFO [library.module_name:12] Result: 0
[29/Nov/2024 12:32:28] INFO [library.module_name:12] Result: 1
[29/Nov/2024 12:32:29] INFO [library.module_name:12] Result: 4
[29/Nov/2024 12:32:30] INFO [library.module_name:12] Result: 9
[29/Nov/2024 12:32:31] INFO [library.module_name:12] Result: 16
Таким образом, журналы становятся менее загроможденными, и я по-прежнему могу видеть важную информацию без повторяющихся сообщений.
Ограничения:
Я не могу изменить код библиотеки.
Я хочу подавить или суммировать дублирующиеся сообщения журнала только из библиотеки при вызове в цикле.
Я предпочитаю чтобы свести к минимуму дополнительный код в моем скрипте.
Что я пробовал:
Я пытался создать собственное ведение журнала. Фильтр для подавления повторяющихся сообщений:

Код: Выделить всё

import logging

class SuppressDuplicatesFilter(logging.Filter):
def __init__(self):
super().__init__()
self.logged_messages = set()

def filter(self, record):
message = record.getMessage()
if message in self.logged_messages:
return False  # Suppress
else:
self.logged_messages.add(message)
return True  # Allow

def enable_duplicate_suppression():
library_logger = logging.getLogger('library.module_name')
suppress_filter = SuppressDuplicatesFilter()
library_logger.addFilter(suppress_filter)
# Store for later removal
enable_duplicate_suppression.filter = suppress_filter

def disable_duplicate_suppression():
library_logger = logging.getLogger('library.module_name')
suppress_filter = enable_duplicate_suppression.filter
library_logger.removeFilter(suppress_filter)
del enable_duplicate_suppression.filter

enable_duplicate_suppression()

for i in range(5):
MathOperations.square_number(i)

disable_duplicate_suppression()
Однако это, похоже, не работает — повторяющиеся сообщения журнала по-прежнему появляются в журналах.
Я также попробовал улучшить фильтр, чтобы подсчитать дубликаты и записать сводку:

Код: Выделить всё

class SummarizingFilter(logging.Filter):
def __init__(self):
super().__init__()
self.last_message = None
self.repeat_count = 0

def filter(self, record):
message = record.getMessage()
if message == self.last_message:
self.repeat_count += 1
return False  # Suppress
else:
if self.repeat_count > 0:
# Log a summary of the repeated message
summary = f'"{self.last_message}" repeated {self.repeat_count} times'
#? How to log this appropriately?
self.last_message = message
self.repeat_count = 0
return True  # Allow
Но я не уверен, какой подход я упустил, чтобы это заработало, и как правильно регистрировать сводное сообщение, чтобы оно отображалось в журналах с правильным форматированием и именем регистратора. .
Как я могу эффективно подавлять или суммировать повторяющиеся сообщения журнала, даже если они не являются последовательными, из библиотечной функции при вызове в цикле без изменения кода библиотеки? Возможно, настроив модуль журналирования?
Дополнительная информация:
Имена журналов библиотеки основаны на путях к их модулям (например, 'library.module_name' ).
Я готов применить фильтр к корневому регистратору, если это необходимо, при условии, что это не мешает другим протоколам.
Мне нужно решение, которое работает со стандартным модулем журналирования, поскольку я не могу изменить настройка ведения журнала библиотеки.
После активации подавления дубликатов может случиться так, что каждый новый уникальный журнал будет пропущен, но тогда, если он был просмотрен раньше, он не разрешается и просто сохраняется. Затем, когда подавление дубликатов отключено, дубликаты освобождаются (каждый в виде одной строки).
Аналогичный вопрос SO:
Подавите несколько сообщений с одинаковым содержимым в модуле журналирования Python. Сжатие журналов AKA
Я просмотрел вышеизложенное, но не думаю, что оно охватывает то, что я ищу: оно будет подавлять только журналы, которые немедленно и последовательно дублируются. . Хотя я хотел бы скрыть и суммировать, даже если одно и то же предупреждение регистрируется непоследовательно.
Спасибо за вашу помощь!

Подробнее здесь: https://stackoverflow.com/questions/792 ... from-a-pyt
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»