1.概述
python
中的日誌庫logging
使用起來有點像log4j
,但組態通常比較複雜,建置日誌伺服器時也不是方便。標準函式庫logging
的替代品是loguru
#,loguru
使用起來就簡單的多。
loguru
預設的輸出格式是:時間、等級、模組、行號以及日誌內容。 loguru
不需要手動建立logger
,開箱即用,比logging
使用方便得多;另外,日誌輸出內建了彩色功能,顏色和非顏色控制很方便,更友善。
loguru
是非標準函式庫,需要事先安裝,指令是:**pip3 install loguru
****。 **安裝後,最簡單的使用樣例如下:
from loguru import logger logger.debug('hello, this debug loguru') logger.info('hello, this is info loguru') logger.warning('hello, this is warning loguru') logger.error('hello, this is error loguru') logger.critical('hello, this is critical loguru')
上述程式碼輸出:
日誌印到檔案的用法也很簡單,程式碼如下:
from loguru import logger logger.add('myloguru.log') logger.debug('hello, this debug loguru') logger.info('hello, this is info loguru') logger.warning('hello, this is warning loguru') logger.error('hello, this is error loguru') logger.critical('hello, this is critical loguru')
上述程式碼執行時,可以列印到console,也可以列印到檔案中去。
2.常見用法
2.1.顯示格式
loguru
預設格式是時間、等級、名稱模組和日誌內容,其中名稱模組是寫死的,是當前檔案的__name__
變量,最好不要修改此變數。
工程比較複雜的情況下,自訂模組名稱,是非常有用的,容易定界定位,避免陷入細節。我們可以透過logger.configure
手動指定模組名稱。如下如下:
import sys from loguru import logger logger.configure(handlers=[ { "sink": sys.stderr, "format": "{time:YYYY-MM-DD HH:mm:ss.SSS} |<lvl>{level:8}</>| {name} : {module}:{line:4} | <cyan>mymodule</> | - <lvl>{message}</>", "colorize": True }, ]) logger.debug('this is debug') logger.info('this is info') logger.warning('this is warning') logger.error('this is error') logger.critical('this is critical')
handlers
:表示日誌輸出句柄或目的地,sys.stderr
表示輸出到命令列終端。
"sink": sys.stderr
,表示輸出到終端機
"format":
表示日誌格式化。<lvl>{level:8}></lvl>
表示依照日誌等級顯示顏色。 8表示輸出寬度為8個字元。
"colorize":
True
**:表示顯示顏色。
上述程式碼的輸出為:
#這裡寫死了模組名稱,每個日誌都這樣設定也是比較繁瑣。下面會介紹指定不同模組名稱的方法。
2.2.寫入檔案
日誌一般需要持久化,除了輸出到命令列終端機外,還需要寫入檔案。標準日誌庫可以透過設定檔配置logger,在程式碼中也可以實現,但過程比較繁瑣。 loguru相對而已就顯得稍微簡單一些,我們看下在程式碼中如何實現這個功能。日誌程式碼如下:
import sys from loguru import logger logger.configure(handlers=[ { "sink": sys.stderr, "format": "{time:YYYY-MM-DD HH:mm:ss.SSS} |<lvl>{level:8}</>| {name} : {module}:{line:4} | <cyan>mymodule</> | - <lvl>{message}</>", "colorize": True }, { "sink": 'first.log', "format": "{time:YYYY-MM-DD HH:mm:ss.SSS} |{level:8}| {name} : {module}:{line:4} | mymodule | - {message}", "colorize": False }, ]) logger.debug('this is debug') logger.info('this is info') logger.warning('this is warning') logger.error('this is error') logger.critical('this is critical')
與2.1.唯一不同的地方,
logger.configure
新增了一個handler
,寫入到日誌檔案去。用法很簡單。
上述只是透過logger.configure
設定日誌格式,但是模組名稱不是可變的,在實際專案開發中,不同模組寫日誌,需要指定不同的模組名稱。因此,模組名稱需要參數化,這樣實用性更強。範例程式碼如下:
import sys from loguru import logger logger.configure(handlers=[ { "sink": sys.stderr, "format": "{time:YYYY-MM-DD HH:mm:ss.SSS} |<lvl>{level:8}</>| {name} : {module}:{line:4} | <cyan>{extra[module_name]}</> | - <lvl>{message}</>", "colorize": True }, { "sink": 'first.log', "format": "{time:YYYY-MM-DD HH:mm:ss.SSS} |{level:8}| {name} : {module}:{line:4} | {extra[module_name]} | - {message}", "colorize": False }, ]) log = logger.bind(module_name='my-loguru') log.debug("this is hello, module is my-loguru") log2 = logger.bind(module_name='my-loguru2') log2.info("this is hello, module is my-loguru2")
logger.bind(module_name='my-loguru')
透過bind方法,實作module_name
的參數化。 bind傳回一個日誌對象,可以透過此對象進行日誌輸出,這樣就可以實現不同模組的日誌格式。loguru中自訂模組名稱的功能比標準日誌庫有點不同。透過bind方法,可以輕鬆實現標準日誌
logging
的功能。而且,可以透過bind和logger.configure
,輕鬆實現結構化日誌。
上述程式碼的輸出如下:
2.3.json日誌
loguru
儲存成結構化json格式非常簡單,只需要設定serialize=True
參數即可。程式碼如下:
from loguru import logger logger.add('json.log', serialize=True, encoding='utf-8') logger.debug('this is debug message') logger.info('this is info message') logger.error('this is error message')
輸出內容如下:
#2.4.日誌繞接
##loguru日誌檔案支援三種設定:循環、保留、壓縮。設定也比較簡單。尤其是壓縮格式,支援非常豐富,常見的壓縮格式都支持,例如:
"gz",
"bz2",
"xz",
"lzma",
"tar",
"tar.gz",
"tar.bz2",
"tar.xz" ,
"zip"。範例程式碼如下:
from loguru import logger logger.add("file_1.log", rotation="500 MB") # 自动循环过大的文件 logger.add("file_2.log", rotation="12:00") # 每天中午创建新文件 logger.add("file_3.log", rotation="1 week") # 一旦文件太旧进行循环 logger.add("file_X.log", retention="10 days") # 定期清理 logger.add("file_Y.log", compression="zip") # 压缩节省空间
2.5.并发安全
loguru
默认是线程安全的,但不是多进程安全的,如果使用了多进程安全,需要添加参数enqueue=True
,样例代码如下:
logger.add("somefile.log", enqueue=True)
loguru
另外还支持协程,有兴趣可以自行研究。
3.高级用法
3.1.接管标准日志logging
更换日志系统或者设计一套日志系统,比较难的是兼容现有的代码,尤其是第三方库,因为不能因为日志系统的切换,而要去修改这些库的代码,也没有必要。好在loguru
可以方便的接管标准的日志系统。
样例代码如下:
import logging import logging.handlers import sys from loguru import logger handler = logging.handlers.SysLogHandler(address=('localhost', 514)) logger.add(handler) class LoguruHandler(logging.Handler): def emit(self, record): try: level = logger.level(record.levelname).name except ValueError: level = record.levelno frame, depth = logging.currentframe(), 2 while frame.f_code.co_filename == logging.__file__: frame = frame.f_back depth += 1 logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage()) logging.basicConfig(handlers=[LoguruHandler()], level=0, format='%(asctime)s %(filename)s %(levelname)s %(message)s', datefmt='%Y-%M-%D %H:%M:%S') logger.configure(handlers=[ { "sink": sys.stderr, "format": "{time:YYYY-MM-DD HH:mm:ss.SSS} |<lvl>{level:8}</>| {name} : {module}:{line:4} | [ModuleA] | - <lvl>{message}</>", "colorize": True }, ]) log = logging.getLogger('root') # 使用标注日志系统输出 log.info('hello wrold, that is from logging') log.debug('debug hello world, that is from logging') log.error('error hello world, that is from logging') log.warning('warning hello world, that is from logging') # 使用loguru系统输出 logger.info('hello world, that is from loguru')
输出为:
3.2.输出日志到网络服务器
如果有需要,不同进程的日志,可以输出到同一个日志服务器上,便于日志的统一管理。我们可以利用自定义或者第三方库进行日志服务器和客户端的设置。下面介绍两种日志服务器的用法。
3.2.1.自定义日志服务器
日志客户端段代码如下:
# client.py import pickle import socket import struct import time from loguru import logger class SocketHandler: def __init__(self, host, port): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((host, port)) def write(self, message): record = message.record data = pickle.dumps(record) slen = struct.pack(">L", len(data)) self.sock.send(slen + data) logger.configure(handlers=[{"sink": SocketHandler('localhost', 9999)}]) while True: time.sleep(1) logger.info("Sending info message from the client") logger.debug("Sending debug message from the client") logger.error("Sending error message from the client")
日志服务器代码如下:
# server.py import pickle import socketserver import struct from loguru import logger class LoggingStreamHandler(socketserver.StreamRequestHandler): def handle(self): while True: chunk = self.connection.recv(4) if len(chunk) < 4: break slen = struct.unpack('>L', chunk)[0] chunk = self.connection.recv(slen) while len(chunk) < slen: chunk = chunk + self.connection.recv(slen - len(chunk)) record = pickle.loads(chunk) level, message = record["level"].no, record["message"] logger.patch(lambda record: record.update(record)).log(level, message) server = socketserver.TCPServer(('localhost', 9999), LoggingStreamHandler) server.serve_forever()
运行结果如下:
3.2.2.第三方库日志服务器
日志客户端代码如下:
# client.py import zmq from zmq.log.handlers import PUBHandler from loguru import logger socket = zmq.Context().socket(zmq.PUB) socket.connect("tcp://127.0.0.1:12345") handler = PUBHandler(socket)logger.add(handler) logger.info("Logging from client")
日志服务器代码如下:
# server.py import sys import zmq from loguru import logger socket = zmq.Context().socket(zmq.SUB) socket.bind("tcp://127.0.0.1:12345") socket.subscribe("") logger.configure(handlers=[{"sink": sys.stderr, "format": "{message}"}]) while True: _, message = socket.recv_multipart() logger.info(message.decode("utf8").strip())
3.3.与pytest结合
官方帮助中有一个讲解loguru
与pytest
结合的例子,讲得有点含糊不是很清楚。简单的来说,pytest
有个fixture
,可以捕捉被测方法中的logging
日志打印,从而验证打印是否触发。
下面就详细讲述如何使用loguru
与pytest
结合的代码,如下:
import pytest from _pytest.logging import LogCaptureFixture from loguru import logger def some_func(i, j): logger.info('Oh no!') logger.info('haha') return i + j @pytest.fixture def caplog(caplog: LogCaptureFixture): handler_id = logger.add(caplog.handler, format="{message}") yield caplog logger.remove(handler_id) def test_some_func_logs_warning(caplog): assert some_func(-1, 3) == 2 assert "Oh no!" in caplog.text
测试输出如下:
以上是Python中loguru日誌庫如何使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python的靈活性體現在多範式支持和動態類型系統,易用性則源於語法簡潔和豐富的標準庫。 1.靈活性:支持面向對象、函數式和過程式編程,動態類型系統提高開發效率。 2.易用性:語法接近自然語言,標準庫涵蓋廣泛功能,簡化開發過程。

