1.安装
pip install loguru
2.快速使用
from loguru import logger
logger.add("my_log.log", rotation="10 MB") # 自动分割日志文件
logger.info("这是一个信息级别的日志")
3.日志器配置方式
1.导入即用 from loguru import logger,有且只有1个日志器对象,简化配置复杂性 2.日志器配置方式只有1种 logger.add(...),直接配置日志输出位置、格式、过滤条件、级别、滚存行为 3.为不同的日志输出位置,多次执行 logger.add(...),支持标准输出/错误、本地文件、网络位置 from loguru import logger # 导入即用,有且只有1个日志器对象,简化配置复杂性 logger.debug("That's it, beautiful and simple logging!") # 只有1种配置方式,直接配置日志输出位置(sink)、格式(format)、过滤条件(filter)、级别(level)、滚存行为(rotation) logger.add(sys.stderr, format="{time} {level} {message}", filter="my_module", level="INFO") # 可选按文件大小、时间 logger.add("file_1.log", rotation="500 MB") # Automatically rotate too big file logger.add("file_2.log", rotation="12:00") # New file is created each day at noon logger.add("file_3.log", rotation="1 week") # Once the file is too old, it's rotated # 对滚存后的旧日志文件,可选进一步配置保留/清理方式、压缩方式 logger.add("file_X.log", retention="10 days") # Cleanup after some time logger.add("file_Y.log", compression="zip") # Save some loved space
4.日志级别及自定义日志级别
TRACE:新增级别,用于开发和调试阶段跟踪执行流程和更详细的变量信息,相当有用 DEBUG INFO SUCCESS:新增,这个成功的语义更加明确,按需选择 WARNING ERROR CRITICAL 另外,还支持自定义级别 new_level = logger.level("SNAKY", no=38, color="<yellow>", icon="") logger.log("SNAKY", "Here we go!")
5.自定义字段、过滤条件
1.自定义字段,就像日志器默认的时间、模块、函数、级别等字段,我们也可以自定义像来访IP、用户ID等字段,这些字段都统一保存在record['extra']的字典里 2.自定义字段,还可以结合过滤条件使用,其中1种应用就是实现以前logging不同日志器输出到不同文件的效果 # 静态绑定自定义字段 ## 在配置格式时,加入自定义字段的占位字符串 logger.add("file.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") ## 修改绑定的自定义字段-方式1 context_logger.bind(user="someone_else").info("Inline binding of extra attribute") ## 修改绑定的自定义字段-方式2 context_logger.info("Use kwargs to add context during formatting: {user}", user="anybody") ## 如果上面写法太麻烦,可以采用with关键字+contextualize方法简写绑定方式: with logger.contextualize(task=task_id): do_something() logger.info("End of task") ================================================ # 动态绑定自定义字段 ## patch方法支持动态绑定自定义字段取值,比如当前时间 logger.add(sys.stderr, format="{extra[utc]} {message}") logger = logger.patch(lambda record: record["extra"].update(utc=datetime.utcnow())) ================================================ # 自定义字段 -> 过滤条件 ## 过滤含special自定义字段的日志到special.log中 logger.add("special.log", filter=lambda record: "special" in record["extra"]) ## 这条日志没有绑定special字段,不会写入special.log logger.debug("This message is not logged to the file") ## 这条日志绑定了special字段,会写入special.log logger.bind(special=True).info("This message, though, is logged to the file!")
6.装饰器方式捕获并日志异常
from loguru import logger @logger.catch def my_function(x, y, z): # An error? It's caught anyway! return 1 / (x + y + z)
7.多协程、多线程、多进程安全
废话,logging本身就是线程安全的,loguru当然也是 废话,线程都安全了,协程能不安全吗 多进程安全,是我喜欢它的另外一个理由 线程池、进程池中使用时,注意如果使用了logger.add(...),为避免重复配置而导致的重复日志,请在前面加上logger.remove()清除配置,否则线程、进程是复用的,提交1次任务就重复配置1次,提交1次就重复配置1次,... from loguru import logger @logger.catch def train_ps(): logger.remove() logger.add('logs/train.log', rotation='2 weeks') ...
8.异步日志解决性能损耗
当磁盘IO很高、网络有延迟时,日志本身可能就会成为程序的性能损耗点
另外多线程、多进程写入相同日志文件时,锁的问题,也会导致程序的性能损耗
Loguru非常贴心地提供了enqueue参数,直接通过消息队列的方式,实现异步日志
logger.add("somefile.log", enqueue=True)
9.其他
1.日志输出到终端时,可配置颜色 logger.add(sys.stdout, colorize=True, format="<green>{time}</green> <level>{message}</level>") 2.日志异常时,支持记录详细到变量值的异常栈,注意可能会在日志中泄露敏感数据 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 ZeroDivisionError: division by zero 3.支持序列化成JSON格式,再输出到日志位置 logger.add(custom_sink_function, serialize=True)
抄自于:https://www.toutiao.com/article/7353288382568841766