在最初学习编程的时候,都将想要数据的信息输出在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