logging模块基本介绍及使用
一.什么是 logging 模块
- logging 模块是 Python 自带的标准模块
二.logging 模块有什么作用
- 主要用于输出运行日志
- 可以控制输出日志的等级, 过滤一些重要信息, 不显示大量无关要紧的调试信息
- 日志保存的路径, 可以是输出到终端, 也可以是输出到文件
- 以及文件轮转等等, 日志文件轮转指的是设置保存日志文件个数, 当超过最大日志文件个数, 最早的那个日志文件会被删除
三.logging 模块的使用
1.直接导入 logging 模块
import logging
🍚先进行日志的基本配置
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
level=30,
)
🍚进行日志输出
logging.debug('在大楼使用电子设备')
logging.info('大楼里面使用打火机')
logging.warning('大楼里抽烟')
logging.error('正在大楼里玩火')
logging.critical('拿着手榴弹在大楼里溜达')
''' 输出结果
2020-12-11 19:50:30 PM - root - WARNING - test: 大楼里抽烟
2020-12-11 19:50:30 PM - root - ERROR - test: 正在大楼里玩火
2020-12-11 19:50:30 PM - root - CRITICAL - test: 拿着手榴弹在大楼里溜达
'''
🍚通过日志等级过滤掉了"debug"以及"info"的日志信息 (大于以及等于你设置的那个等级才会输出)
四.logging 模块的四种对象
1.logger : 负责生产日志
logger1 = logging.getLogger('[日志名]')
2.fitter : 过滤日志 (不常用)
玉炉香 红蜡泪 偏照画堂秋思
3.handler : 控制日志输出的位置 (文件or终端)
fh1 = logging.FileHandler(filename='a1.log', encoding='utf-8')
fh2 = logging.FileHandler(filename='a2.log', encoding='utf-8')
sh = logging.StreamHandler()
4.formatter : 控制日志的格式
formatter1 = logging.Formatter(
fmt='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(massage)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
)
属性名称 | 格式 | 说明 |
---|
name | %(name)s | 日志的名称 |
asctime | %(asctime)s | 可读时间,默认格式‘2003-07-08 16:49:45,896’,逗号之后是毫秒 |
filename | %(filename)s | 文件名,pathname的一部分 |
pathname | %(pathname)s | 文件的全路径名称 |
funcName | %(funcName)s | 调用日志多对应的方法名 |
levelname | %(levelname)s | 日志的等级 |
levelno | %(levelno)s | 数字化的日志等级 |
lineno | %(lineno)d | 被记录日志在源码中的行数 |
module | %(module)s | 模块名 |
msecs | %(msecs)d | 时间中的毫秒部分 |
process | %(process)d | 进程的ID |
processName | %(processName)s | 进程的名称 |
thread | %(thread)d | 线程的ID |
threadName | %(threadName)s | 线程的名称 |
relativeCreated | %(relativeCreated)d | 日志被创建的相对时间,以毫秒为单位 |
五.日志字典配置
import os
formatter1_format = '%(asctime)s %(name)s %(filename)s:%(lineno)d %(levelname)s: %(message)s'
formatter2_format = '%(asctime)s %(name)s : %(message)s'
formatter3_format = '%(asctime)s : %(message)s'
logfile_path1 = os.path.join(os.path.dirname(__file__),'a1.log')
logfile_path2 = os.path.join(os.path.dirname(__file__),'a2.log')
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
"formatter1": {
'format': formatter1_format
},
'formatter2': {
'format': formatter2_format
},
'formatter3': {
'format': formatter3_format
},
},
'filters': {},
'handlers': {
'file1_hanlder': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'formatter': 'formatter1',
'filename': logfile_path1,
'encoding': 'utf-8',
},
'file2_hanlder': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'formatter': 'formatter2',
'filename': logfile_path2,
'encoding': 'utf-8',
},
'terminal': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'formatter3'
},
},
'loggers': {
'': {
'handlers': ['file1_hanlder', 'file2_hanlder','terminal'],
'level': 'DEBUG',
'propagate': False,
},
'自定义日志名1': {
'handlers': ['terminal'],
'level': 'DEBUG',
'propagate': False,
},
'自定义日志名2': {
'handlers': ['file2_hanlder','terminal'],
'level': 'INFO',
'propagate': False,
},
},
}
六.导入字典模块来进行使用

🍚先导入"setting.py"以及"logging.config"
import logging.config
from conf import setting
🍚加载配置字典
logging.config.dictConfig(setting.LOGGING_DIC)
🔰测试一:
logger1 = logging.getLogger('自定义日志名1')
logger1.info('派大星向海绵宝宝转账 : $1000000万')
🔰测试二:
logger2 = logging.getLogger('自定义日志名2')
logger2.error('派大星向章鱼哥转账 : $1000000万')
🔰测试三:
logger3 = logging.getLogger('找不到就默认')
logger3.info('派大星向蟹老板转账 : $1000000万')
''' 日志输出结果
2020-12-11 21:13:10,758 : 派大星向海绵宝宝转账 : $1000000万
2020-12-11 21:13:10,758 : 派大星向章鱼哥转账 : $1000000万
2020-12-11 21:13:10,758 : 派大星向蟹老板转账 : $1000000万
'''
七.日志级别的两层关卡
- 第一层是 logger 中设置的日志级别
- 第二层是 handler 中设置的日志级别
🔰当使用"logger_obj.info("XXXX")"/"logger_obj.error("XXXX")"等等这样的功能输入内容的时候
🔰"logger"中的日志等级会进行判断/过滤如果日志级别满足,那么就会被收取到
🔰满足以后会交给"handlers"中你自定义的"handler"日志等级来进行第二次过滤
🔰如果又满足,那么就会被你相应的"handler"功能进行处理
八.日志功能在实际应用中的简单示例
- 以下只是截取了程序的一小段来做演示(倒数第二行为记录日志)
from db import db_handler
from lib import common
def register_interface(name, password, balance=15000):
'''
注册接口.
:param name:用户名
:param password: 密码
:param balance: 确认密码
:return:True,False
'''
user_dic = db_handler.select(name)
if user_dic:
return False, '用户已存在'
else:
user_dic = {'name': name, 'password': password, 'balance': balance,
'locked': False, 'bankflow': [], 'shoppingcart': {}}
db_handler.save(user_dic)
user_logger.info('用户%s注册成功' % name)
return True, '注册成功'