開發(fā)過程中出現(xiàn)bug是必不可免的,你會怎樣debug董济?從第1行代碼開始看么步清?還是有個文件里面記錄著哪里錯了更方便呢!B采觥尼啡!log日志
Python中有個logging模塊可以完成相關信息的記錄唠梨,在debug時用它往往事半功倍
1. 日志級別
日志一共分成5個等級锦茁,從低到高分別是:
- DEBUG
- INFO
- WARNING
- ERROR
- CRITICAL
說明:
- DEBUG:詳細的信息,通常只出現(xiàn)在診斷問題上
- INFO:確認一切按預期運行
- WARNING:一個跡象表明,一些意想不到的事情發(fā)生了,或表明一些問題在不久的將來(例如。磁盤空間低”)胚吁。這個軟件還能按預期工作撑毛。
- ERROR:更嚴重的問題,軟件沒能執(zhí)行一些功能
- CRITICAL:一個嚴重的錯誤,這表明程序本身可能無法繼續(xù)運行
這5個等級书聚,也分別對應5種打日志的方法: debug 、info 藻雌、warning 雌续、error 、critical胯杭。默認的是WARNING驯杜,當在WARNING或之上時才被跟蹤。
2. 日志輸出
有兩種方式記錄跟蹤做个,一種輸出控制臺鸽心,另一種是記錄到文件中,如日志文件居暖。
2.1顽频、將日志輸出到控制臺
比如,log1.py 如下:
import logging
logging.basicConfig(level=logging.WARNING,
format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
# 開始使用log功能
logging.info('這是 loggging info message')
logging.debug('這是 loggging debug message')
logging.warning('這是 loggging a warning message')
logging.error('這是 an loggging error message')
logging.critical('這是 loggging critical message')
運行結(jié)果
2017-11-06 23:07:35,725 - log1.py[line:9] - WARNING: 這是 loggging a warning message
2017-11-06 23:07:35,725 - log1.py[line:10] - ERROR: 這是 an loggging error message
2017-11-06 23:07:35,725 - log1.py[line:11] - CRITICAL: 這是 loggging critical message
說明
通過logging.basicConfig函數(shù)對日志的輸出格式及方式做相關配置太闺,上面代碼設置日志的輸出等級是WARNING級別糯景,意思是WARNING級別以上的日志才會輸出。另外還制定了日志輸出的格式省骂。
注意蟀淮,只要用過一次log功能再次設置格式時將失效,實際開發(fā)中格式肯定不會經(jīng)常變化钞澳,所以剛開始時需要設定好格式
2.2怠惶、將日志輸出到文件
我們還可以將日志輸出到文件,只需要在logging.basicConfig函數(shù)中設置好輸出文件的文件名和寫文件的模式略贮。
log2.py 如下:
import logging
logging.basicConfig(level=logging.WARNING,
filename='./log.txt',
filemode='w',
format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
# use logging
logging.info('這是 loggging info message')
logging.debug('這是 loggging debug message')
logging.warning('這是 loggging a warning message')
logging.error('這是 an loggging error message')
logging.critical('這是 loggging critical message')
運行效果
python@ubuntu: cat log.txt
2017-11-06 23:10:44,549 - log2.py[line:10] - WARNING: 這是 loggging a warning message
2017-11-06 23:10:44,549 - log2.py[line:11] - ERROR: 這是 an loggging error message
2017-11-06 23:10:44,549 - log2.py[line:12] - CRITICAL: 這是 loggging critical message
2.3甚疟、既要把日志輸出到控制臺仗岖, 還要寫入日志文件
這就需要一個叫作Logger 的對象來幫忙,下面將對他進行詳細介紹览妖,現(xiàn)在這里先學習怎么實現(xiàn)把日志既要輸出到控制臺又要輸出到文件的功能轧拄。
import logging
# 第一步,創(chuàng)建一個logger
logger = logging.getLogger()
logger.setLevel(logging.INFO) # Log等級總開關
# 第二步讽膏,創(chuàng)建一個handler檩电,用于寫入日志文件
logfile = './log.txt'
fh = logging.FileHandler(logfile, mode='a') # open的打開模式這里可以進行參考
fh.setLevel(logging.DEBUG) # 輸出到file的log等級的開關
# 第三步,再創(chuàng)建一個handler府树,用于輸出到控制臺
ch = logging.StreamHandler()
ch.setLevel(logging.WARNING) # 輸出到console的log等級的開關
# 第四步俐末,定義handler的輸出格式
formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# 第五步,將logger添加到handler里面
logger.addHandler(fh)
logger.addHandler(ch)
# 日志
logger.debug('這是 logger debug message')
logger.info('這是 logger info message')
logger.warning('這是 logger warning message')
logger.error('這是 logger error message')
logger.critical('這是 logger critical message')
運行時終端的輸出結(jié)果:
2017-11-06 23:14:04,731 - log3.py[line:28] - WARNING: 這是 logger warning message
2017-11-06 23:14:04,731 - log3.py[line:29] - ERROR: 這是 logger error message
2017-11-06 23:14:04,731 - log3.py[line:30] - CRITICAL: 這是 logger critical message
在log.txt中奄侠,有如下數(shù)據(jù):
2017-11-06 23:14:04,731 - log3.py[line:27] - INFO: 這是 logger info message
2017-11-06 23:14:04,731 - log3.py[line:28] - WARNING: 這是 logger warning message
2017-11-06 23:14:04,731 - log3.py[line:29] - ERROR: 這是 logger error message
2017-11-06 23:14:04,731 - log3.py[line:30] - CRITICAL: 這是 logger critical message
3卓箫、日志格式說明
logging.basicConfig函數(shù)中,可以指定日志的輸出格式format垄潮,這個參數(shù)可以輸出很多有用的信息烹卒,如下:
- %(levelno)s: 打印日志級別的數(shù)值
- %(levelname)s: 打印日志級別名稱
- %(pathname)s: 打印當前執(zhí)行程序的路徑,其實就是sys.argv[0]
- %(filename)s: 打印當前執(zhí)行程序名
- %(funcName)s: 打印日志的當前函數(shù)
- %(lineno)d: 打印日志的當前行號
- %(asctime)s: 打印日志的時間
- %(thread)d: 打印線程ID
- %(threadName)s: 打印線程名稱
- %(process)d: 打印進程ID
- %(message)s: 打印日志信息
在工作中給的常用格式如下:
format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s'
這個格式可以輸出日志的打印時間弯洗,是哪個模塊輸出的旅急,輸出的日志級別是什么,以及輸入的日志內(nèi)容牡整。
日志配置(Django自帶的日志配置)
LOGGING = {
'version': 1,
'disable_existing_loggers': False, # 是否禁用已經(jīng)存在的日志器
'formatters': { # 日志信息顯示的格式
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
},
'simple': {
'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
},
},
'filters': { # 對日志進行過濾
'require_debug_true': { # django在debug模式下才輸出日志
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': { # 日志處理方法
'console': { # 向終端中輸出日志
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'file': { # 向文件中輸出日志
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(os.path.dirname(BASE_DIR), "logs/meiduo.log"), # 日志文件的位置
'maxBytes': 300 * 1024 * 1024,
'backupCount': 10,
'formatter': 'verbose'
},
},
'loggers': { # 日志器
'django': { # 定義了一個名為django的日志器
'handlers': ['console', 'file'], # 可以同時向終端與文件中輸出日志
'propagate': True, # 是否繼續(xù)傳遞日志信息
'level': 'INFO', # 日志器接收的最低日志級別
},
}
}