Python Logging庫(kù)完全指南
一、為什么要使用Logging?
很多初學(xué)者喜歡用print()調(diào)試,但在實(shí)際項(xiàng)目中會(huì)遇到問題:
- 項(xiàng)目跑起來(lái)后,不能隨意中斷程序查看輸出
- 需要區(qū)分不同重要程度的信息(錯(cuò)誤、警告、普通信息)
- 需要將日志保存到文件方便后續(xù)分析
- 在生產(chǎn)環(huán)境中,需要?jiǎng)討B(tài)調(diào)整日志詳細(xì)程度
這就是Logging庫(kù)存在的意義!
二、快速開始:5分鐘上手
基礎(chǔ)示例
import logging
# 最簡(jiǎn)單的使用方式
logging.basicConfig(level=logging.WARN) # 設(shè)置日志級(jí)別
logging.debug('這是一條debug信息') # 不會(huì)顯示(默認(rèn)級(jí)別更高)
logging.info('這是一條info信息') # 不會(huì)顯示
logging.warning('這是一條warning信息') # 會(huì)顯示√
logging.error('這是一條error信息') # 會(huì)顯示√
logging.critical('這是一條critical信息')# 會(huì)顯示√
理解日志級(jí)別(從低到高)
- DEBUG - 調(diào)試細(xì)節(jié),開發(fā)時(shí)使用
- INFO - 普通信息,確認(rèn)事情按預(yù)期運(yùn)行
- WARNING - 警告,發(fā)生了意外但不影響運(yùn)行
- ERROR - 錯(cuò)誤,部分功能受影響
- CRITICAL - 嚴(yán)重錯(cuò)誤,程序可能崩潰
重要規(guī)則: 只會(huì)顯示設(shè)置級(jí)別及以上的日志!
三、核心配置:讓日志更實(shí)用
1. 配置日志格式和輸出
# 詳細(xì)配置示例
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
filename='app.log', # 輸出到文件
filemode='a', # 追加模式
encoding='utf-8' # 指定UTF-8編碼,解決中文亂碼問題
)
# 使用
logging.info("程序啟動(dòng)")
logging.warning("磁盤空間不足90%")
logging.error("數(shù)據(jù)庫(kù)連接失敗")
2. 常用格式化字段
%(name)s Logger的名字 %(levelname)s 日志級(jí)別 %(message)s 日志內(nèi)容 %(asctime)s 時(shí)間,可指定格式 %(filename)s 文件名 %(funcName)s 函數(shù)名 %(lineno)d 行號(hào)
四、進(jìn)階技巧:模塊化使用
在實(shí)際項(xiàng)目中,我們通常不直接使用logging模塊,而是創(chuàng)建自己的Logger:
1. 創(chuàng)建模塊專用的Logger
# 在每個(gè)模塊中這樣做
import logging
# 創(chuàng)建logger實(shí)例,通常以模塊名命名
logger = logging.getLogger(__name__) # 這是最佳實(shí)踐!
def process_data(data):
logger.debug(f"開始處理數(shù)據(jù),長(zhǎng)度: {len(data)}")
try:
# 你的業(yè)務(wù)邏輯
result = data * 2
logger.info(f"數(shù)據(jù)處理成功,結(jié)果: {result}")
return result
except Exception as e:
logger.error(f"數(shù)據(jù)處理失敗: {str(e)}", exc_info=True)
return None
2. 項(xiàng)目級(jí)別的配置
# config_logging.py - 日志配置文件
import logging
import logging.handlers
import os
def setup_logging():
"""配置項(xiàng)目日志系統(tǒng)"""
# 創(chuàng)建formatter(定義日志格式)
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
# 創(chuàng)建logger
logger = logging.getLogger() # 根logger
logger.setLevel(logging.DEBUG) # 設(shè)置最低級(jí)別
# 控制臺(tái)處理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO) # 控制臺(tái)只顯示INFO及以上
console_handler.setFormatter(formatter)
# 文件處理器
file_handler = logging.FileHandler('app.log')
file_handler.setLevel(logging.DEBUG) # 文件記錄所有DEBUG及以上
file_handler.setFormatter(formatter)
# 按時(shí)間切分的文件處理器(推薦生產(chǎn)環(huán)境使用)
time_handler = logging.handlers.TimedRotatingFileHandler(
'app.log',
when='midnight', # 每天午夜切分
interval=1,
backupCount=7 # 保留7天
)
time_handler.setFormatter(formatter)
# 添加處理器
logger.addHandler(console_handler)
logger.addHandler(file_handler)
# logger.addHandler(time_handler) # 使用這個(gè)替換上面的file_handler
五、實(shí)用場(chǎng)景示例
場(chǎng)景1:Web應(yīng)用日志
import logging
from logging.handlers import RotatingFileHandler
# 創(chuàng)建logger
logger = logging.getLogger('webapp')
logger.setLevel(logging.INFO)
# 按大小滾動(dòng)日志文件(最大10MB,保留5個(gè)備份)
handler = RotatingFileHandler(
'webapp.log',
maxBytes=10*1024*1024, # 10MB
backupCount=5
)
formatter = logging.Formatter(
'%(asctime)s - %(clientip)s - %(user)s - %(message)s'
)
handler.setFormatter(formatter)
logger.addHandler(handler)
# 使用(假設(shè)在請(qǐng)求處理中)
def handle_request(request, user):
# 添加額外信息
extra = {'clientip': request.client_ip, 'user': user}
logger.info('用戶登錄成功', extra=extra)
場(chǎng)景2:不同級(jí)別日志分開存儲(chǔ)
import logging
# 配置不同的處理器
logger = logging.getLogger('myapp')
# 錯(cuò)誤日志單獨(dú)保存
error_handler = logging.FileHandler('errors.log')
error_handler.setLevel(logging.ERROR)
# 所有日志保存
all_handler = logging.FileHandler('all.log')
all_handler.setLevel(logging.DEBUG)
# 設(shè)置格式
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
error_handler.setFormatter(formatter)
all_handler.setFormatter(formatter)
logger.addHandler(error_handler)
logger.addHandler(all_handler)
六、最佳實(shí)踐和小貼士
?應(yīng)該這樣做:
盡早配置日志:在程序入口處配置,不要多處配置
使用getLogger(__name__) :自動(dòng)獲取模塊名作為logger名
合理使用級(jí)別:
- DEBUG:調(diào)試信息
- INFO:關(guān)鍵流程節(jié)點(diǎn)
- WARNING:可預(yù)料的問題
- ERROR:需要關(guān)注的錯(cuò)誤
包含上下文信息:logger.error(f"用戶{user_id}操作失敗")
避免這樣做:
- 不要在所有地方都用根logger
- 不要在日志中記錄敏感信息(密碼、密鑰)
- 不要過(guò)度記錄,避免日志過(guò)大
總結(jié)
Logging庫(kù)看似復(fù)雜,但核心只有幾個(gè)概念:
- Logger - 記錄器(誰(shuí)在記錄)
- Handler - 處理器(記錄到哪里)
- Formatter - 格式化器(怎么記錄)
- Level - 級(jí)別(記錄什么)
到此這篇關(guān)于Python Logging庫(kù)完全指南的文章就介紹到這了,更多相關(guān)Python Logging庫(kù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Python實(shí)現(xiàn)模擬三體運(yùn)動(dòng)的示例代碼
此前所做的一切三體和太陽(yáng)系的動(dòng)畫,都是基于牛頓力學(xué)的,而且直接對(duì)微分進(jìn)行差分化,從而精度非常感人,用不了幾年就得撞一起去。所以本文來(lái)用Python重新模擬一下三體運(yùn)動(dòng),感興趣的可以了解一下2023-03-03
python使用scapy模塊實(shí)現(xiàn)ping掃描的過(guò)程詳解
這篇文章主要介紹了python使用scapy模塊實(shí)現(xiàn)ping掃描的過(guò)程詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
python使用tornado實(shí)現(xiàn)登錄和登出
這篇文章主要為大家詳細(xì)介紹了python使用tornado實(shí)現(xiàn)登錄和登出,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
Python字典循環(huán)添加一鍵多值的用法實(shí)例
今天小編就為大家分享一篇Python字典循環(huán)添加一鍵多值的用法實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
Python中五種不同解析庫(kù)的應(yīng)用與提取速度對(duì)比
這篇文章主要為大家詳細(xì)介紹了Python中五種不同解析庫(kù)的應(yīng)用與提取速度對(duì)比,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-05-05
使用Python實(shí)現(xiàn)為PDF文檔設(shè)置和移除密碼
在數(shù)字化時(shí)代,文檔的安全性變得越來(lái)越重要,特別是對(duì)于包含敏感信息的PDF文件,所以本文主要來(lái)和大家介紹一下如何使用Python實(shí)現(xiàn)為PDF文檔設(shè)置和移除密碼,需要的可以參考下2024-03-03
Python如何使用bokeh包和geojson數(shù)據(jù)繪制地圖
這篇文章主要介紹了Python如何使用bokeh包和geojson數(shù)據(jù)繪制地圖,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
python re正則匹配網(wǎng)頁(yè)中圖片url地址的方法
今天小編就為大家分享一篇python re正則匹配網(wǎng)頁(yè)中圖片url地址的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-12-12

