繁体   English   中英

将Loggers的消息重定向到sys.stdout和sys.stderr

[英]Redirecting Loggers`messages to sys.stdout and sys.stderr

我刚刚开始学习Python,遇到了我无法解决的问题。 我想将CRITICAL以上的每个级别都重定向到sys.stderr,将WARNING以上的所有内容都重定向到sys.stdout。 我想出了这个脚本...

 import logging import sys print("imported module {}".format(__name__)) class PyLogger(logging.Logger): """Wrapper for logging.Logger to redirect its message to sys.stdout or sys.stderr accordingly """ def __init__(self, *args): super(PyLogger, self).__init__(self, *args) # get Logger logger = logging.getLogger() logger.setLevel(logging.DEBUG) # build Formatter formatter = logging.Formatter(fmt="%(asctime)s:%(name)s %(message)s") # build StreamHandler for sys.stderr error = logging.StreamHandler(stream=sys.stderr) error.setLevel(logging.CRITICAL) error.setFormatter(formatter) logger.addHandler(error) # build StreamHandler for sys.stdin out = logging.StreamHandler(stream=sys.stdout) out.setFormatter(formatter) out.setLevel(logging.WARNING) logger.addHandler(out) def main(): logger = PyLogger() # help(logger) logger.info("INFO") if __name__ == "__main__": main() 

直接运行此脚本时,出现以下错误:

No handlers could be found for logger "<__main__.PyLogger object at 0x105f23c50>"

我到处搜索,许多人说logging.basicConfig()可以完成这项工作,但这对我没有用。

也许你们当中有人可以帮助我。 谢谢!

您的类getLogger logging.Logger子类,因此您不应调用getLogger或将logger当作属性使用。 相反,记录仪self的类里面,而应该直接调整:

import logging
import sys


print("imported module {}".format(__name__))


class PyLogger(logging.Logger):
    """Wrapper for logging.Logger to redirect its message to                                                                                   
    sys.stdout or sys.stderr accordingly """

    def __init__(self, *args):
        super(PyLogger, self).__init__(self, *args)

        #####
        # self *is* the logger!                                                                                                                          
        self.setLevel(logging.DEBUG)

        # build Formatter                                                                                                                      
        formatter = logging.Formatter(fmt="%(asctime)s:%(name)s   %(message)s")

        # build StreamHandler for sys.stderr                                                                                                   
        error = logging.StreamHandler(stream=sys.stderr)
        error.setLevel(logging.CRITICAL)
        error.setFormatter(formatter)

        #####
        # Assign the handler to self
        self.addHandler(error)

        # build StreamHandler for sys.stdin                                                                                                    
        out = logging.StreamHandler(stream=sys.stdout)
        out.setFormatter(formatter)
        out.setLevel(logging.WARNING)

        #####
        # Assign the handler to self
        self.addHandler(out)


def main():
    logger = PyLogger()
    # help(logger)                                                                                                                             
    logger.info("INFO")
    logger.warning("WARN")
    logger.critical("CRIT")


if __name__ == "__main__":
    main()

按预期显示以下内容:

ely@eschaton:~/programming$ python test_logger.py 
imported module __main__
2018-03-01 11:59:41,896:<__main__.PyLogger object at 0x7fa236aa4a50>   WARN
2018-03-01 11:59:41,896:<__main__.PyLogger object at 0x7fa236aa4a50>   CRIT
2018-03-01 11:59:41,896:<__main__.PyLogger object at 0x7fa236aa4a50>   CRIT

请注意,关键消息如何触发两个不同的输出处理程序,因此它出现两次(一次是因为它满足警告级别,一次是关键级别)。

在原始代码中,请注意,您正在__init__内创建一个名为logger的变量,但这未分配给self或任何东西。 当该变量超出__init__函数的范围时,该变量将被销毁,因此任何处理程序的分配都是没有意义的。 另外,因为处理程序并没有分配给self ,但该对象self被引用的 ,稍后将被称为记录器,这就是为什么你看到没有处理的错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM