This question already has answers here:
Duplicate log output when using Python logging module

(15个答案)


7年前关闭。




在我的代码中,记录器以某种方式将事件打印两次,但是传统的print显示正确的事件数。
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

对我来说还不清楚为什么在多线程情况下相同的消息会在多个时间发布。
import logging
from 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()

最佳答案

查看logger文档:



现在,您的构造函数正在调用以下代码:

ch = logging.StreamHandler()
self.logger = logging.getLogger('SQLLogger')
self.logger.addHandler(ch)

请注意,您不会为每个SQLEngine对象创建一个新的记录器,但始终会获得对同一记录器实例的引用。这意味着您总是向同一记录器添加处理程序,因此在创建第二个对象后,记录器有两个处理程序,每个处理程序都打印到屏幕上。

您将只需要注册一个处理程序(例如,在SQLEngine构造函数之外),或为每个getLogger实例调用__init__中的SQLEngine,并为其使用不同的名称。

10-08 09:20