简介
这是一个基于logging的日志模块,引用官方的说话:Loguru是一个旨在为 Python 带来愉快的日志记录的库。
您是否曾经对配置记录器感到懒惰并print()
改为使用记录器?...我做到了,但记录是每个应用程序的基础,并且简化了调试过程。使用Loguru,您没有理由不从一开始就使用日志记录,这就像from loguru import logger
.
此外,该库旨在通过添加一系列有用的功能来解决标准记录器的警告,从而减少 Python 记录的痛苦。在你的应用程序中使用日志应该是一种自动化,Loguru试图让它既愉快又强大。
基础使用
安装
pip install Loguru
引入模块
from loguru import logger
开启|关闭日志功能
# For scripts
config = {
"handlers": [
{"sink": sys.stdout, "format": "{time} - {message}"},
{"sink": "file.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")
错误追踪
方式1:
@logger.catch
def my_function(x, y, z):
# An error? It's caught anyway!
return 1 / (x + y + z)
方式2:
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)
常用方法
add - 基础配置
logger.add(
rotation:str, # 日志的替换条件(比如按时间,按大小,条件满足就会覆盖重写)
compression:str, # 日志的协程接收器
enqueue:bool, # 日志在多进程的时候,是否使用队列,确保进程安全
serialize:bool, # 是否序列号日志(每个日志消息将在发送到配置的接收器之前转换为 JSON 字符串)
)
通过add可以对日志进行复杂的配置:
# Automatically rotate too big file
# 设定一个大小来替换原日志文件
logger.add("file_1.log", rotation="500 MB")
# New file is created each day at noon
# 自动按照时间周期来分割日志
logger.add("file_2.log", rotation="12:00")
# Once the file is too old, it's rotated
# 按照周来替换文件
logger.add("file_3.log", rotation="1 week")
# Cleanup after some time
# 按照日期替换文件
logger.add("file_X.log", retention="10 days")
# Save some loved space
logger.add("file_Y.log", compression="zip")
bind - 远程输出
绑定一个远程接收器
context_logger = logger.bind(ip="192.168.0.1", user="someone")
context_logger.bind(user="someone_else").info("Inline binding of extra attribute")
patch - 过滤器
对每一条日志添加一个过滤器,对内容进行一定的修改
logger.add(sys.stderr, format="{extra[utc]} {message}")
logger = logger.patch(lambda record: record["extra"].update(utc=datetime.utcnow()))
level - 自定义日志级别
创建一个 SNAKY
级别的日志等级
new_level = logger.level("SNAKY", no=38, color="<yellow>", icon="🐍")
logger.log("SNAKY", "Here we go!")
opt - 性能
使用 opt() 可以在生产环境中以不降低性能(官方描述)的方式记录日志
使用示例
定义 format
- 自定义格式
# 使用 类format的模板进行格式化
logger.info(
"If you're using Python {}, prefer {feature} of course!",
3.6,
feature="f-strings")
- 自定义颜色
logger.add(
sys.stdout,
colorize=True,
format="<green>{time}</green> <level>{message}</level>")
捕获异常
@logger.catch
def my_function(x, y, z):
# An error? It's caught anyway!
return 1 / (x + y + z)
更准确的异常位置
# backtrace=True
# diagnose=True
logger.add("out.log", backtrace=True, diagnose=True)
def func(a, b):
return a / b
def nested(c):
try:
func(5, c)
except ZeroDivisionError:
logger.exception("What?!")
nested(0)
- 日志输出
2018-07-17 01:38:43.975 | ERROR | __main__:nested:10 - What?!
Traceback (most recent call last):
File "test.py", line 12, in <module>
nested(0)
└ <function nested at 0x7f5c755322f0>
> File "test.py", line 8, in nested
func(5, c)
│ └ 0
└ <function func at 0x7f5c79fc2e18>
File "test.py", line 4, in func
return a / b
│ └ 0
└ 5
使用示例
fastapi
import uvicorn
from loguru import logger
from fastapi.responses import JSONResponse
@app.post("/",summary="测试"])
def none():
logger.debug("测试")
return JSONResponse(content={"结果":"测试"})
if __name__ == "__main__":
# 日志设置
dir_log = "logs"
path_log = os.path.join(dir_log, '日志文件.log')
logger.add(path_log,
rotation='0:00', # 每日分割时间 输入 "1 mb" 则以大小分割
enqueue=True, # 是否异步记录
serialize=False, # 日志是否序列化
encoding="utf-8", # 编码格式
retention="10 days") # 最长保存日志时间
backtrace=True, # 显示详细的错误信息
# 等价于logger.exception("What?!", exe_xxx=True)
diagnose=True #
logger.debug("服务器重启!")
uvicorn.run('main:app',host="0.0.0.0", port=8000,reload=False)