Python 日志记录-loguru

Python 日志记录-loguru

引言

loguru是一个第三方库,用来记录日志的。使用起来比较方便,且功能比较全面。

官方文档

安装

pip install loguru

日志级别

Level nameSeverity valueLogger method
TRACE5logger.trace
DEBUG10logger.debug
INFO20logger.info
SUCCESS25logger.success
WARNING30logger.warning
ERROR40logger.error
CRITICAL50logger.critical

简单测试下

from loguru import logger

logger.debug("debug")
logger.info("info")
logger.success("success")
logger.warning("warning")
logger.error("error")
logger.critical("critical")

输出结果

在这里插入图片描述

特性

简介

此函数应用于注册接收器,这些接收器负责管理使用记录字典上下文化的日志消息。接收器可以采用多种形式:简单函数、字符串路径、类似文件的对象、协程函数或内置处理程序。

请注意:可以使用remove()函数来删除以前添加的处理程序。

例子:

import sys
from loguru import logger


logger.add("test.log", format="{time} {level} {message}", filter="", level="INFO", encoding="utf-8")
logger.debug("debug")
logger.info("info")
logger.success("success")
logger.warning("warning")
logger.error("error")
logger.critical("critical")

效果,输出日志到test.log文件

2022-07-27T17:14:36.393072+0800 INFO info
2022-07-27T17:14:36.394068+0800 SUCCESS success
2022-07-27T17:14:36.395066+0800 WARNING warning
2022-07-27T17:14:36.396063+0800 ERROR error
2022-07-27T17:14:36.397060+0800 CRITICAL critical

rotation/retension/compression

官方介绍:loguru.logger — loguru documentation

rotation:指示何时应关闭当前记录的文件并创建新文件,可以是文件大小/每天的时间点/时间间隔等。

logger.add("test1.log", rotation="500 MB") # 日志文件超过500M创建新的文件
logger.add("test2.log", rotation="12:00")  # 每天中午12点创建新的日志文件
logger.add("test3.log", rotation="1 week") # 当前使用的日志文件超过1周,创建新的日志文件

retension:指示合适应该删除旧文件。

logger.add("test4.log", retention="10 days") # 超过十天的日志文件删除

compression:日志文件在关闭时应转换为的压缩或归档格式。

logger.add("test5.log", compression="zip") # 日志文件关闭后,使用zip进行压缩

异常捕获

使用catch()装饰器或者上下文管理器可以捕获异常,确保任何错误都能够记录到log日志中。

装饰器

from loguru import logger

@logger.catch
def test(x, y, z):
    return 1 / (x + y + z)

test(0, 1, -1)

上下文装饰器

from loguru import logger


def test(x, y, z):
    return 1 / (x + y + z)

with logger.catch():
    test(0, 1, -1) 

输出结果
在这里插入图片描述

完全描述性异常

记录代码中发生的异常对于跟踪BUG非常重要,loguru允许显示整个堆栈跟踪(包括变量值)来帮助定位BUG原因。

logger.add("out.log", backtrace=True, diagnose=True)  # Caution, may leak sensitive data in prod

def func(a, b):
    return a / b

def nested(c):
    try:
        func(5, c)
    except ZeroDivisionError:
        logger.exception("What?!")

nested(0)

输出结果
在这里插入图片描述

自定义颜色

logger.add(sys.stdout, colorize=True, format="<red>{time}</red> <level>{message}</level>")
logger.debug("debug")
logger.info("info")
logger.success("success")
logger.warning("warning")
logger.error("error")
logger.critical("critical")

输出结果
在这里插入图片描述

异步/线程安全/多进程安全

默认情况下,添加到log的所有接收器都是线程安全的,但他们不是多进程安全的。如果需要实现多进程安全,异步记录日志,需要添加一个enqueue参数:

logger.add("test.log", enqueue = True)

结构化日志记录

将消息转化为json字符串以便于传递或者解析,可以使用serialize来配置:

