更优雅的 Python 日志解决方案 loguru
off999 2024-10-07 12:18 41 浏览 0 评论
更优雅的 Python 日志解决方案 loguru
Loguru是一个旨在为Python带来愉悦的日志记录库。
官方文档:https://github.com/Delgan/loguru
loguru 封装脚本
#!/usr/bin/python
# -*- coding: utf-8 -*-
# pip install loguru
import sys
from loguru import logger
def get_logger(log_file=None):
"""
日志规则
:param log_file:日志文件名,如为None,则不写入日志文件
:return:
"""
# 清除之前所有的设置,包括终端打印的设置
logger.remove(handler_id=None)
# 添加终端日志输出
logger.add(
sink=sys.stdout,
level='INFO', # 设置日志最低级别,如果为INFO,则DEBUG日志则不会显示
format="<light-green>{time:YYYY-MM-DD HH:mm:ss}</light-green> | " # 时间,高亮绿显示
"<level>{level:>8}:</level> " # 等级
"<level>{message}</level>", # 日志内容
)
# 如果需要写入文件,则传入文件路径
if log_file:
logger.add(
sink=log_file,
# serialize=True, # 序列化为 json,以 json 格式显示日志的每一行
encoding='utf-8', # 避免中文乱码
rotation="50 MB", # 日志文件大小超过50MB则创建新日志文件
level='DEBUG', # 设置日志最低级别,默认DEBUG
format="{time:YYYY-MM-DD HH:mm:ss} | " # 时间
"{level:<8} | " # 等级
"{process.name}:{process.id} | " # 进程名:进程ID
"{thread.name}:{thread.id} | " # 线程名:线程ID
"{name}.{module}.{function}:{line} - " # 模块名.方法名
"<level>{message}</level>", # 日志内容
)
return logger
my_logger = get_logger('loguru.log')
def my_func():
my_logger.debug('这是一个debug级别的信息')
my_logger.info('这是一个info级别的信息')
my_logger.success('这是一个success级别的信息')
my_logger.warning('这是一个warning级别的信息')
try:
with open('test.log') as f:
f.readlines()
except:
logger.exception('打开文件报错')
my_logger.error('这是一个error级别的信息')
my_logger.critical('这是一个critical级别的信息')
if __name__ == '__main__':
my_func()loguru 详细介绍
add 参数说明
- sink: 用来确定日志的输出路径,sink的选择如下:sink可以传入一个file对象,例如sys.stderr或者open('file.log','w')都可以;sink可以直接传入一个str字符串或者pathlib.Path对象,其实就是代表文件路径的,如果识别到是这种类型,它会自动创建对应路径的日志文件并将日志数据输入进去;sink可以是一个方法,可以自行定义输出实现;sink还可以是一个自定义的类。具体的实现规范可以参见官方文档;
- level: 标志日志的级别,低于该级别的日志将不会输出,如下图,值越小的日志级别越低级别值方法TRACE5logger.trace()DEBUG10logger.debug()INFO20logger.info()SUCCESS25logger.success()WARNING30logger.warning()ERROR40logger.error()CRITICAL50logger.critical()
- format: 格式化输出日志信息取值作用elapsed从程序开始经过的时间差exception格式化异常(如果有),否则为Noneextra用户绑定的属性字典(参见bind())file进行日志记录调用的文件function进行日志记录调用的函数level用于记录消息的严重程度line源代码中的行号message记录的消息(尚未格式化)module进行日志记录调用的模块name进行日志记录调用的__name__process进行日志记录调用的进程名thread进行日志记录调用的线程名time发出日志调用时的可感知的本地时间
- rotation: 设置日志的生成大小、生成时间、保存最长时间等
- retention: 指定日志保留时长,通常,一些久远的日志文件,需要周期性的去清除,避免日志堆积,浪费存储空间
- compression: 配置文件压缩格式,比如使用 zip 文件格式保存
- serialize: 希望输出类似于Json-line格式的结构化日志,可以通过 serialize 参数,将日志信息序列化的json格式写入log 文件,最后可以将日志文件导入类似于MongoDB、ElasticSearch 中用作后续的日志分析
仅输出到命令行
# pip install loguru
from loguru import logger
logger.debug('这是一个debug级别的信息')
logger.info('这是一个info级别的信息')
logger.warning('这是一个warning级别的信息')
logger.error('这是一个error级别的信息')
logger.critical('这是一个critical级别的信息')- 终端日志输出
loguru 默认以时间,级别,函数名,模块名,行号,信息的顺序来输出日志。
同时输出到文件
from loguru import logger
# 输出日志到文件(下图日志文件上部分)
# logger.add('loguru.log')
# 自定义格式输出到日志格式,在 add 中配置的格式只对写入日志文件的内容生效,命令行仍不变(下图日志文件下部分)
logger.add('loguru.log', format='[{time}] [{level}]: {message}')
logger.debug('这是一个debug级别的信息')
logger.info('这是一个info级别的信息')
logger.warning('这是一个warning级别的信息')
logger.error('这是一个error级别的信息')
logger.critical('这是一个critical级别的信息')- 日志文件记录
如没使用路径 'loguru.log' ,则会在脚本所在目录创建日志文件。也可以在日志路径中添加时间:
logger.add('loguru_{time}.log', format='[{time}] [{level}]: {message}')
# 则会生成类似 loguru_2023-02-13_19-45-41_059677.log 的日志文件format中的{time}修改为{time:YYYY-MM-DD HH:mm:ss},那么时间会自动处理成2023-02-13 20:16:09
日志转存/保留/压缩
用了 loguru 还可以非常方便地使用 rotation 配置,比如想一天输出一个日志文件,或者文件太大了自动分隔日志文件,可以直接使用 add 方法的 rotation 参数进行配置:
# 日志文件转存
logger.add("file_1.log", rotation="500 MB") # 当日志文件超过 500MB 时自传转存
logger.add("file_2.log", rotation="12:00") # 每天中午创建新的日志文件
logger.add("file_3.log", rotation="1 week") # 每一周创建日志文件
# 日志文件清理
logger.add("file_X.log", retention="10 days") # 自动清理10天之前的日志文件
# 日志文件压缩
logger.add("file_Y.log", compression="zip") # 使用zip压缩日志文件日志格式化
Loguru 更喜欢更优雅和强大的{}格式化而不是% ,日志记录函数实际上等效于 str.format()。
logger.debug('这是一个debug级别的信息,数据1:{},数据2:{data2}', 'qwe', data2=100)
# 2023-02-13 19:59:43.671 | DEBUG | __main__:<module>:8 - 这是一个debug级别的信息,数据1:qwe,数据2:100在线程或主线程中捕获异常
用法1
是否遇到程序意外崩溃,而在日志文件中没有看到任何内容?是否注意到线程中发生的异常没有被记录?可以使用catch()装饰器/上下文管理器解决这个问题,该管理器确保任何错误都被正确地传播到日志记录器。
from loguru import logger
logger.add('loguru.log', format='[{time}] [{level}]: {message}')
@logger.catch
def my_function(x, y, z):
# 异常捕获
return 1 / (x + y + z)
my_function(1, 0, -1)- 终端日志输出
- 日志文件loguru.log记录
用法2
针对exception, Loguru也有专门的分类,且可以很方便的定位到引发错误的行。
from loguru import logger
logger.add('loguru.log')
try:
if test:
print('test')
except NameError:
logger.exception('异常')- 那么在终端和日志文件中将出现下方的异常捕获
自定义颜色
如果终端兼容,Loguru会自动为日志添加颜色。可以自定义定义自己喜欢的样式。
import sys
from loguru import logger
# logger 默认包含终端打印功能,清除终端打印功能
logger.remove(handler_id=0)
# 清除之前所有的设置,包括终端打印的设置
# logger.remove(handler_id=None)
# 添加自定义的终端打印
logger.add(sys.stdout, colorize=True, format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> <level>{message}</level>")
logger.info('这是一个info级别的信息')
logger.warning('这是一个warning级别的信息')- 如果不添加logger.remove(handler_id=0),则一条日志会输出两行,因为默认有终端打印功能。
- 清除默认的终端打印功能后正常。
不同级别分别记录
将warning以及warning以上级别的log,打印到屏幕同时也记录到文件,warning以下的级别只打印不记录文件。
# 清除之前所有的设置,包括终端打印的设置
logger.remove(handler_id=None)
cmd_log = logger.add(sys.stdout) #终端打印
file_log = logger.add("loguru.log" , level="WARNING") # 文件保存,最低记录级别为WARNING
logger.info("info日志,打印到终端,不保存到文件")
logger.error("error日志,打印到终端,且保存到文件")配置日志过滤规则
我们通过实现自定义方法error_only,判断日志级别,当日志级别为ERROR,返回TRUE,我们在add方法设置filter参数时,设置为error_only,即可过滤掉ERROR以外的所有日志 。
from loguru import logger
def error_only(record):
"""
若日志级别为ERROR, 输出TRUE
"""
return record["level"].name == "ERROR"
# ERROR以外级别日志被过滤掉
logger.add("loguru.log", filter=error_only)
logger.warning('这是一个warning级别的信息')
logger.error('这是一个error级别的信息')
logger.critical('这是一个critical级别的信息')同一个项目不同模块日志
import sys
from loguru import logger
logger.remove(handler_id=None)
cmd_log = logger.add(sys.stdout) # 添加终端打印
# 日志文件,在filter中设置仅针对record name == "module1"的实例化对象。
file_log_module1 = logger.add("module1.log",
level='INFO',
filter=lambda record: record["extra"].get("name") == "module1",
enqueue=True)
# 日志文件,在filter中设置仅针对record name == "module2"的实例化对象。
file_log_module2 = logger.add("module2.log",
level='INFO',
filter=lambda record: record["extra"].get("name") == "module2",
enqueue=True)
bind_log_module1 = logger.bind(name="module1")
bind_log_module2 = logger.bind(name="module2")
bind_log_module1.info("打印+保存 module1.log")
bind_log_module2.info("打印+保存 module2.log")
# 以上执行后,会输出
# 2023-02-13 20:54:47.625 | INFO | __main__:<module>:27 - 打印+保存 module1.log
# 2023-02-13 20:54:47.627 | INFO | __main__:<module>:28 - 打印+保存 module2.log
# 同时module1.log中记录
# 2023-02-13 20:54:47.625 | INFO | __main__:<module>:27 - 打印+保存 module1.log
# module2.log中记录
# 2023-02-13 20:54:47.627 | INFO | __main__:<module>:28 - 打印+保存 module2.logenqueue=True:支持异步且线程和多进程安全。默认情况下,添加到 logger 中的日志信息都是线程安全的。但这并不是多进程安全的,可以通过添加 enqueue 参数来确保日志完整性。 如果想要在异步任务中使用日志记录的话,也是可以使用同样的参数来保证的。并且通过 complete() 来等待执行完成。
相关推荐
- 为啥系统重装后有两个系统(为啥系统重装后有两个系统 原来的系统还在)
-
电脑重装系统后有两个系统,需要重新安装,并且再安装系统时需要把原来的系统所在盘即C盘进行格式化,否则安装完成就还是两个系统,非常占系统内存。1、可能在安装时删除了原来的引导分区。2、可能安装时直接安装...
- win10win7双系统引导设置(win10 win7双系统引导)
-
步骤如下: 1、首先我是开机时按F8,进入安全模式界面。但是进去的时候等待了几分钟都无反应,上面一直显示请稍等。 2、没办法只有按下复位键重启电脑,因电脑之前装有一键GHOST备份,于是果断还原...
- ie缓存清理在哪里(ie缓存如何清除)
-
? 1、首先打开IE浏览器,选择IE浏览器的工具这一选项; 2、下一步选择工具中的Internet的选项; 3、下一步就是在Internet选项中的常规的选项中; 4、选择常规--浏览历史记录...
- 华为正版鸿蒙40电脑操作系统下载中文版
-
安装华为鸿蒙40系统正式版需要先下载官方固件包,然后将固件包放到手机内部存储或外部存储卡中。打开手机设置,选择系统更新,点击“手动更新”,选择已下载的固件包进行安装。安装前请备份重要数据并确保手机电量...
- 笔记本电脑哪个牌子好用又实惠
-
1.神舟优雅X4优点:1.35kg很轻巧,14英寸够便携固态硬盘,速度快,有背光键盘。缺点:配置较低,只能轻度办公,售后一般。2.攀升MaxBookP1优点:零噪音,金属机身,固态硬盘,大触摸板,背...
- 电脑一开机就进入bios界面(电脑开机就会进入bios)
-
原因一:你的BIOS电池没有电了。解决方式:更换电池即可原因二:没有软驱但启用了软驱解决:可将软驱禁用——开机按DEL进BIOS,选择:STANDARDCMOSFEATURESDRIVEA:...
- 电脑windows7旗舰版怎么样(电脑windows7旗舰版好不好)
-
win7旗舰版挺好使的不过现在可以选择更win10。Windows7旗舰版属于微软公司开发的Windows7操作系统系统系列中的功能最高级的版本,也被叫做终结版本,是为了取代WindowsXP...
- office2010老是弹出安装程序
-
没看到截图,最好是吧提示信息完整截图发上来。因为信息不会是仅仅“更改安装”几个字的。猜测是已经安装有Office2010了或原本的2010没有卸载干净。
- win8玩游戏稳定吗(win8的游戏win10能玩吗)
-
1、确定驱动是最稳定的公版驱动,新驱动不一定适合游戏不要贸然升级。 2、确定电源已经设置为高性能模式。3、游戏过程开个游戏加加,可以自动为你切换独显,并且自动释放内存。也可以通过它注意下CPU占用,如...
- win10系统更新版本(win10系统更新版本能回退吗)
-
win10怎么更新到1909版本win101909升级方法一:WindowsUpdate更新:1.依次点击开始—设置—更新和安全—windows更新—检查更新,需要更新补丁至最新,如果你经常不更新...
- win7升级win10要留多少空间(windows7升级windows10需要多长时间)
-
win7电脑在系统已经激活并且开启系统更新的情况下,符合条件的系统会在右下角弹出windows10免费升级,直接点击确定就开始升级了。或者下载win10安助手,运行软件后会自动下载windows1...
- 国外比较开放的浏览器(国外比较开放的浏览器推荐)
-
1、打开控制面板。2、点击“检查防火墙状态”。3、点击左侧“高级设置”。4、选中“入栈规则”。5、右侧点击“新建规则”。6、选择“端口”。7、选择“TCP”,选中“特定端口”并输入你要开发的端口,或者...
- 一健ghost下载(一键ghost v2015.07.05)
-
你的是原版镜像,当然无法识别。。你可以使用微软usb工具。将镜像写入U盘或光盘。
- 纯净无毒的win7下载(有没有纯净的win7系统)
-
下面提供的是微软发布的Windows7各版本光盘ISO镜像下载地址,原始文件均来源自MSDN,和零-售彩盒版本光盘内容完全一致。请放心下载。(如果需要光盘的买家,请无视以下内容)下...
欢迎 你 发表评论:
- 一周热门
-
-
抖音上好看的小姐姐,Python给你都下载了
-
全网最简单易懂!495页Python漫画教程,高清PDF版免费下载
-
Python 3.14 的 UUIDv6/v7/v8 上新,别再用 uuid4 () 啦!
-
飞牛NAS部署TVGate Docker项目,实现内网一键转发、代理、jx
-
python入门到脱坑 输入与输出—str()函数
-
宝塔面板如何添加免费waf防火墙?(宝塔面板开启https)
-
Python三目运算基础与进阶_python三目运算符判断三个变量
-
(新版)Python 分布式爬虫与 JS 逆向进阶实战吾爱分享
-
失业程序员复习python笔记——条件与循环
-
使用 python-fire 快速构建 CLI_如何搭建python项目架构
-
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)
