Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何为自己的日志记录级别编写自己的日志记录方法_Python_Logging - Fatal编程技术网

Python 如何为自己的日志记录级别编写自己的日志记录方法

Python 如何为自己的日志记录级别编写自己的日志记录方法,python,logging,Python,Logging,你好 我想用我自己的方法扩展我的记录器(由logging.getLogger(“rrcheck”)实现),比如: def warnpfx(…): 如何做到最好 我最初的愿望是让一个根记录器将所有内容写入一个文件,并另外命名为logger(“rrcheck”)写入stdout,但后者还应该有一些其他方法和级别。我需要它在一些消息前面加上“!PFXWRN”前缀(但仅限于那些去stdout的消息),并保持其他消息不变。我还想分别为root和命名记录器设置日志记录级别 这是我的代码: class Ch

你好
我想用我自己的方法扩展我的记录器(由logging.getLogger(“rrcheck”)实现),比如:
def warnpfx(…):

如何做到最好

我最初的愿望是让一个根记录器将所有内容写入一个文件,并另外命名为logger(“rrcheck”)写入stdout,但后者还应该有一些其他方法和级别。我需要它在一些消息前面加上“!PFXWRN”前缀(但仅限于那些去stdout的消息),并保持其他消息不变。我还想分别为root和命名记录器设置日志记录级别

这是我的代码:

class CheloExtendedLogger(logging.Logger):
    """
    Custom logger class with additional levels and methods
    """
    WARNPFX = logging.WARNING+1

    def __init__(self, name):
        logging.Logger.__init__(self, name, logging.DEBUG)                

        logging.addLevelName(self.WARNPFX, 'WARNING')

        console = logging.StreamHandler()
        console.setLevel(logging.DEBUG)
        # create formatter and add it to the handlers
        formatter = logging.Formatter("%(asctime)s [%(funcName)s: %(filename)s,%(lineno)d] %(message)s")
        console.setFormatter(formatter)

        # add the handlers to logger
        self.addHandler(console)

        return

    def warnpfx(self, msg, *args, **kw):
        self.log(self.WARNPFX, "! PFXWRN %s" % msg, *args, **kw)


logging.setLoggerClass(CheloExtendedLogger)    
rrclogger = logging.getLogger("rrcheck")
rrclogger.setLevel(logging.INFO)

def test():
    rrclogger.debug("DEBUG message")
    rrclogger.info("INFO message")
    rrclogger.warnpfx("warning with prefix")

test()
这是一个输出函数,lilne数字是错误的:warnpfx而不是test

也许我自己的记录器方法不是最好的?
您建议朝哪个方向(自己的记录器、自己的处理程序、自己的格式化程序等)

如果我想要另一个记录器,如何继续?
不幸的是,日志记录无法注册自己的日志记录程序,因此getLogger(名称)将使用必需的日志记录程序

问候,
Zbigniew

如果您进行检查,您将看到罪魁祸首是
Logger.findCaller
方法,该方法遍历调用堆栈并搜索不在
logging.py
文件中的第一行。因此,您对
CheloExtendedLogger.warnpfx
中的
self.log
的自定义调用注册了错误的行

不幸的是,
logging.py
中的代码不是很模块化,因此修复程序相当难看:您必须自己在子类中重新定义
findCaller
方法,以便它同时考虑
logging.py
文件和记录器所在的文件(请注意,您的文件中不应存在除记录器之外的任何代码,否则结果将再次不准确)。这需要在方法正文中更改一行:

class CheloExtendedLogger(logging.Logger):

    [...]

    def findCaller(self):
        """
        Find the stack frame of the caller so that we can note the source
        file name, line number and function name.
        """
        f = logging.currentframe().f_back
        rv = "(unknown file)", 0, "(unknown function)"
        while hasattr(f, "f_code"):
            co = f.f_code
            filename = os.path.normcase(co.co_filename)
            if filename in (_srcfile, logging._srcfile): # This line is modified.
                f = f.f_back
                continue
            rv = (filename, f.f_lineno, co.co_name)
            break
        return rv
为此,您需要在文件中定义自己的
\srcfile
变量。同样,
logging.py
不使用函数,而是将所有代码放在模块级别,因此您必须再次复制粘贴:

if hasattr(sys, 'frozen'): #support for py2exe
    _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
elif string.lower(__file__[-4:]) in ['.pyc', '.pyo']:
    _srcfile = __file__[:-4] + '.py'
else:
    _srcfile = __file__
_srcfile = os.path.normcase(_srcfile)
好吧,如果你不喜欢编译版本,最后两行就足够了

现在,您的代码按预期工作:

2011-02-10 16:41:48,108 [test: lg.py,16] INFO message
2011-02-10 16:41:48,171 [test: lg.py,17] ! PFXWRN warning with prefix

对于多个logger类,如果您不介意logger名称和logger类之间的依赖关系,您可以创建一个子类
logging.logger
,根据其名称将其调用委托给适当的logger类。可能还有其他更优雅的可能性,但我现在想不出任何可能性。

谢谢DzinX。我又做了一些尝试,看起来像是在调用self。_log而不是self.log使它运行。啊,这是因为
currentframe()
返回调用堆栈上的第四个顶部函数:)它们有多难看:)
2011-02-10 16:41:48,108 [test: lg.py,16] INFO message
2011-02-10 16:41:48,171 [test: lg.py,17] ! PFXWRN warning with prefix