logger.add("test.log", serialize=True, encoding="utf-8")
logger.debug("debug")
logger.info("info")
logger.success("success")
logger.warning("warning")
logger.error("error")
logger.critical("critical")

输出结果

{"text": "2022-07-28 11:25:44.434 | DEBUG    | __main__:<module>:43 - debug\n", "record": {"elapsed": {"repr": "0:00:00.127658", "seconds": 0.127658}, "exception": null, "extra": {}, "file": {"name": "logutil.py", "path": "e:\\GitPorject\\ZanguS1\\ZanguRecorder\\common\\logutil.py"}, "function": "<module>", "level": {"icon": "🐞", "name": "DEBUG", "no": 10}, "line": 43, "message": "debug", "module": "logutil", "name": "__main__", "process": {"id": 15768, "name": "MainProcess"}, "thread": {"id": 10228, "name": "MainThread"}, "time": {"repr": "2022-07-28 11:25:44.434074+08:00", "timestamp": 1658978744.434074}}}
{"text": "2022-07-28 11:25:44.436 | INFO     | __main__:<module>:44 - info\n", "record": {"elapsed": {"repr": "0:00:00.129653", "seconds": 0.129653}, "exception": null, "extra": {}, "file": {"name": "logutil.py", "path": "e:\\GitPorject\\ZanguS1\\ZanguRecorder\\common\\logutil.py"}, "function": "<module>", "level": {"icon": "ℹ️", "name": "INFO", "no": 20}, "line": 44, "message": "info", "module": "logutil", "name": "__main__", "process": {"id": 15768, "name": "MainProcess"}, "thread": {"id": 10228, "name": "MainThread"}, "time": {"repr": "2022-07-28 11:25:44.436069+08:00", "timestamp": 1658978744.436069}}}
{"text": "2022-07-28 11:25:44.438 | SUCCESS  | __main__:<module>:45 - success\n", "record": {"elapsed": {"repr": "0:00:00.131648", "seconds": 0.131648}, "exception": null, "extra": {}, "file": {"name": "logutil.py", "path": "e:\\GitPorject\\ZanguS1\\ZanguRecorder\\common\\logutil.py"}, "function": "<module>", "level": {"icon": "✔️", "name": "SUCCESS", "no": 25}, "line": 45, "message": "success", "module": "logutil", "name": "__main__", "process": {"id": 15768, "name": "MainProcess"}, "thread": {"id": 10228, "name": "MainThread"}, "time": {"repr": "2022-07-28 11:25:44.438064+08:00", "timestamp": 1658978744.438064}}}
{"text": "2022-07-28 11:25:44.439 | WARNING  | __main__:<module>:46 - warning\n", "record": {"elapsed": {"repr": "0:00:00.132645", "seconds": 0.132645}, "exception": null, "extra": {}, "file": {"name": "logutil.py", "path": "e:\\GitPorject\\ZanguS1\\ZanguRecorder\\common\\logutil.py"}, "function": "<module>", "level": {"icon": "⚠️", "name": "WARNING", "no": 30}, "line": 46, "message": "warning", "module": "logutil", "name": "__main__", "process": {"id": 15768, "name": "MainProcess"}, "thread": {"id": 10228, "name": "MainThread"}, "time": {"repr": "2022-07-28 11:25:44.439061+08:00", "timestamp": 1658978744.439061}}}
{"text": "2022-07-28 11:25:44.440 | ERROR    | __main__:<module>:47 - error\n", "record": {"elapsed": {"repr": "0:00:00.133642", "seconds": 0.133642}, "exception": null, "extra": {}, "file": {"name": "logutil.py", "path": "e:\\GitPorject\\ZanguS1\\ZanguRecorder\\common\\logutil.py"}, "function": "<module>", "level": {"icon": "❌", "name": "ERROR", "no": 40}, "line": 47, "message": "error", "module": "logutil", "name": "__main__", "process": {"id": 15768, "name": "MainProcess"}, "thread": {"id": 10228, "name": "MainThread"}, "time": {"repr": "2022-07-28 11:25:44.440058+08:00", "timestamp": 1658978744.440058}}}
{"text": "2022-07-28 11:25:44.442 | CRITICAL | __main__:<module>:48 - critical\n", "record": {"elapsed": {"repr": "0:00:00.135637", "seconds": 0.135637}, "exception": null, "extra": {}, "file": {"name": "logutil.py", "path": "e:\\GitPorject\\ZanguS1\\ZanguRecorder\\common\\logutil.py"}, "function": "<module>", "level": {"icon": "☠️", "name": "CRITICAL", "no": 50}, "line": 48, "message": "critical", "module": "logutil", "name": "__main__", "process": {"id": 15768, "name": "MainProcess"}, "thread": {"id": 10228, "name": "MainThread"}, "time": {"repr": "2022-07-28 11:25:44.442053+08:00", "timestamp": 1658978744.442053}}}

