我想从一个Python的logging.Logger
类继承的基本日志记录类。但是,我不确定我应该如何构建我的类,以便可以建立自定义继承的记录器所需的基础知识。如何扩展logger.Logging类?
这是我在我的logger.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
:
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
模块:
# 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!
一切都打印两次,因为可能我没有正确设置记录器类。
--- UPDATE(01):澄清我的目标 ---
(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
类通过继承的技术。
将两个外部项目混合到日志流中:funcname
和username
,而不使用任何Formatters
或Adapters
。
你为什么要那样做? –
@JonasWielicki我想封装基于现有设施的日志记录机制,我想使用自定义的'Formatters','Handlers','Adapters'等。这个想法是(作为练习)来覆盖所需的位的日志记录。话虽如此,我知道这一直在社区引起一定的争议。我仍然相信有一种方法可以通过自定义类来实现。我知道还有其他**官方的方法。 – symbolix
我创建了一个具有正常工作基本版本的回购协议。请阅读“UPDATE(02)”以获取更多信息。 – symbolix