目錄
1.概述
2.常見用法
2.1.顯示格式
2.2.寫入檔案
2.3.json日誌
#2.4.日誌繞接
2.5.并发安全
3.高级用法
3.1.接管标准日志logging
3.2.输出日志到网络服务器
3.3.与pytest结合
首頁 後端開發 Python教學 Python中loguru日誌庫如何使用

Python中loguru日誌庫如何使用

May 01, 2023 pm 10:34 PM
python loguru

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')
登入後複製

上述程式碼輸出:

Python中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,也可以列印到檔案中去。

Python中loguru日誌庫如何使用

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(&#39;this is debug&#39;)
logger.info(&#39;this is info&#39;)
logger.warning(&#39;this is warning&#39;)
logger.error(&#39;this is error&#39;)
logger.critical(&#39;this is critical&#39;)
登入後複製

handlers:表示日誌輸出句柄或目的地,sys.stderr表示輸出到命令列終端。

"sink": sys.stderr,表示輸出到終端機

"format":表示日誌格式化。 <lvl>{level:8}</>表示依照日誌等級顯示顏色。 8表示輸出寬度為8個字元。

"colorize": True**:表示顯示顏色。

上述程式碼的輸出為:

Python中loguru日誌庫如何使用

#這裡寫死了模組名稱,每個日誌都這樣設定也是比較繁瑣。下面會介紹指定不同模組名稱的方法。

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": &#39;first.log&#39;,
        "format": "{time:YYYY-MM-DD HH:mm:ss.SSS} |{level:8}| {name} : {module}:{line:4} | mymodule | - {message}",
        "colorize": False
    },
])

logger.debug(&#39;this is debug&#39;)
logger.info(&#39;this is info&#39;)
logger.warning(&#39;this is warning&#39;)
logger.error(&#39;this is error&#39;)
logger.critical(&#39;this is critical&#39;)
登入後複製

與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": &#39;first.log&#39;,
        "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=&#39;my-loguru&#39;)
log.debug("this is hello, module is my-loguru")

log2 = logger.bind(module_name=&#39;my-loguru2&#39;)
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,輕鬆實現結構化日誌。

上述程式碼的輸出如下:

Python中loguru日誌庫如何使用

2.3.json日誌

loguru儲存成結構化json格式非常簡單,只需要設定serialize=True參數即可。程式碼如下:

from loguru import logger

logger.add(&#39;json.log&#39;, serialize=True, encoding=&#39;utf-8&#39;)
logger.debug(&#39;this is debug message&#39;)
logger.info(&#39;this is info message&#39;)
logger.error(&#39;this is error message&#39;)
登入後複製

輸出內容如下:

Python中loguru日誌庫如何使用

#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=(&#39;localhost&#39;, 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=&#39;%(asctime)s %(filename)s %(levelname)s %(message)s&#39;,
                    datefmt=&#39;%Y-%M-%D %H:%M:%S&#39;)

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(&#39;root&#39;)

# 使用标注日志系统输出
log.info(&#39;hello wrold, that is from logging&#39;)
log.debug(&#39;debug hello world, that is from logging&#39;)
log.error(&#39;error hello world, that is from logging&#39;)
log.warning(&#39;warning hello world, that is from logging&#39;)

# 使用loguru系统输出
logger.info(&#39;hello world, that is from loguru&#39;)
登入後複製

输出为:

Python中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(&#39;localhost&#39;, 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(&#39;>L&#39;, 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((&#39;localhost&#39;, 9999), LoggingStreamHandler)
server.serve_forever()
登入後複製

运行结果如下:

Python中loguru日誌庫如何使用

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结合

官方帮助中有一个讲解logurupytest结合的例子,讲得有点含糊不是很清楚。简单的来说,pytest有个fixture,可以捕捉被测方法中的logging日志打印,从而验证打印是否触发。

下面就详细讲述如何使用logurupytest结合的代码,如下:

import pytest
from _pytest.logging import LogCaptureFixture
from loguru import logger

def some_func(i, j):
    logger.info(&#39;Oh no!&#39;)
    logger.info(&#39;haha&#39;)
    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日誌庫如何使用

以上是Python中loguru日誌庫如何使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

vs code 可以在 Windows 8 中運行嗎 vs code 可以在 Windows 8 中運行嗎 Apr 15, 2025 pm 07:24 PM

VS Code可以在Windows 8上運行,但體驗可能不佳。首先確保系統已更新到最新補丁,然後下載與系統架構匹配的VS Code安裝包,按照提示安裝。安裝後,注意某些擴展程序可能與Windows 8不兼容,需要尋找替代擴展或在虛擬機中使用更新的Windows系統。安裝必要的擴展,檢查是否正常工作。儘管VS Code在Windows 8上可行,但建議升級到更新的Windows系統以獲得更好的開發體驗和安全保障。

visual studio code 可以用於 python 嗎 visual studio code 可以用於 python 嗎 Apr 15, 2025 pm 08:18 PM

VS Code 可用於編寫 Python,並提供許多功能,使其成為開發 Python 應用程序的理想工具。它允許用戶:安裝 Python 擴展,以獲得代碼補全、語法高亮和調試等功能。使用調試器逐步跟踪代碼,查找和修復錯誤。集成 Git,進行版本控制。使用代碼格式化工具,保持代碼一致性。使用 Linting 工具,提前發現潛在問題。

notepad 怎麼運行python notepad 怎麼運行python Apr 16, 2025 pm 07:33 PM

在 Notepad 中運行 Python 代碼需要安裝 Python 可執行文件和 NppExec 插件。安裝 Python 並為其添加 PATH 後,在 NppExec 插件中配置命令為“python”、參數為“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通過快捷鍵“F6”運行 Python 代碼。

vscode 擴展是否是惡意的 vscode 擴展是否是惡意的 Apr 15, 2025 pm 07:57 PM

VS Code 擴展存在惡意風險,例如隱藏惡意代碼、利用漏洞、偽裝成合法擴展。識別惡意擴展的方法包括:檢查發布者、閱讀評論、檢查代碼、謹慎安裝。安全措施還包括:安全意識、良好習慣、定期更新和殺毒軟件。

See all articles