使用bind()添加额外的属性:

logger.add("test.log", format="{extra[ip]} {extra[user]} {message}")
context_logger = logger.bind(ip="192.168.0.1", user="someone")
context_logger.info("Contextualize your logger easily")
context_logger.bind(user="someone_else").info("Inline binding of extra attribute")
context_logger.info("Use kwargs to add context during formatting: {user}", user="anybody")

输出结果

192.168.0.1 someone Contextualize your logger easily
192.168.0.1 someone_else Inline binding of extra attribute
192.168.0.1 anybody Use kwargs to add context during formatting: anybody

使用bind()和filter对日志进行过滤:

logger.add("test.log", filter=lambda record: "special" in record["extra"])
logger.debug("This message is not logged to the file")
logger.bind(special=True).info("This message, though, is logged to the file!")

输出结果

2022-07-28 11:33:58.214 | INFO     | __main__:<module>:58 - This message, though, is logged to the file!

自定义级别

Loguru 附带了所有标准日志记录级别,额外添加了trace和success。如果需要自定义级别,可以使用level()函数来创建:

new_level = logger.level("test2", no=66, color="<black>", icon="🐍")

logger.log("test2", "Here we go!")

输出结果:
在这里插入图片描述

日期时间处理

logger.add("test.log", format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}")
logger.debug("debug")
logger.info("info")
logger.success("success")
logger.warning("warning")
logger.error("error")
logger.critical("critical")

输出结果:

2022-07-28 at 11:41:32 | DEBUG | debug
2022-07-28 at 11:41:32 | INFO | info
2022-07-28 at 11:41:32 | SUCCESS | success
2022-07-28 at 11:41:32 | WARNING | warning
2022-07-28 at 11:41:32 | ERROR | error
2022-07-28 at 11:41:32 | CRITICAL | critical

loguru配置

在脚本中使用记录器很容易,您可以在开始时configure()它。要从库中使用 Loguru,请记住永远不要调用 add(),而是使用 disable(),以便日志记录函数变为 no-op。如果开发人员希望查看库的日志,他可以再次enable() 它。

# For scripts
config = {
    "handlers": [
        {"sink": sys.stdout, "format": "{time} - {message}"},
        {"sink": "test.log", "serialize": True},
    ],
    "extra": {"user": "someone"}
}
logger.configure(**config)

# For libraries
logger.disable("my_library")
logger.info("No matter added sinks, this message is not displayed")
logger.enable("my_library")
logger.info("This message however is propagated to the sinks")

通知程序

Loguru 可以和强大的邮件通知模块 notifiers 库结合使用,以在程序意外失败时接收电子邮件,或发送许多其他类型的通知。

import notifiers

params = {
    "username": "you@gmail.com",
    "password": "abc123",
    "to": "dest@gmail.com"
}

# Send a single notification
notifier = notifiers.get_notifier("gmail")
notifier.notify(message="The application is running!", **params)

# Be alerted on each error message
from notifiers.logging import NotificationHandler

handler = NotificationHandler("gmail", defaults=params)
logger.add(handler, level="ERROR")

尾语

希望能帮助到大家,如果又说的不对的地方,欢迎大家指正。

优快云开发云]

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淡定九号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值