Python日志:只记录到处理程序n

2024-10-03 02:42:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下课程:

class Log(object):

# class new
#new is used instead of init because __new__ is able to return (where __init__ can't)
def __new__(self, name, consolelevel, filelevel):

    formatter = logging.Formatter('%(asctime)s %(levelname)s: %(name)s: %(message)s')

    #Create consolehandler and set formatting (level is set in the ROOT)
    consolehandler = StreamHandler()
    consolehandler.setFormatter(formatter)

    #Create filehandler, set level and set formatting
    filehandler = FileHandler(name + '.log')
    filehandler.setLevel(filelevel)
    filehandler.setFormatter(formatter)

    #Create the root logger, add console and file logger. Set the rootlevel == consolelevel.
    self.root = logging.getLogger(name)

    #causing me problems....
    self.root.setLevel(consolelevel)

    self.root.addHandler(consolehandler)
    self.root.addHandler(filehandler)
    self.root.propagate = True

    return self.root

# Close the logger object
def close():
    # to be implemented
    pass

我使用这个类来记录控制台和文件(取决于设置的级别)。问题是根级别似乎是addhandlers的前导。有什么方法可以禁用它吗?现在我将rootlevel设置为与consolelevel相同的级别,但这不起作用。。。在

有什么建议吗?在

提前致谢并致以诚挚的问候

JR公司


Tags: andthenameselfnewisformattercreate
2条回答

这是我正在制作的模块的简化版本。该模块包含几个需要日志记录功能的类。每个类都会记录到一个不同的文件中,并且应该可以在类之间更改文件处理程序级别(例如,gamepad类:控制台.debug以及文件处理程序.info和MQTT类:控制台信息和filehandler.debug). 在

因此,我认为建立一个日志类是最简单的方法。请记住,我通常是做电子学的,但现在和python结合了。所以我的技能很基本。。。。在

#!/bin/env python2.7

来自未来进口部 从操作员导入* 导入日志记录 从日志导入文件处理程序 从日志导入StreamHandler 导入pygame 导入线程 从pygame.locals游戏进口* 进口莫斯基托 导入时间 从时间导入睡眠 导入系统

类ConsoleFileLogger(对象):

^{pr2}$

类游戏板():

# class constructor
def __init__(self, mqttgamepad):
    self.logger = ConsoleFileLogger('BaseLogFiles/Gamepad', 'Gamepad', logging.INFO, logging.INFO, logging.INFO).set()

    if joystickcount == 0:
        self.logger.error('No gamepad connected')
    elif joystickcount == 1:
        self.gamepad = pygame.joystick.Joystick(0)
        self.gamepad.init()
        self.logger.debug('Joystick name %s', self.gamepad.get_name())
        self.logger.debug('nb of axes = %s', self.gamepad.get_numaxes())
        self.logger.debug('nb of balls = %s', self.gamepad.get_numballs())
        self.logger.debug('nb of buttons = %s', self.gamepad.get_numbuttons())
        self.logger.debug('nb of mini joysticks = %s', self.gamepad.get_numhats())
    elif joystickcount > 1:
        self.logger.error('only one gamepad is allowed')

def run(self):
    self.logger.debug('gamepad running')

类MQTTClient():

def __init__(self, clientname):
    self.logger = ConsoleFileLogger('BaseLogFiles/MQTT/Pub', clientname, logging.DEBUG, logging.DEBUG, logging.DEBUG).set()
    self.logger.debug('test')

def run(self):
       self.logger.info('Connection MQTT Sub OK')

def main(): logger=ConsoleFileLogger('BaseLogFiles/logControlCenterMain','ControlCenterMain',日志记录.DEBUG, 日志记录.DEBUG, 日志记录.DEBUG).set()

mqttclient = MQTTClient("MQTTClient")
mqttclient.connect()

gamepad = Gamepad(mqttclient)

if gamepad.initialized():
    gamepadthread = threading.Thread(target=gamepad.run)
    gamepadthread.start()

    mqtttpubhread = threading.Thread(target=mqttclient.run)
    mqtttpubhread.start()

logger.info('BaseMain started')

# Monitor the running program for a KeyboardInterrupt exception
# If this is the case all threads and other methods can be closed the correct way :)
while 1:
    try:
        sleep(1)
    except KeyboardInterrupt:
        logger.info('Ctrl-C pressed')
        gamepad.stop()
        mqttclient.stop()
        logger.info('BaseMain stopped')
        sys.exit(0)

如果名称='main': 主()

我在您的代码中看到的一个问题是,每当您实例化Log类时,它会添加更多的处理程序。你可能不想要这个。在

请记住,getLogger使用相同的参数调用时返回的实例总是相同的,并且基本上它实现了singleton模式。 因此,当您稍后调用addHandler时,它每次都会添加一个新的处理程序。在

处理logging的方法是在模块级别创建一个记录器并使用它。在

我也会避免使用__new__。在您的例子中,您可以使用一个简单的函数。请注意,Log.close方法无法工作,因为您的__new__方法不返回Log实例,因此返回的记录器没有该方法。在

关于记录器的级别,我不明白为什么不在consolehandler上设置级别,而是在整个记录器上设置级别。在

相关问题 更多 >