将 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()
直接运行这个scrip的时候出现如下错误:
No handlers could be found for logger "<__main__.PyLogger object at 0x105f23c50>"
我用谷歌搜索了一下,很多人说 logging.basicConfig() 可以完成这项工作,但对我来说没用。
也许你们中有人可以帮助我。
谢谢!
您的 class subclass 是 logging.Logger
,因此您不应调用 getLogger
或将记录器作为属性进行操作。相反,记录器是self
在class里面,应该直接调整:
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
引用的对象 是 稍后将调用的记录器,这就是为什么你看到关于没有处理程序的错误。
我刚开始学习 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()
直接运行这个scrip的时候出现如下错误:
No handlers could be found for logger "<__main__.PyLogger object at 0x105f23c50>"
我用谷歌搜索了一下,很多人说 logging.basicConfig() 可以完成这项工作,但对我来说没用。
也许你们中有人可以帮助我。 谢谢!
您的 class subclass 是 logging.Logger
,因此您不应调用 getLogger
或将记录器作为属性进行操作。相反,记录器是self
在class里面,应该直接调整:
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
引用的对象 是 稍后将调用的记录器,这就是为什么你看到关于没有处理程序的错误。