一,日志模块介绍
1,默认日志级别为30(输出到屏幕)
import logging
logging.debug('debug') #10
logging.info('info') #20
logging.warning('warm') #30
logging.error('error') #40
logging.critical('critical') #50
# WARNING:root:warm
# ERROR:root:error
# CRITICAL:root:critical
执行可发现默认的日志级别是warming
图1
2, 日志指定输出到文件
import logging
logging.basicConfig(
filename='access.log',
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',
level=10
)
logging.debug('debug')
logging.info('info')
logging.warning('warm')
logging.error('error')
logging.critical('critical')
执行,在当前文件夹的access.log内容如下,如图1
2021-08-27 12:55:55 PM - root - DEBUG -日志_logging: debug
2021-08-27 12:55:55 PM - root - INFO -日志_logging: info
2021-08-27 12:55:55 PM - root - WARNING -日志_logging: warm
2021-08-27 12:55:55 PM - root - ERROR -日志_logging: error
2021-08-27 12:55:55 PM - root - CRITICAL -日志_logging: critical
二,日志模块的四种角色
import logging
#1,logger产生日志
logger1=logging.getLogger('访问日志')
#2,Filter(过滤日志):几乎不用,略
#3,Handle:接收logger传过来的日志,进行格式化,可以打印到终端也可以打印到文件
sh=logging.StreamHandler() #打印到终端
sh1=logging.FileHandler('s1.log',encoding='utf-8')
sh2=logging.FileHandler('s2.log',encoding='utf-8')
#4,Formatter:日志格式()定义3种不同的日志格式
formatter=logging.Formatter(
fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p'
)
formatter1=logging.Formatter(
fmt='%(name)s - -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p'
)
formatter2=logging.Formatter(
fmt='%(asctime)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p'
)
#5,为handle绑定日志格式
sh.setFormatter(formatter)
sh1.setFormatter(formatter1)
sh2.setFormatter(formatter2)
#6,为logger绑定handle
logger1.addHandler(sh)
logger1.addHandler(sh1)
logger1.addHandler(sh2)
#7,设置日志级别
logger1.setLevel(0)
sh.setLevel(20)
sh1.setLevel(30)
sh2.setLevel(40)
#8,测试
logger1.debug('这是测试debug')
logger1.info('运行正常~')
logger1.warning('可能有bug哦')
logger1.error('出bug了!!!!!')
logger1.critical('完蛋了!!!!!')
执行结果:
终端屏幕上会输出:
2021-08-28 20:33:57 PM - 访问日志 - WARNING -日志_logging: 可能有bug哦
2021-08-28 20:33:57 PM - 访问日志 - ERROR -日志_logging: 出bug了!!!!!
2021-08-28 20:33:57 PM - 访问日志 - CRITICAL -日志_logging: 完蛋了!!!!!
多出个s1文件内容:
访问日志 - -日志_logging: 可能有bug哦
访问日志 - -日志_logging: 出bug了!!!!!
多出个s2文件内容:
2021-08-28 20:33:57 PM - ERROR - 出bug了!!!!!
2021-08-28 20:33:57 PM - CRITICAL - 完蛋了!!!!!
注意⚠️
logger1.setLevel(0)
sh.setLevel(20)
sh1.setLevel(30)
sh2.setLevel(40)
第7步的日志级别中,logger1的日志级别必须比sh,sh1,sh2小,
如果logger1级别为30,要设置sh的级别为10,是输出不了10级别(debug)和20级别(info)的日志的
总结:
1,输出日志logger需要绑定handle绑定终端输出,或者是文件输出(一个输出日志可以绑定给多个handle处理成多个文件)
2,每个handle需要一个日志格式,即handle要绑定formatter(不同的handle可以绑定不同的formatter)
3,formatter需要单独设置
4,日志级别需要设置
三,日志配置
"""
logging配置
"""
import os
import logging.config
# 定义三种日志输出格式 开始
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
# 定义日志输出格式 结束
logfile_dir = os.path.dirname(os.path.abspath(__file__)) # log文件的目录
logfile_name = 'all2.log' # log文件名
# 如果不存在定义的日志目录就创建一个
if not os.path.isdir(logfile_dir):
os.mkdir(logfile_dir)
# log文件的全路径
logfile_path = os.path.join(logfile_dir, logfile_name)
# log配置字典
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': { #standard名字可以随便起,已在上方定义
'format': standard_format
},
'simple': {
'format': simple_format
},
},
'filters': {},
'handlers': {
#打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
#打印到文件的日志,收集info及以上的日志
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
'formatter': 'standard',
'filename': logfile_path, # 日志文件
'maxBytes': 1024*1024*5, # 日志大小 5M
'backupCount': 5,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
},
'loggers': {
#logging.getLogger(__name__)拿到的logger配置
'': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': True, # 向上(更高level的logger)传递
},
},
}
def load_my_logging_cfg():
logging.config.dictConfig(LOGGING_DIC) # 导入上面定义的logging配置
logger = logging.getLogger(__name__) # 生成一个log实例
logger.info('It works!') # 记录该文件的运行状态
if __name__ == '__main__':
load_my_logging_cfg()
四,日志应用(升级ATM)
start.py
import os,sys
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
from core import src
if __name__ == '__main__':
src.run()
setting.py
import os
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 以上路径为/Users/shiheng/PycharmProjects/py-study/ATM
LOG_PATH=os.path.join(BASE_DIR,'log','access.log')
DB_PATH=os.path.join(BASE_DIR,'db','user')
"""
logging配置
"""
import os
import logging.config
# 定义三种日志输出格式 开始
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字
simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'
# log配置字典
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': { #standard名字可以随便起,已在上方定义
'format': standard_format
},
'simple': {
'format': simple_format
},
},
'filters': {},
'handlers': {
#打印到终端的日志
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'simple'
},
#打印到文件的日志,收集info及以上的日志
'default': {
'level': 'DEBUG',
'class': 'logging.handlers.RotatingFileHandler', # 保存到文件
'formatter': 'standard',
'filename': LOG_PATH, # 日志文件
'maxBytes': 1024*1024*5, # 日志大小 5M
'backupCount': 5,
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
},
'loggers': {
#logging.getLogger(__name__)拿到的logger配置
'': {
'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
'level': 'DEBUG',
'propagate': False, # 向上(更高level的logger)传递,如果是true,会打印多个父级日志
},
},
}
src.py
from lib import common
def shop():
print('购物。。。')
def check_balance():
print('查看余额。。。')
def transfer_accounts():
print('转账。。。')
log_msg='转账了一个亿'
logger=common.logger_handle('转账')
logger.debug(log_msg)
def run():
msg='''
1 购物
2 查看余额
3 转账
'''
while True:
print(msg)
choice=input('>>:').strip()
if not choice:continue
if choice == '1':
shop()
elif choice == '2':
check_balance()
elif choice == '3':
transfer_accounts()
common.py
from conf import settings
import logging.config
def logger_handle(log_name):
logging.config.dictConfig(settings.LOGGING_DIC) # 导入上面定义的logging配置
logger = logging.getLogger(log_name) # 生成一个log实例
return logger
accesss.log
[2021-08-28 21:38:40,574][MainThread:4298358080][task_id:转账][src.py:12][DEBUG][转账了一个亿]
执行start.py
/usr/local/bin/python3 /Users/sg/PycharmProjects/py-study/ATM/bin/start.py
1 购物
2 查看余额
3 转账
>>:3
转账。。。
1 购物
2 查看余额
3 转账
>>:[DEBUG][2021-08-28 21:38:54,837][src.py:12]转账了一个亿
# 屏幕上会出现日志
# access.log也会有相同的日志
网友评论