Pythonのlogging.Logger
クラスを継承する基本的なログクラスを使いたいと思います。しかし、継承されたロガーをカスタマイズするために必要な基礎を確立できるように、クラスをどのように構築するべきかはわかりません。logger.Loggingクラスを拡張するには?
これは私がこれまでのところ、私のlogger.py
ファイルにしたものである:
import entity
from core import MyLogger
my_logger = MyLogger("myApp")
def cmd():
my_logger.info("Hello from %s!" % ("__CMD"))
entity.third_party()
entity.another_function()
cmd()
そして、これがentity.py
モジュールです::
import sys
import logging
from logging import DEBUG, INFO, ERROR
class MyLogger(object):
def __init__(self, name, format="%(asctime)s | %(levelname)s | %(message)s", level=INFO):
# Initial construct.
self.format = format
self.level = level
self.name = name
# Logger configuration.
self.console_formatter = logging.Formatter(self.format)
self.console_logger = logging.StreamHandler(sys.stdout)
self.console_logger.setFormatter(self.console_formatter)
# Complete logging config.
self.logger = logging.getLogger("myApp")
self.logger.setLevel(self.level)
self.logger.addHandler(self.console_logger)
def info(self, msg, extra=None):
self.logger.info(msg, extra=extra)
def error(self, msg, extra=None):
self.logger.error(msg, extra=extra)
def debug(self, msg, extra=None):
self.logger.debug(msg, extra=extra)
def warn(self, msg, extra=None):
self.logger.warn(msg, extra=extra)
これがメインmyApp.py
ある
# Local modules
from core import MyLogger
# Global modules
import logging
from logging import DEBUG, INFO, ERROR, CRITICAL
my_logger = MyLogger("myApp.entity", level=DEBUG)
def third_party():
my_logger.info("Initial message from: %s!" % ("__THIRD_PARTY"))
def another_function():
my_logger.warn("Message from: %s" % ("__ANOTHER_FUNCTION"))
メインアプリケーションを実行すると、次のようになります。
2016-09-14 12:40:50,445 | INFO | Initial message from: __THIRD_PARTY!
2016-09-14 12:40:50,445 | INFO | Initial message from: __THIRD_PARTY!
2016-09-14 12:40:50,445 | WARNING | Message from: __ANOTHER_FUNCTION
2016-09-14 12:40:50,445 | WARNING | Message from: __ANOTHER_FUNCTION
2016-09-14 12:40:50,445 | INFO | Hello from __CMD!
2016-09-14 12:40:50,445 | INFO | Hello from __CMD!
おそらく私がロガークラスを適切に設定できなかったため、すべてが2回印刷されます。
--- UPDATE(01):私の目標の明確化---
(1)私はこれを行うことができますので、1つの場所での主なロギング機能をカプセル化したいと思います:
from mylogger import MyLogger
my_logger = MyLogger("myApp")
my_logger.info("Hello from %s!" % ("__CMD"))
(2)私はCustomFormatter
とCustomAdapter
クラスを使用する予定です。このビットはカスタムロギングクラスを必要とせず、すぐにプラグインすることができます。
(3)私はおそらくlogger.info
を傍受、根本的なロガークラス(記録など)のカスタマイズの面で非常に深い行く必要はありません、loggin.debug
など十分なはずです。
だから、戻ってこれらのフォーラムで何度も循環されていますthis python receiptへの参照:
私はLogger Class
を持つとの甘い点を見つけ、それでもFormatters
を割り当てるように構築された関数を使用することができるようにしようとしていますAdapters
などです。したがって、すべてがlogging
モジュールと互換性があります。
class OurLogger(logging.getLoggerClass()):
def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
# Don't pass all makeRecord args to OurLogRecord bc it doesn't expect "extra"
rv = OurLogRecord(name, level, fn, lno, msg, args, exc_info, func)
# Handle the new extra parameter.
# This if block was copied from Logger.makeRecord
if extra:
for key in extra:
if (key in ["message", "asctime"]) or (key in rv.__dict__):
raise KeyError("Attempt to overwrite %r in LogRecord" % key)
rv.__dict__[key] = extra[key]
return rv
--- UPDATE(02):作業中の可能な解決策 ---
私は可能な解決策を実証する簡単なPythonアプリケーションとのレポを作成しました。ピーク時には気をつけて、これを改善してください。
この例では、効果的に継承によってlogging.Logger
クラスとlogging.LogRecord
クラスをオーバーライドする手法を示しています。
ログストリームには、Formatters
またはAdapters
を使用せずに、2つの外部項目が混在しています(funcname
およびusername
)。
なぜあなたはそれをしますか? –
@ JonasWielicki私は、既存の機能に基づいてロギングメカニズムをカプセル化したいと思います。私はカスタムの 'Formatters'、' Handlers'、 'Adapters'などで作業したいと思います。アイデアは、ロギングの言いましたが、私はこれがいつもコミュニティである程度の論争を起こしていることを知っています。私はまだカスタムクラスなどでそれを行う方法があると信じています。私はそれを行う他の**公式**の方法があることを知っています。 – symbolix
私は動作する基本バージョンでレポを作成しました。詳細は 'UPDATE(02)'を参照してください。 – symbolix