Python logging: print message only once
Define a filter which keeps track of what was logged, and attach it to your logger for the duration of the loop. This example will remember each message it sees, and only allow the first occurrence to be logged.
class DuplicateFilter(object):
def __init__(self):
self.msgs = set()
def filter(self, record):
rv = record.msg not in self.msgs
self.msgs.add(record.msg)
return rv
dup_filter = DuplicateFilter()
logger.addFilter(dup_filter)
for i in range(10):
canned_example()
logger.removeFilter(dup_filter)
This is a modified variant of @chepner's answer. I had some issues getting it to work when the thing logged wasn't a string (i.e. an exception) and wanted to make use of context managers to more conveniently add and remove the filter:
class DuplicateFilter:
"""
Filters away duplicate log messages.
Modified version of: https://stackoverflow.com/a/31953563/965332
"""
def __init__(self, logger):
self.msgs = set()
self.logger = logger
def filter(self, record):
msg = str(record.msg)
is_duplicate = msg in self.msgs
if not is_duplicate:
self.msgs.add(msg)
return not is_duplicate
def __enter__(self):
self.logger.addFilter(self)
def __exit__(self, exc_type, exc_val, exc_tb):
self.logger.removeFilter(self)
Usage:
logger = logging.getLogger(__name__)
with DuplicateFilter(logger):
for _ in range(5):
logger.info("This will only show up once!")
logger.error(Exception("So will this!")) # This didn't work in @chepner's example