ow-me
ow-me

Reputation: 161

Python logging module isolate loggers

IN a Rest API server I am using logging module to logs the script run and to send the result to th client. I am using a logging with a file global handler and a single stream handler. The Http response depends by the number of errors and critical in logger. IN order to count logger and error I am using a custom version of logger.

Inspired by this post I wrote the following code in order to count the times a method is called

def init_logger(lid: str):
    log = MyLogger(str(lid))
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    log.addHandler(ch)
    log.setLevel(logging.DEBUG)
    return log

The problem is that if I init two different logger with different id the counting is overlapped as showed below

log1 = init_logger(1)
log2 = init_logger(2)
log1.info("INFO 1")
print(log2.info.called) -->1

Upvotes: 0

Views: 272

Answers (1)

blues
blues

Reputation: 5185

It doesn't work because using a decorator for this is a horrible way to count logs. What if someone writes a log by using log1.log(logging.INFO, "INFO 1") instead of using the convenience shortcut?

Here is a much better way, which is also how the python documentation proposes to do such things:

import logging
from collections import Counter

def counting_filter(record):
    logger = logging.getLogger(record.name)
    logger.counter[record.levelno] += 1
    return True

def init_logger(lid):
    log = logging.getLogger(str(lid))
    log.counter = Counter() # <-- added this line, but count could be stored anywhere
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    log.addHandler(ch)
    log.setLevel(logging.DEBUG)
    log.addFilter(counting_filter) # <-- added Filter here
    return log

log1 = init_logger(1)
log2 = init_logger(2)

log1.info("info 1")

print(log1.counter[logging.INFO]) # 1
print(log2.counter[logging.INFO]) # 0

Upvotes: 1

Related Questions