python框架中自定义封装logging,一文解决
为什么需要Logger
刚开始写代码可能使用print
打印输出就够用了,但是print
重定向输出内容非常麻烦,而且无法区分打印日志等级。
而logging
可以设置打印等级,也可以重定向输出到指定日志文件供定位问题使用,也可以同时重定向到输出台,也可以一键开关。
那么又为什么要封装logging
呢,因为封装后的logging
,可以在整个项目中统一使用,而不是每次都去调用配置一次。
Logging基础使用
import logging # 定义日志输出位置,等级,格式等 # logging.basicConfig(filename="test.log", filemode="w", format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG) logging.debug("debug") logging.info("info") logging.warning("warning") logging.error("error") logging.critical("critical") 输出 WARNING:root:warning ERROR:root:error CRITICAL:root:critical
默认情况下,logging
等级为warning,也就是说只打印warning等更高等级的log。
也可以使用basicConfig()
函数设置log的打印路径、写入方式和格式,以及日志等级。
自定义logger
系统中的Logger对象,不能直接被实例化,获取Logger对象的方法getLogger()
,并且这里是使用了单例模式。这里的单例模式并不是说只有一个Logger对象,而是指整个系统只有一个root logger对象,其他logger对象在执行info() error()等方法时实际上调用的都是root logger对象对应的info() error()等方法。可以创建多个Logger对象,但是真正输出日志的是root logger对象。每个logger对象都可以设置一个名字,设置方法logging.getLogger(__name__)
。
logging提供了以下模块和方法:
- Loggers:记录器公开应用程序代码直接使用的接口
- Handlers:处理程序将日志记录(由记录器创建)发送到相应目标
- Filters:过滤器提供更细粒度的工具,用于确定要输出哪些日志记录
- Formatters:格式化程序指定最终输出中日志记录的布局
Loggers
logger对象有三方面的工作
- 向应用程序代码公开几种方法,以便程序可以记录运行时记录信息。
logging.info("info") logging.error("error")
- 根据severrity,即严重性或过滤对象要对哪些日志采取行动。如
logger.setLevel(INFO)
logger = logging.getLogger("mylogger") # 创建logger对象 logger.setLevel(logging.DEBUG) # 写入内容的严重级别
- 将相关日志消息传递给对应的日志处理程序,如传递给handler
Handler
Handler对象负责将适当的日志消息分派给处理程序的指定目标。
Handler对象可以使用addHandler()方法添加零个或者多个handler对象,主要介绍两种handler对象
- StreamHandler
sh = logging.StreamHandler() # 将日志写入控制台 sh.setLevel(logging.DEBUG) # 指定写入内容的严重等级
- FileHandler
fh = logging.FileHandler('test.log') # 将日志写入test.log fh.setLevel(logging.DEBUG) # 指定写入内容的严重等级
可以看到,在上面logger那里进行了一次setLevel
,那为什么在handler这里还要再进行一次setLevel
呢?其实是Logger
中设置的级别决定它将传递给Handler
的消息严重性,而每个Handler
设置的setLevel
决定了该程序将发送出来哪些级别的消息
Fommatters
fommatters对象配置了最终的顺序、结构和日志消息内容
logging.Formmaters.__init__(fmt=None, datefmt=None, style='%') fmt:消息格式 datefmt:时间格式,默认为:%Y-%m-%d %H:%M:%S
自定义封装
import logging class logger: # 1、创建一个logger logger = logging.getLogger('mylogger') logger.setLevel(logging.DEBUG) # 2、创建一个handler,用于写入日志文件 fh = logging.FileHandler('test.log') fh.setLevel(logging.DEBUG) # 再创建一个handler,用于输出到控制台 ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) # 3、定义handler的输出格式(formatter) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 4、给handler添加formatter fh.setFormatter(formatter) ch.setFormatter(formatter) # 5、给logger添加handler logger.addHandler(fh) logger.addHandler(ch)