0

私は次のクラスを持っています:

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

このクラスを使用して、コンソールとファイルにログを記録します(設定されたレベルによって異なります)。問題は、ルートレベルがアドハンドラーをリードしているように見えることです。これを無効にする方法はありますか?ルートレベルをコンソールレベルと同じレベルに設定しましたが、これは機能しません...

何かアドバイス?

よろしくお願いいたします。

JR

4

2 に答える 2

1

コードに見られる問題は、Logクラスをインスタンス化するたびにハンドラーが追加されることです。あなたはおそらくこれを望まないでしょう。

getLogger同じ引数で呼び出された場合は常に同じインスタンスを返し、基本的にシングルトン パターンを実装することに注意してください。したがって、後で呼び出すaddHandlerと、毎回新しいハンドラーが追加されます。

対処方法logging、モジュールレベルでロガーを作成して使用することです。

また、使用は避け__new__ます。あなたの場合、単純な関数を使用できます。また、メソッドはインスタンスを返さないため、Log.closeメソッドが機能しないことに注意してください。したがって、返されたロガーにはそのメソッドがありません。__new__Log

consolehandlerロガーのレベルに関しては、ロガー全体ではなくレベルを設定する理由がわかりません。

于 2013-03-02T12:17:32.070 に答える
0

これは私が作っているモジュールの簡略版です。モジュールには、すべてロギング機能を必要とするいくつかのクラスが含まれています。各クラスは異なるファイルにログを記録し、クラス間でファイルハンドラーレベルを変更することも可能である必要があります(例:ゲームパッドクラス:console.debugとfilehandler.infoおよびMQTTクラス:console infoとfilehandler.debug)。

そのため、ログクラスを設定するのが最も簡単な方法だと思いました。私は通常電子機器を使用していますが、現在はPythonと組み合わせていることを覚えておいてください。ですから、私のスキルはかなり基本的なものです。

#!/bin/env python2.7

将来のインポート部門からオペレーターからインポート*インポートロギングからロギングインポートFileHandlerからロギングインポートStreamHandlerインポートpygameインポートスレッドからpygame.localsインポート*インポートモスキートインポート時間からインポートスリープインポート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 ':main()

于 2013-03-02T20:20:54.127 に答える