用 Logging 模塊實現(xiàn)日志記錄的六個配置技巧
一、Logging模塊基礎(chǔ)與日志記錄簡介
Python 的 logging 模塊是處理日志記錄的強大工具。通過它,你可以輕松記錄程序運行時的信息、警告或錯誤。比如,當(dāng)程序出錯時,日志能幫你快速定位問題。
來看一個簡單的例子:
import logging
# 配置日志
logging.basicConfig(level=logging.DEBUG)
# 記錄一條日志
logging.debug("這是一個調(diào)試信息")
運行后,你會在控制臺看到這條日志。這就是 logging 模塊的基本用法!接下來,我們會深入學(xué)習(xí)更多實用技巧哦~
二、配置日志輸出格式的基礎(chǔ)方法
1. 使用 logging.basicConfig() 設(shè)置格式
Python 的 Logging 模塊提供了 basicConfig() 方法,可以快速設(shè)置日志的輸出格式。比如,你想讓日志顯示時間、級別和消息,只需要簡單配置!來看個例子:
import logging
# 配置日志輸出格式
logging.basicConfig(
format="%(asctime)s - %(levelname)s - %(message)s", # 日志格式
level=logging.DEBUG # 日志級別
)
# 輸出日志
logging.debug("這是一個調(diào)試信息")
運行后,你會看到類似這樣的輸出:
2023-10-01 14:30:00,000 - DEBUG - 這是一個調(diào)試信息
2. 添加自定義內(nèi)容到日志
如果你想在日志中加入更多細(xì)節(jié),比如代碼所在的文件名或行號,也可以輕松實現(xiàn)!只需修改 format 參數(shù)即可:
logging.basicConfig(
format="%(asctime)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s",
level=logging.INFO
)
logging.info("這是帶有文件名和行號的日志")
輸出結(jié)果會包含文件名和行號,方便定位問題:
2023-10-01 14:35:00,000 - INFO - example.py:10 - 這是帶有文件名和行號的日志
通過這些基礎(chǔ)配置,你可以讓日志更加清晰易讀!
三、設(shè)置日志級別以控制輸出內(nèi)容
1. 控制日志輸出的“閥門”
在Python中,Logging模塊提供了多種日志級別(DEBUG、INFO、WARNING、ERROR、CRITICAL)。通過設(shè)置不同的日志級別,你可以像調(diào)節(jié)“閥門”一樣控制哪些日志會被記錄下來。比如,調(diào)試時用DEBUG,生產(chǎn)環(huán)境用ERROR。
來看個例子:
import logging
# 設(shè)置日志級別為ERROR
logging.basicConfig(level=logging.ERROR)
logging.debug("這是調(diào)試信息") # 不會輸出
logging.error("這是一個錯誤!") # 會輸出
運行后,只會看到錯誤信息。這是因為我們設(shè)置了日志級別為ERROR,低于這個級別的日志(如DEBUG)就會被忽略掉。是不是很方便?
四、使用文件處理日志輸出的配置技巧
1. 將日志寫入文件
Logging模塊不僅能將日志打印到控制臺,還能輕松寫入文件。只需要設(shè)置FileHandler即可!比如:
import logging
# 創(chuàng)建日志記錄器
logger = logging.getLogger('example_logger')
logger.setLevel(logging.DEBUG)
# 創(chuàng)建文件處理器并設(shè)置級別
file_handler = logging.FileHandler('example.log')
file_handler.setLevel(logging.DEBUG)
# 創(chuàng)建格式化器并添加到處理器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
# 將處理器添加到記錄器
logger.addHandler(file_handler)
# 記錄一條日志
logger.debug("This is a debug message.")
運行后,你會在當(dāng)前目錄下看到一個example.log文件,里面存儲了日志內(nèi)容。
2. 配置日志文件編碼
默認(rèn)情況下,Logging模塊可能會使用系統(tǒng)默認(rèn)編碼(如GBK),這可能導(dǎo)致中文亂碼問題。可以通過設(shè)置encoding參數(shù)解決:
file_handler = logging.FileHandler('example.log', encoding='utf-8')
這樣就能確保日志文件支持UTF-8編碼,完美兼容中文!
3. 日志文件追加模式
如果不想每次運行程序都覆蓋日志文件,可以設(shè)置文件打開模式為追加模式('a'):
file_handler = logging.FileHandler('example.log', mode='a')
這樣,日志會不斷追加到文件末尾,方便長期記錄。
以上就是 Logging 模塊中關(guān)于文件日志輸出的一些小技巧,簡單實用!
五、添加時間旋轉(zhuǎn)功能實現(xiàn)日志輪轉(zhuǎn)
1. 使用TimedRotatingFileHandler實現(xiàn)日志輪轉(zhuǎn)
Python的Logging模塊自帶了一個很強大的工具——TimedRotatingFileHandler,它能按時間自動輪轉(zhuǎn)日志文件。比如每天生成一個新的日志文件,舊的日志會被歸檔。下面是一個簡單的例子:
import logging
from logging.handlers import TimedRotatingFileHandler
import time
# 配置日志輪轉(zhuǎn)
logger = logging.getLogger("timed_logger")
logger.setLevel(logging.DEBUG)
handler = TimedRotatingFileHandler("app.log", when="midnight", interval=1, backupCount=7)
handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
logger.addHandler(handler)
# 測試日志記錄
for _ in range(10):
logger.info("This is a test log.")
time.sleep(1)
這里我們配置了日志每天凌晨輪轉(zhuǎn)一次,保留最近7天的日志文件。
這段代碼展示了如何通過TimedRotatingFileHandler來管理日志文件,確保日志不會無限增長,非常適合長期運行的應(yīng)用程序!
六、實戰(zhàn)案例:為一個小型Web應(yīng)用配置日志系統(tǒng)
1. 配置日志輸出到控制臺和文件
在Web應(yīng)用中,同時將日志輸出到控制臺和文件非常實用。通過logging.handlers模塊可以輕松實現(xiàn):
import logging
from logging.handlers import RotatingFileHandler
logger = logging.getLogger("web_app_logger")
logger.setLevel(logging.DEBUG)
# 控制臺處理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_formatter = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(console_formatter)
# 文件處理器
file_handler = RotatingFileHandler('app.log', maxBytes=1024*1024, backupCount=3)
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(file_formatter)
logger.addHandler(console_handler)
logger.addHandler(file_handler)
這段代碼會將INFO及以上級別的日志打印到控制臺,DEBUG及以上級別的日志保存到文件。
2. 使用時間旋轉(zhuǎn)功能優(yōu)化日志管理
為了讓日志文件按天輪轉(zhuǎn),我們可以用TimedRotatingFileHandler替代RotatingFileHandler:
from logging.handlers import TimedRotatingFileHandler
time_handler = TimedRotatingFileHandler('app.log', when='midnight', interval=1, backupCount=7)
time_handler.setLevel(logging.DEBUG)
time_handler.setFormatter(file_formatter)
logger.addHandler(time_handler)
這樣每天凌晨生成一個新的日志文件,保留最近7天的日志。
3. 添加異常追蹤信息
在處理錯誤時,記錄完整的堆棧信息非常重要:
try:
1 / 0
except ZeroDivisionError as e:
logger.exception("An error occurred: ")
運行后,日志中會包含詳細(xì)的異常堆棧信息,方便排查問題。
4. 自定義日志格式
通過調(diào)整日志格式,可以讓日志更易讀:
custom_formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s')
console_handler.setFormatter(custom_formatter)
file_handler.setFormatter(custom_formatter)
這條格式只顯示時間、級別和消息內(nèi)容,簡潔明了。
5. 使用JSON格式化日志
對于需要與外部系統(tǒng)集成的場景,JSON格式的日志更加友好:
import json
class JsonFormatter(logging.Formatter):
def format(self, record):
log_record = {
"level": record.levelname,
"message": super().format(record),
"timestamp": self.formatTime(record, "%Y-%m-%dT%H:%M:%S")
}
return json.dumps(log_record)
json_handler = logging.StreamHandler()
json_handler.setFormatter(JsonFormatter())
logger.addHandler(json_handler)
這段代碼讓日志以JSON格式輸出,便于解析。
6. 配置日志過濾器
有時我們只想記錄特定模塊的日志,可以通過過濾器實現(xiàn):
class ModuleFilter(logging.Filter):
def filter(self, record):
return 'my_module' in record.name
module_filter = ModuleFilter()
file_handler.addFilter(module_filter)
這樣只有來自my_module的日志會被寫入文件。