python logger logging same entry numerous times
Asked Answered
G

5

14

I have a such logger initializing function:

def generate_logger():
    import logging
    LOG_FILENAME = os.path.join(PROJECT_DIR, "mylog.log")
    FORMAT = "%(asctime)s : %(message)s"
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    fh = logging.FileHandler(LOG_FILENAME)
    formatter = logging.Formatter(FORMAT)
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    return logger

And at some part of my code I have such exception catching:

logger = generate_logger()
except AttributeError:
    logger.error('Opps we got an error')

Weirdly I get same error written 2 times and it can be caugh only once, once I change logger.error('Opps we got an error') with print "test", I get "test" printed once.

What can be the problem and the solution?

Gibraltar answered 12/8, 2010 at 12:16 Comment(0)
M
15

You are adding a new FileHandler to the root logger every time you call that function: the call to logger.getLogger() without a name argument returns the same logger object every time.

You should call generate_logger() only once and then simply get the same logger object by calling logger.getLogger():

generate_logger()

# .... some time later

log = logger.getLogger()
except AttributeError:
   log.error('Opps we got an error')

(note that you do not need generate_logger() to return a value now)

Marocain answered 17/6, 2011 at 12:12 Comment(0)
R
12

I also faced the same problem and came across this page. Yes, I was also creating multiple handlers. In generate_logger(), you can check if there's any other handlers and delete them.

def generate_logger():
    import logging
    LOG_FILENAME = os.path.join(PROJECT_DIR, "mylog.log")
    FORMAT = "%(asctime)s : %(message)s"
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    # Reset the logger.handlers if it already exists.
    if logger.handlers:
        logger.handlers = []
    fh = logging.FileHandler(LOG_FILENAME)
    formatter = logging.Formatter(FORMAT)
    fh.setFormatter(formatter)
    logger.addHandler(fh)
    return logger
Refreshing answered 21/1, 2012 at 0:37 Comment(0)
G
3

I think you're probably getting two handlers added to the logger somehow. Perhaps at some point an implicit handler is being added.

Gama answered 12/8, 2010 at 12:37 Comment(0)
R
2

You probably have two handlers going to the same resulting log.

How many handlers are you creating? How many times are you executing generate_logger? Each time you execute generate_logger you'll create another handler to the same file, leading to potential duplication.

Runny answered 12/8, 2010 at 12:28 Comment(0)
P
0

use can use singleton design pattern for this:

43 class Singleton(type):
44 """
45 Define an Instance operation that lets clients access its unique
46 instance.
47 """
48
49 def init(cls, name, bases, attrs, **kwargs):
50 super().init(name, bases, attrs)
51 cls._instance = None
52
53 def call(cls, *args, **kwargs):
54 if cls._instance is None:
55 cls._instance = super().call(*args, **kwargs)
56 return cls._instance
57
58
59
60 def _setup_logger(name, log_file, level=logging.INFO):
61 """Function setup as many loggers as you want"""
62
63 handler = logging.FileHandler(log_file)
64 handler.setFormatter(formatter)
65 logger = logging.getLogger(name)
66 logger.setLevel(level)
67 logger.addHandler(handler)
68
69 return logger
70
71 class Logger(metaclass=Singleton):
72
73 def init(self, file_name, level):
74 if not (isinstance(file_name, str) and
75 isinstance(level, int)):
76 raise ValueError("Invalid Args")
77
78 self.log_inf = _setup_logger('inf', file_name+'.inf', level)
79 self.log_err = _setup_logger('err', file_name+'.err', level)

Pechora answered 19/3, 2019 at 9:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.