django logging的StreamHandler的一个小用法
首先先了解下,logging的大致结构,它有一个内置处理器,还有一个django提供的内置记录器。基本上,日志模块就是由这俩组成的,他俩的关系,有点水渠理论的意思。就是说,处理器,和记录器,都是有level的,而他们俩的level,决定了一条日志信息,能否正常输出。比如:
当处理器的level比记录器的level高的时候,日志就是可以正常输出的,反之,日志就会像水渠的水,记录器就会像拦住水渠的大坝,导致日志无法输出。ok,大致就是这个原理了。(纯属个人理解,如有错误,欢迎留言哈)
这是日志的level的级别。对应 1,2,3,4,5 级。5级级别最高。即CRITICAL级别最高。
翻译一下:
- DEBUG:程序调试bug时使用
- INFO:程序正常运行时使用
- ERROR:程序出错误时使用,如:IO操作失败
- CRITICAL:特别严重的问题,导致程序不能再继续运行时使用,如:磁盘空间为空,一般很少使 用
另外,默认情况的是WARNING等级,当在WARNING或WARNING之上等级的才记录日志信息。
正常来说,django的logging模块,一般都是这么用的:
import logging
import sys
# 先搞一个日志对象,这里是可以起名字的,logging.getLogger(),这里传的参数就是日志的名字,不给默认就是root。这就是记录器了。
mylogger = logging.getLogger("mylogger")
# 造一个handler,就是搞一个日志处理器。logging.StreamHandler()这里可以不传参数,不传默认就是sys.stderr。
handler = logging.StreamHandler(stream=sys.stdout)
# 做日志格式
formatter = logging.Formatter('[%(levelname)s] %(message)s')
handler.setFormatter(formatter)
# 设置日志处理器级别
handler.setLevel(logging.DEBUG)
# 将日志处理器和日志记录器组合起来
mylogger.addHandler(handler)
# 设置日志记录器的级别
mylogger.setLevel(logging.DEBUG)
# 然后,就可以打印日志了
mylogger.debug("This is a debug message.")
mylogger.info("Some info message.")
mylogger.warning("A warning.")
这就是一个最简单的日志对象的构造。
如果,想不打印某个级别的日志,可以直接给记录器添加disable参数:
logging.disable(logging.CRITICAL),这里一定注意给定的级别啊!!!这里是相当于不打印给定的日志级别的日志,和比给定日志级别低的日志也不打印了。就拿当下的例子来说,就是所有logging.CRITICAL级别的日志,和比logging.CRITICAL级别低的日志,都不打印了。由于logging.CRITICAL,已经是最高级别的日志了,所以换句话说,就是直接啥日志都不打印了。
所以啊,通常,别直接 import logging 然后 logging.disable(),这样搞事情,这等于是对所有日志对象都给搞事情了。除非你的本意就是去除所有日志的打印,那你可以这么干。但是,基本上如果只是去除某些日志的打印,那么最好,对具体的日志对象,做这样的操作就好了。比如:
mylogger = logging.getLogger("mylogger")
mylogger.disable(logging.DEBUG)
更多关于日志的内容也可以看下这几篇文章:
Python中Logging 日志模块(最详细完整版) - 知乎
logging日志模块配置文件参数详解_myprogram513的博客-CSDN博客_logging.handlers.sysloghandler
【Python基础】Python模块之Logging(四)——常用handlers的使用_修炼_人生的博客-CSDN博客_logging streamhandler
ok,这次主要是对 logging.StreamHandler 这个参数有点新东西,记录一下。
正常来说,我们在使用 logging.StreamHandler() 这个对象的时候,一般是不传参数的,就算传,大多也就是将默认的sys.stderr,改为 sys.stdout。但是最近遇到了一种新传法。
class MyStream(object):
def __init__(self, error_msg):
self.error_msg = error_msg
self.writes = 0
def read(self, size=None):
pass
def write(self, s):
self.writes += 1
error_msg = 'ERRORED %(error)s'
my_stream = MyStream(error_msg=error_msg)
root = logging.getLogger()
old_level = root.level
my_handler = logging.StreamHandler(my_stream)
root.setLevel(logging.INFO)
root.addHandler(my_handler)
root.info('11111111')
assertEqual(my_stream.writes, 1)
基本上对于 logging.StreamHandler() 对象,这里直接造了一个类,传给 logging.StreamHandler()对象了,从当下用例来看,就是用来统计日志调用次数的。貌似,没谁会关心这个......但是,这种用法,确实是很稀奇的,记录一下了。