Python日志模塊Logging使用指北(最新推薦)
Logging
模塊是Python
中一個(gè)很重要的日志模塊,它提供了靈活的日志記錄功能,廣泛應(yīng)用于調(diào)試、運(yùn)行狀態(tài)監(jiān)控、錯(cuò)誤追蹤以及系統(tǒng)運(yùn)維中。相比于簡(jiǎn)單的print()
打印調(diào)試,Logging
支持不同的日志級(jí)別(如DEBUG
、INFO
、WARNING
、ERROR
和CRITICAL
),可將日志輸出到不同位置(如控制臺(tái)、文件、網(wǎng)絡(luò)等),還能自定義日志格式和處理方式,從而更好地滿足實(shí)際項(xiàng)目中的日志管理需求。
相信各位小伙伴在平時(shí)比賽或者項(xiàng)目中寫Python代碼的時(shí)候,肯定會(huì)遇到代碼出現(xiàn)莫名其妙的報(bào)錯(cuò),而我們一時(shí)半會(huì)無法快速定位到問題出在哪里。這時(shí)候,相信很多同學(xué)都會(huì)使用 print()
函數(shù)在代碼的不同地方插入打印輸出來不斷調(diào)試、縮小問題范圍。雖然這種方式簡(jiǎn)單粗暴,在小項(xiàng)目或調(diào)試時(shí)確實(shí)能派上用場(chǎng),但隨著項(xiàng)目復(fù)雜度的提高,print()
調(diào)試法就顯得力不從心了。比如,你可能想?yún)^(qū)分調(diào)試信息和錯(cuò)誤信息,或者只在生產(chǎn)環(huán)境中輸出關(guān)鍵日志,還可能需要將日志寫入文件供后續(xù)分析抑或是在找到問題之后還需手動(dòng)刪除各處的調(diào)試 print()
函數(shù),這不僅麻煩,而且很容易遺漏,甚至可能將調(diào)試信息帶到線上環(huán)境,造成信息泄露或日志污染。
因此,學(xué)會(huì)使用專業(yè)的日志工具顯得尤為重要。在Python中,logging
模塊正是官方推薦用于記錄日志的強(qiáng)大工具。它不僅支持不同的日志等級(jí)(如 DEBUG
、INFO
、WARNING
、ERROR
、CRITICAL
),還允許我們將日志靈活地輸出到控制臺(tái)、文件,甚至遠(yuǎn)程服務(wù)器。此外,logging
還支持自定義日志格式和多種處理器組合,能很好地適配各種復(fù)雜應(yīng)用場(chǎng)景。接下來,我們就從最基礎(chǔ)的用法入手,帶你一步步掌握 logging
模塊的強(qiáng)大功能,寫出更專業(yè)、更易維護(hù)的Python代碼?。?!
首先我們要知道,在Logging
模塊中日志根據(jù)作用以及重要程度從小到大依次被分為了如下五個(gè)等級(jí),具體如下表:
日志等級(jí)(level) | 描述 |
---|---|
DEBUG | 調(diào)試信息,通常在診斷問題的時(shí)候使用 |
INFO | 普通信息,確認(rèn)程序按照預(yù)期運(yùn)行 |
WARNING | 警告信息,表示發(fā)生意想不到的事,或者指示接下來可能會(huì)出現(xiàn)一些問題,但是程序還是繼續(xù)運(yùn)行 |
ERROR | 錯(cuò)誤信息,程序運(yùn)行中出現(xiàn)了一些問題,程序某些功能可能不能執(zhí)行 |
CRITICAL | 危險(xiǎn)信息,一個(gè)嚴(yán)重的錯(cuò)誤,導(dǎo)致程序無法繼續(xù)運(yùn)行 |
知道了這些,那我們具體該如何在代碼中實(shí)現(xiàn)日志管理呢?我們接著往下講,首先我們肯定是要在代碼中導(dǎo)入我們的logging
模塊,這個(gè)模塊是Python內(nèi)置的,無需額外安裝,接著我們要引入logging
模塊中的basicConfig
函數(shù),這個(gè)是配置日志系統(tǒng)最常用、最簡(jiǎn)單的一種方式,我們可以通過它來設(shè)置最低顯示的日志等級(jí)、日志的顯示格式、日志輸出位置(默認(rèn)是終端)以及寫入文件的文件名和編碼,接著我們結(jié)合示例來給大家演示一下:
- 最低顯示的日志等級(jí):
從下面的代碼中我們可以看到,我們可以使用level
參數(shù)來設(shè)置日志的最低顯示的等級(jí),而當(dāng)我們?cè)?code>basicConfig中將最低顯示的日志等級(jí)level
設(shè)置為WARNING
的時(shí)候,只有大于 WARNING
的消息才會(huì)被顯示出來
import logging logging.basicConfig( level=logging.WARNING, ) logging.debug("This is a debug message") logging.info("This is an info message") logging.warning("This is a warning message") logging.error("This is an error message") logging.critical("This is a critical message")
- 日志的顯示格式:
除了設(shè)置最低顯示的日志等級(jí)之外,我們還可以使用format
參數(shù)來對(duì)我們的日志顯示格式進(jìn)行設(shè)置,format
有很多可供選擇的占位符,具體的見下表:
format占位符 | 含義說明 |
---|---|
%(asctime)s | 日志事件發(fā)生的時(shí)間(默認(rèn)格式可自定義) |
%(levelname)s | 日志級(jí)別名稱(如 INFO、DEBUG 等) |
%(message)s | 日志內(nèi)容主體(你傳入的日志消息) |
%(name)s | 日志器的名稱(Logger對(duì)象的名字) |
%(filename)s | 當(dāng)前執(zhí)行代碼的文件名 |
%(funcName)s | 調(diào)用日志輸出函數(shù)的函數(shù)名 |
%(lineno)d | 輸出日志的代碼行號(hào) |
%(pathname)s | 當(dāng)前執(zhí)行代碼的完整路徑 |
%(module)s | 模塊名 |
%(threadName)s | 線程名稱(在多線程應(yīng)用中常用) |
%(process)d | 進(jìn)程 ID(在多進(jìn)程應(yīng)用中常用) |
import logging logging.basicConfig( level=logging.WARNING, format="時(shí)間:%(asctime)s-日志名稱:%(name)s-日志級(jí)別:%(levelname)s-日志信息:%(message)s-文件名:%(filename)s-行號(hào):%(lineno)d" ) logging.debug("This is a debug message") logging.info("This is an info message") logging.warning("This is a warning message") logging.error("This is an error message") logging.critical("This is a critical message")
- 日志輸出位置:
除了將日志信息打印到終端(默認(rèn)行為)以外,我們還可以通過 filename
參數(shù)將日志寫入到指定的文件中。這樣一來,我們就可以保存程序運(yùn)行過程中的所有重要信息,便于后續(xù)排查問題或?qū)ο到y(tǒng)進(jìn)行日志分析。 我們還可以指定文件的編碼方式,比如使用 utf-8
,以避免中文亂碼等問題。下面我們通過一個(gè)示例將日志寫入文件中:
import logging logging.basicConfig( level=logging.WARNING, format = '[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s', filename='my_log.log', encoding="utf-8" ) logging.debug("This is a debug message") logging.info("This is an info message") logging.warning("This is a warning message") logging.error("This is an error message") logging.critical("This is a critical message")
可以看到,運(yùn)行了這段代碼之后終端沒有輸出了,而在同路徑下生成了一個(gè)我們指定的my_log.log
文件,這個(gè)文件里就有我們需要的日志輸出
如果想每次運(yùn)行都重新生成日志文件,我們可以繼續(xù)加上 filemode='w'
參數(shù)
import logging logging.basicConfig( level=logging.WARNING, format = '[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s', filename='my_log.log', encoding="utf-8", filemode='w' ) logging.debug("This is a debug message") logging.info("This is an info message") logging.warning("This is a warning message") logging.error("This is an error message") logging.critical("This is a critical message")
除此之外,我們也可以給當(dāng)前的日志信息“命個(gè)名”,這在大型項(xiàng)目中非常有用!只需要通過 logging.getLogger("名字")
來創(chuàng)建一個(gè)具名 Logger,你可以根據(jù)模塊、功能、組件的不同給它們起不同的名字,這樣日志輸出的時(shí)候就能快速定位日志是從哪個(gè)部分打印出來的,非常適合團(tuán)隊(duì)協(xié)作和大型工程的調(diào)試分析。
import logging logging.basicConfig( level=logging.WARNING, format = '[%(name)s] [%(asctime)s.%(msecs)03d] [%(levelname)s] %(message)s', ) logger = logging.getLogger("example") logger.debug("This is a debug message") logger.info("This is an info message") logger.warning("This is a warning message") logger.error("This is an error message") logger.critical("This is a critical message")
但是有同學(xué)就要問了:“哥們哥們,如果我既想讓日志在終端顯示,又想把日志寫進(jìn)文件保存下來,該怎么辦呢?”這個(gè)問題非常常見!實(shí)際上,basicConfig
方式雖然簡(jiǎn)單方便,但它本質(zhì)上是對(duì)根日志器(root logger)做一次性配置的,不支持同時(shí)配置多個(gè)輸出目標(biāo)(Handler)。也就是說,如果你想實(shí)現(xiàn)“同時(shí)輸出到終端和文件”,就需要用更靈活的方式——自定義 Logger + Handler + Formatter 的組合配置!
而Handler
是什么呢?Handler
是 logging
模塊中的一個(gè)核心概念,它負(fù)責(zé)將日志消息輸出到指定的目標(biāo),如控制臺(tái)、文件、網(wǎng)絡(luò)等。而 Formatter 則負(fù)責(zé)定義輸出日志的格式。通過組合 Logger
、Handler
和 Formatter
,我們能夠更加靈活地控制日志的輸出方式和格式。我們可以用下圖來進(jìn)行理解
具體的示例如下,我們首先創(chuàng)建一個(gè) logger
對(duì)象,并通過 getLogger
方法為其指定一個(gè)名稱(在這里是 "example_logger"
)。接著,我們使用 setLevel
方法設(shè)置日志的最低輸出級(jí)別為 DEBUG
,這樣所有級(jí)別(包括 DEBUG
、INFO
、WARNING
、ERROR
和 CRITICAL
)的日志都能被處理。然后,我們創(chuàng)建了兩個(gè) Handler
:一個(gè)是 StreamHandler
,用于將日志輸出到控制臺(tái);另一個(gè)是 FileHandler
,用于將日志寫入名為 logfile.log
的文件。接著,我們使用 Formatter
設(shè)置日志輸出的格式,包括日志器名稱、日志時(shí)間、日志級(jí)別和日志信息,最后將這個(gè) Formatter
配置應(yīng)用到兩個(gè) Handler
上。最后,通過 addHandler
方法將這兩個(gè) Handler
添加到 logger
中,這樣我們就能實(shí)現(xiàn)同時(shí)將日志輸出到控制臺(tái)和文件。
import logging logger = logging.getLogger("example_logger") logger.setLevel(logging.DEBUG) # 創(chuàng)建兩個(gè)Handler,分別輸出到控制臺(tái)和文件 console_handler = logging.StreamHandler() # 輸出到控制臺(tái) file_handler = logging.FileHandler("logfile.log", encoding="utf-8") # 輸出到文件 # 創(chuàng)建Formatter并設(shè)置格式 formatter = logging.Formatter( '[%(name)s] [%(asctime)s] [%(levelname)s] %(message)s' ) console_handler.setFormatter(formatter) # 控制臺(tái)Handler設(shè)置Formatter file_handler.setFormatter(formatter) # 文件Handler設(shè)置Formatter # 將Handler添加到Logger中 logger.addHandler(console_handler) logger.addHandler(file_handler) logger.debug("This is a debug message") logger.info("This is an info message") logger.warning("This is a warning message") logger.error("This is an error message") logger.critical("This is a critical message")
我們運(yùn)行下這段代碼可以發(fā)現(xiàn)不僅終端有輸出,我們的日志文件里面也有記錄:
到此這篇關(guān)于Python日志模塊Logging使用指北的文章就介紹到這了,更多相關(guān)Python日志模塊Logging內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python中axis=0與axis=1指的方向有什么不同詳解
對(duì)數(shù)據(jù)進(jìn)行操作時(shí),經(jīng)常需要在橫軸方向或者數(shù)軸方向?qū)?shù)據(jù)進(jìn)行操作,這時(shí)需要設(shè)定參數(shù)axis的值,下面這篇文章主要給大家介紹了關(guān)于Python中axis=0與axis=1指的方向有什么不同的相關(guān)資料,需要的朋友可以參考下2024-01-01淺談flask中的before_request與after_request
這篇文章主要介紹了淺談flask中的before_request與after_request,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01關(guān)于pycharm?python3.7成功安裝dlib庫(kù)的問題
這篇文章主要介紹了pycharm?python3.7成功安裝dlib庫(kù)的解決方法,本文分步驟給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12Python實(shí)現(xiàn)K-近鄰算法的示例代碼
k-近鄰算法(K-Nearest Neighbour algorithm),又稱 KNN 算法,是數(shù)據(jù)挖掘技術(shù)中原理最簡(jiǎn)單的算法。本文將介紹實(shí)現(xiàn)K-近鄰算法的示例代碼,需要的可以參考一下2022-09-09python 辦公自動(dòng)化——基于pyqt5和openpyxl統(tǒng)計(jì)符合要求的名單
前幾天接到的一個(gè)需求,因?yàn)閷W(xué)校給的名單是青年大學(xué)習(xí)已學(xué)習(xí)的名單,然而要知道未學(xué)習(xí)的名單只能從所有團(tuán)員中再排查一次,過程相當(dāng)麻煩。剛好我也學(xué)過一些操作辦公軟件的基礎(chǔ),再加上最近在學(xué)pyqt5,所以我決定用python寫個(gè)自動(dòng)操作文件的腳本給她用用。2021-05-05關(guān)于Python的一些學(xué)習(xí)總結(jié)
這篇文章主要介紹了關(guān)于Python的一些總結(jié),希望自己以后在學(xué)習(xí)Python的過程中可以邊學(xué)習(xí)邊總結(jié),就自己之前的學(xué)習(xí)先做以總結(jié),之后將不斷總結(jié)更新2018-05-05Python與MongoDB交互的代碼實(shí)現(xiàn)
Python與MongoDB的交互通常通過pymongo庫(kù)來實(shí)現(xiàn),pymongo是一個(gè)官方的Python驅(qū)動(dòng)程序,用于與MongoDB數(shù)據(jù)庫(kù)進(jìn)行交互,以下是一個(gè)簡(jiǎn)單的示例,具有一定的參考價(jià)值,需要的朋友可以參考下2024-10-10python3+PyQt5 數(shù)據(jù)庫(kù)編程--增刪改實(shí)例
今天小編就為大家分享一篇python3+PyQt5 數(shù)據(jù)庫(kù)編程--增刪改實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-06-06