multithreading - Python logger prints the same output several times in multithreaded environment -


this question has answer here:

in code, somehow logger prints out events twice, conventional print shows correct number of events.

select 1,2 select 1,2 2013-04-19 18:37:30,618:4561354752 - sqllogger - debug - select 1,2 2013-04-19 18:37:30,618:4561354752 - sqllogger - debug - select 1,2 2013-04-19 18:37:30,618:4565561344 - sqllogger - debug - select 1,2 2013-04-19 18:37:30,618:4565561344 - sqllogger - debug - select 1,2 

it not clear me why same message being published mutliple times in multithreaded situations.

import logging threading import thread  class sqlengine(object):     def __init__(self, db_path):         ch = logging.streamhandler()         ch.setlevel(logging.debug)         formatter = logging.formatter('%(asctime)s:%(thread)d - %(name)s - %(levelname)s - %(message)s')         ch.setformatter(formatter)         self.logger = logging.getlogger('sqllogger')         self.logger.setlevel(logging.debug)         self.logger.addhandler(ch)      def execute(self,sql,):             self.logger.debug(sql)             print sql  class dbworker(thread):     def __init__(self, name):         thread.__init__(self)         self.name = name      def run(self):         db = sqlengine('')         db.execute('select 1,2')  if __name__ == '__main__':     dbworker('thread 1').start()     dbworker('thread 2').start() 

looking @ logger documentation:

loggers never instantiated directly, through module-level function logging.getlogger(name). multiple calls getlogger() same name return reference same logger object.

now constructor calling following code:

ch = logging.streamhandler() self.logger = logging.getlogger('sqllogger') self.logger.addhandler(ch) 

note don't create new logger every sqlengine object, reference same logger instance. means you're adding handler 1 , same logger, hence after creating second object logger has 2 handlers, each of them printing screen.

you we'll need either register 1 handler (for example outside of sqlengine constructor) or call getlogger in __init__ different name every sqlengine instance.


Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -