一昼扛,日志模塊介紹
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
執(zhí)行可發(fā)現(xiàn)默認的日志級別是warming
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')
執(zhí)行,在當前文件夾的access.log內(nèi)容如下瓢喉,如圖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產(chǎn)生日志
logger1=logging.getLogger('訪問日志')
#2栓票,F(xiàn)ilter(過濾日志):幾乎不用决左,略
#3,Handle:接收logger傳過來的日志走贪,進行格式化佛猛,可以打印到終端也可以打印到文件
sh=logging.StreamHandler() #打印到終端
sh1=logging.FileHandler('s1.log',encoding='utf-8')
sh2=logging.FileHandler('s2.log',encoding='utf-8')
#4,F(xiàn)ormatter:日志格式()定義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了d銮凇!K踅痢T桨堋!')
logger1.critical('完蛋了E鸢辍>糠伞!L美稹亿傅!')
執(zhí)行結(jié)果:
終端屏幕上會輸出:
2021-08-28 20:33:57 PM - 訪問日志 - WARNING -日志_logging: 可能有bug哦
2021-08-28 20:33:57 PM - 訪問日志 - ERROR -日志_logging: 出bug了!N疗堋?妗!半哟!
2021-08-28 20:33:57 PM - 訪問日志 - CRITICAL -日志_logging: 完蛋了3曷恕!T⒄恰6⒋!
多出個s1文件內(nèi)容:
訪問日志 - -日志_logging: 可能有bug哦
訪問日志 - -日志_logging: 出bug了=淞肌L迥蟆!E雌椤几缭!
多出個s2文件內(nèi)容:
2021-08-28 20:33:57 PM - ERROR - 出bug了!D绰W嗨尽!樟插!
2021-08-28 20:33:57 PM - CRITICAL - 完蛋了T涎蟆!;拼浮L掠А!
注意??
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)的日志的
總結(jié):
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'
# 定義日志輸出格式 結(jié)束
logfile_dir = os.path.dirname(os.path.abspath(__file__)) # log文件的目錄
logfile_name = 'all2.log' # log文件名
# 如果不存在定義的日志目錄就創(chuàng)建一個
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數(shù)據(jù)既寫入文件又打印到屏幕
'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!') # 記錄該文件的運行狀態(tài)
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數(shù)據(jù)既寫入文件又打印到屏幕
'level': 'DEBUG',
'propagate': False, # 向上(更高level的logger)傳遞,如果是true瑞妇,會打印多個父級日志
},
},
}
src.py
from lib import common
def shop():
print('購物稿静。梭冠。。')
def check_balance():
print('查看余額改备。控漠。。')
def transfer_accounts():
print('轉(zhuǎn)賬悬钳。盐捷。。')
log_msg='轉(zhuǎn)賬了一個億'
logger=common.logger_handle('轉(zhuǎn)賬')
logger.debug(log_msg)
def run():
msg='''
1 購物
2 查看余額
3 轉(zhuǎn)賬
'''
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:轉(zhuǎn)賬][src.py:12][DEBUG][轉(zhuǎn)賬了一個億]
執(zhí)行start.py
/usr/local/bin/python3 /Users/sg/PycharmProjects/py-study/ATM/bin/start.py
1 購物
2 查看余額
3 轉(zhuǎn)賬
>>:3
轉(zhuǎn)賬默勾。碉渡。。
1 購物
2 查看余額
3 轉(zhuǎn)賬
>>:[DEBUG][2021-08-28 21:38:54,837][src.py:12]轉(zhuǎn)賬了一個億
# 屏幕上會出現(xiàn)日志
# access.log也會有相同的日志