我有以下课程:
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
我使用此类登录控制台和文件(取决于设置级别)。问题是根级别似乎是addhandler的领先者。有没有办法禁用它?现在我将rootlevel设置为与consolelevel相同的级别,但这不起作用......
有什么建议吗?
提前致谢,并表示最诚挚的问候,
JR
答案 0 :(得分:1)
我可以在代码中看到的一个问题是,只要您实例化Log
类,它就会添加更多处理程序。你可能不想要这个。
请记住,getLogger
在使用相同参数调用时始终返回相同的实例,并且基本上它实现了单例模式。
因此,当您稍后调用addHandler
时,它将每次添加一个新的处理程序。
处理logging
的方法是在模块级别创建一个记录器并使用它。
我也避免使用__new__
。在您的情况下,您可以使用一个简单的功能。请注意,您的Log.close
方法不会有效,因为您的__new__
方法未返回Log
个实例,因此返回的记录器没有该方法
关于记录器的级别,我不明白为什么你没有在consolehandler
上设置级别,而是在整个记录器上设置级别。
答案 1 :(得分:0)
这是我正在制作的模块的简化版本。该模块包含一些所有需要日志记录功能的类。每个类都记录到不同的文件,并且还应该可以更改类之间的文件处理程序级别(例如,gamepad类:console.debug和filehandler.info以及MQTT类:console info和filehandler.debug)。
因此我认为设置日志类是最简单的方法。请记住,我通常做电子产品,但现在结合python。所以我的技能非常基本......
#!/bin/env python2.7
来自未来导入部门
来自运营商进口*
导入日志记录
从日志导入FileHandler
从日志导入StreamHandler
导入pygame
导入线程
来自pygame.locals import *
进口蚊子
进口时间
从时间导入睡眠
import sys
类ConsoleFileLogger(object):
# class constructor
def __init__(self, filename, loggername, rootlevel, consolelevel, filelevel):
# logger levels: DEBUG, INFO, WARNING, ERROR, CRITICAL
# define a root logger and set its ROOT logging level
logger = logging.getLogger(loggername)
logger.setLevel(rootlevel)
# define a Handler which writes messages or higher to the sys.stderr (Console)
self.console = logging.StreamHandler()
# set the logging level
self.console.setLevel(consolelevel)
# define a Handler which writes messages to a logfile
self.logfile = logging.FileHandler(filename + '.log')
# set the logging level
self.logfile.setLevel(filelevel)
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s %(levelname)s: %(name)s: %(message)s')
self.console.setFormatter(formatter)
self.logfile.setFormatter(formatter)
# add the handlers to the root logger
logger.addHandler(self.console)
logger.addHandler(self.logfile)
self._logger = logger
# set a net instance of the logger
def set(self):
return self._logger
# Stop and remove the ConsoleFileLogger object
def remove(self):
self._logger.removeHandler(self.console)
self._logger.removeHandler(self.logfile)
self._logfile.FileHandler().close()
类Gamepad():
# 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',logging.DEBUG,logging.DEBUG,logging.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()的