ホームページ  >  記事  >  バックエンド開発  >  Python で loguru ログ ライブラリを使用する方法

Python で loguru ログ ライブラリを使用する方法

王林
王林転載
2023-05-01 22:34:051959ブラウズ

1. 概要

pythonlogging のログ ライブラリは log4j に似ていますが、通常、設定はより複雑です。構築ログ サーバーも不便です。標準ライブラリ logging の代わりとなるのは loguru で、より簡単に使用できます。

loguru

デフォルトの出力形式は、時間、レベル、モジュール、行番号、ログの内容です。 loguru logger を手動で作成する必要はなく、すぐに使用でき、logging よりもはるかに使いやすく、さらにログ出力カラー機能と非カラー機能が組み込まれています。コントロールは非常に便利で、よりフレンドリーです。

loguru

は非標準ライブラリなので、事前にインストールする必要があります。コマンドは **pip3 install loguru**** です。 **インストール後の最も簡単な使用例は次のとおりです: <pre class="brush:py;">from loguru import logger logger.debug(&amp;#39;hello, this debug loguru&amp;#39;) logger.info(&amp;#39;hello, this is info loguru&amp;#39;) logger.warning(&amp;#39;hello, this is warning loguru&amp;#39;) logger.error(&amp;#39;hello, this is error loguru&amp;#39;) logger.critical(&amp;#39;hello, this is critical loguru&amp;#39;)</pre>上記のコード出力:

Python で loguru ログ ライブラリを使用する方法ファイルへのログ出力の使用法も非常に便利です。単純なコードは次のとおりです。

from loguru import logger

logger.add(&#39;myloguru.log&#39;)

logger.debug(&#39;hello, this debug loguru&#39;)
logger.info(&#39;hello, this is info loguru&#39;)
logger.warning(&#39;hello, this is warning loguru&#39;)
logger.error(&#39;hello, this is error loguru&#39;)
logger.critical(&#39;hello, this is critical loguru&#39;)

上記のコードを実行すると、コンソールまたはファイルに出力できます。

#2. 一般的な使用法Python で loguru ログ ライブラリを使用する方法

2.1. 表示形式

loguru

デフォルトの形式は、時間、レベル、 name モジュールとログの内容、name モジュールはハードコーディングされており、現在のファイルの

__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":

はログのフォーマットを意味します。

{level:8}> は、ログレベルに応じて色を表示することを意味します。 8 は、出力幅が 8 文字であることを意味します。 "colorize":

True**: 表示色を示します。 上記のコードの出力は次のとおりです:

Python で loguru ログ ライブラリを使用する方法ここではモジュール名がハードコーディングされており、非常に面倒です。このように各ログを設定します。異なるモジュール名を指定する方法を以下に説明します。

2.2. ファイルへの書き込み

ログは通常、永続化する必要があり、コマンド ライン ターミナルに出力するだけでなく、ファイルに書き込む必要もあります。標準ログ ライブラリは、構成ファイルを通じてロガーを構成でき、コードに実装することもできますが、プロセスは比較的面倒です。 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')

module_name のパラメータ化は、bind メソッドによって実現されます。 。 bind は、ログ出力を実行できるログ オブジェクトを返すため、さまざまなモジュールのログ形式を実装できます。 loguru のモジュール名をカスタマイズする機能は、標準のロギング ライブラリとは少し異なります。バインドメソッドを利用することで、標準のloglogging

の機能を簡単に実現できます。さらに、構造化されたログは、

bind および logger.configure を通じて簡単に実装できます。 上記のコードの出力は次のとおりです:

2.3.json logPython で loguru ログ ライブラリを使用する方法

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;)
出力内容は次のとおりです:

2.4. ログのラッピングPython で loguru ログ ライブラリを使用する方法

loguru

ログ ファイルのサポート 3 つの設定: ループ、保存、圧縮。セットアップも比較的簡単です。特に圧縮形式のサポートが充実しており、

"gz""bz2""xz"、# などの一般的な圧縮形式がサポートされています。 # #"lzma", "tar", "tar.gz", "tar.bz2", "tar.xz " ###、 ###"ジップ"###。サンプルコードは次のとおりです:

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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。