在最初学习编程的时候,都将想要数据的信息输出在debug窗口中,然后在正式运行环境中,代码都是部署在生产环境中, 如果继续将一些代码运行日志打印在debug窗口也没有多大意义,所以有一个强悍的日志打印库是很有必要的, 在一般的日志类中,在python中系统提供了
logging
模块用于日志打印, 如果了解过C++的log4cpp
库,将会特别容易理解logging
模块
一. 初次尝试
import logging
logging.debug('调试')
logging.info('消息')
logging.warning('警告')
logging.error('错误')
logging.critical('严重的')
# 结果
'''
WARNING:root:警告
ERROR:root:错误
CRITICAL:root:严重
'''
从上面可以发现 日志打印之后默认会显示在控制台中, 并且只打印WARNING
ERROR
CRITICAL
三个级别的日志, 显示格式为日志等级:root:打印内容
,如果想控制日志打印在文件中,并且调整打印的日志格式 或者打印的级别,则需要调整一些配置参数
二. 日志的打印级别
级别 : 值 解释
CRITICAL : 50 # 严重错误, 一般软件会面临崩溃或者没法运行
ERROR : 40 # 软件的部分功能出现文件 一些数据出现错误 请求不合法等等
WARNING : 30 # 发生了一些意外,但是不影响软件的正常运行,
INFO : 20 # 正常运行时打印的数据
DEBUG : 10 # 调试信息,当调试代码时打印的内容,一般在生产环境不会去打印这个级别的日志
NOTSET : 0 # 不设置 默认设置
# 数值越大 级别越高 当用setLevel()设定一个级别后,默认只会输出这个级别和高于这个级别的日志
三. logging类的一些继承关系
Filterer类: 最大的一个父类
Logger类(Filterer): 记录器--不能直接实例化该类 通过logging.getLogger(name)实例化得到单例对象, 提供直接使用的记录器接口
RootLogger类(Logger):
Handler类(Filterer): 处理器--将记录器产生的日志发送到合适的位置(缓冲区/文件/debug窗口...)
StreamHandler类(Handler):
FileHandler类(StreamHandler):
NullHandler类(Handler):
Formatter类: 格式化器--控制格式化日志的布局
Filter类: 过滤器--更高的控制输出日志的级别
LogRecord类: 日志记录的一些属性中间值 包括姓名 等级 使用日志的线程, 日志创建时间等....
LoggerAdapter类: 将日志的上下文传递到日志调用中, 便于在线程切换过程中 保存一些中间值
四. logging类的使用
在使用日志时必须创建日志Logger实例(记录器), 没有创建则默认为name=root的实例 日志级别为'WARN',处理器Handler默认为StreamHandler 输出到标准输出中, Formatter为默认格式'日志等级:root:打印内容'
五. 日志的布局(输出格式)
%(asctime)s: 默认为asc时间格式 '2003-08-08 16:49:45,896'
%(message)s: 日志内容
%(filename)s:日志调用的文件部分路径名称
%(funcName)s:日志调用的函数名
%(levelname)s:日志级别名称
%(levelno)s:日记级别数值。
%(lineno)s:日志调用的源行号
%(module)s:模块名称(可能时部分名称 过长会自动截断)
%(name)s:实例名称
%(process)d: 进程ID
%(thread)d:线程ID
%(processName)s:进程名称
%(threadName)s:线程名称
六. 一个简单的栗子
import logging
import sys
# 设置日志实例名称
logger = logging.getLogger('App')
# 设置日志布局
standard_layout = '%(asctime)s [%(name)s][%(filename)s:%(lineno)d][%(threadName)s:%(thread)d][%(levelname)s] %(message)s'
simple_layout = '%(asctime)s [%(filename)s:%(lineno)d][%(levelname)s] %(message)s'
formatter1 = logging.Formatter(standard_layout)
formatter2 = logging.Formatter(simple_layout)
# 输出文件
file_handler = logging.FileHandler("example.log")
# 将布局设置到处理器中 处理器会按照设置的布局输出格式 否则不输出
file_handler.setFormatter(formatter1)
# 输出到标准输出
console_Handler = logging.StreamHandler(sys.stdout)
console_Handler.formatter = formatter2
# 将两个设置添加到日志处理器
logger.addHandler(file_handler)
logger.addHandler(console_Handler)
# 指定日志的最低输出级别,默认为WARN
logger.setLevel(logging.INFO)
# 测试打印
logger.debug("debug info")
("info info")
logger.warning("warn info")
logger.error("error info")
logger.fatal("fatal info")
logger.critical("critical info")
# 结果
'''
控制台输出
2020-08-25 18:31:54,833 [my_logging.py:32][INFO] info info
2020-08-25 18:31:54,835 [my_logging.py:33][WARNING] warn info
2020-08-25 18:31:54,835 [my_logging.py:34][ERROR] error info
2020-08-25 18:31:54,836 [my_logging.py:35][CRITICAL] fatal info
2020-08-25 18:31:54,837 [my_logging.py:36][CRITICAL] critical info
文件输出
2020-08-25 18:31:54,833 [App][my_logging.py:32][MainThread:14852][INFO] info info
2020-08-25 18:31:54,835 [App][my_logging.py:33][MainThread:14852][WARNING] warn info
2020-08-25 18:31:54,835 [App][my_logging.py:34][MainThread:14852][ERROR] error info
2020-08-25 18:31:54,836 [App][my_logging.py:35][MainThread:14852][CRITICAL] fatal info
2020-08-25 18:31:54,837 [App][my_logging.py:36][MainThread:14852][CRITICAL] critical info
'''
七. THE END