I have a such logger initializing function:
def generate_logger():
import logging
LOG_FILENA开发者_开发知识库ME = 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.
Regards
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)
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
I think you're probably getting two handlers added to the logger somehow. Perhaps at some point an implicit handler is being added.
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.
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)
精彩评论