Python因其簡潔與強大而備受青睞,適用於從初學者到高級開發者的各種需求。其多功能性體現在:1)易學易用,語法簡單;2)豐富的庫和框架,如NumPy、Pandas等;3)跨平台支持,可在多種操作系統上運行;4)適合腳本和自動化任務,提升工作效率。

可以,在每天花費兩個小時的時間內學會Python。 1.制定合理的學習計劃,2.選擇合適的學習資源,3.通過實踐鞏固所學知識,這些步驟能幫助你在短時間內掌握Python。

Python適合快速開發和數據處理,而C 適合高性能和底層控制。 1)Python易用,語法簡潔,適用於數據科學和Web開發。 2)C 性能高,控制精確,常用於遊戲和系統編程。

學習Python所需時間因人而異,主要受之前的編程經驗、學習動機、學習資源和方法及學習節奏的影響。設定現實的學習目標並通過實踐項目學習效果最佳。

Python在自動化、腳本編寫和任務管理中表現出色。 1)自動化:通過標準庫如os、shutil實現文件備份。 2)腳本編寫:使用psutil庫監控系統資源。 3)任務管理:利用schedule庫調度任務。 Python的易用性和豐富庫支持使其在這些領域中成為首選工具。

要在有限的時間內最大化學習Python的效率,可以使用Python的datetime、time和schedule模塊。 1.datetime模塊用於記錄和規劃學習時間。 2.time模塊幫助設置學習和休息時間。 3.schedule模塊自動化安排每週學習任務。

Python在遊戲和GUI開發中表現出色。 1)遊戲開發使用Pygame,提供繪圖、音頻等功能,適合創建2D遊戲。 2)GUI開發可選擇Tkinter或PyQt,Tkinter簡單易用,PyQt功能豐富,適合專業開發。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

WebStorm Mac版
好用的JavaScript開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中