Подавление нескольких сообщений с одинаковым содержимым в модуле ведения журнала Python AKA log compression
по дизайну, мое приложение иногда производит повторяющиеся ошибки, которые заполняют файл журнала и делают его раздражающим для чтения. Это выглядит так:
WARNING:__main__:CRON10: clock unset or no wind update received in 60 sec -> supressed rrd update
WARNING:__main__:CRON10: clock unset or no wind update received in 60 sec -> supressed rrd update
WARNING:__main__:CRON10: clock unset or no wind update received in 60 sec -> supressed rrd update
WARNING:__main__:CRON10: clock unset or no wind update received in 60 sec -> supressed rrd update
как я могу использовать модуль ведения журнала Python для подавления повторяющихся сообщений и вывода чего-то большего стиля rsyslog (http://www.rsyslog.com/doc/rsconf1_repeatedmsgreduction.html):
WARNING:__main__:CRON10: clock unset or no wind update received in 60 sec -> supressed rrd update
--- The last message repeated 3 times
есть ли способ расширить ведение журнала или мне нужно написать полностью собственный регистратор?
В код, который я использую для ведения журнала:
logging.basicConfig(format='%(asctime)s %(message)s')
logging.basicConfig(level=logging.info)
logger = logging.getLogger(__name__)
hdlr = logging.FileHandler(LOGFILE)
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
есть идеи по этому поводу?
1 ответов
вы можете создать logging.Filter
это будет отслеживать последнюю зарегистрированную запись и отфильтровывать любые повторяющиеся (похожие) записи, что-то вроде:
import logging
class DuplicateFilter(logging.Filter):
def filter(self, record):
# add other fields if you need more granular comparison, depends on your app
current_log = (record.module, record.levelno, record.msg)
if current_log != getattr(self, "last_log", None):
self.last_log = current_log
return True
return False
затем просто добавьте его в регистратор/обработчик вы используете (т. е. hdlr.addFilter(DuplicateFilter())
) или корневой регистратор для фильтрации всех журналов по умолчанию. Вот простой тест:
import logging
logging.warn("my test")
logging.warn("my repeated test")
logging.warn("my repeated test")
logging.warn("my repeated test")
logging.warn("my other test")
logger = logging.getLogger() # get the root logger
logger.addFilter(DuplicateFilter()) # add the filter to it
logging.warn("my test")
logging.warn("my repeated test")
logging.warn("my repeated test")
logging.warn("my repeated test")
logging.warn("my other test")
это будет напечатано:
WARNING:root:my test WARNING:root:my repeated test WARNING:root:my repeated test WARNING:root:my repeated test WARNING:root:my other test WARNING:root:my test WARNING:root:my repeated test WARNING:root:my other test