1. 安装

pip install loguru

2. 初识

from loguru import logger

logger.debug("This is a debug...")

loguru 里面有且仅有一个主要对象,那就是 loggerloguru 里面有且仅有一个 logger,而且它已经被提前配置了一些基础信息,比如比较友好的格式化、文本颜色信息等等。

上面的代码运行结果如下:

2020-05-03 09:22:35.746 | DEBUG    | __main__:<module>:3 - This is a debug...

可以看到其默认的输出格式是上面的内容,有时间、级别、模块名、行号以及日志信息,不需要手动创建 logger,直接使用即可,另外其输出还是彩色的,看起来会更加友好。

以上的日志信息是直接输出到控制台的,并没有输出到其他的地方,如果想要输出到其他的位置,比如存为文件,我们只需要使用一行代码声明即可。

例如将结果同时输出到一个 runtime.log 文件里面,可以这么写:

from loguru import logger

logger.add("runtime.log")
logger.debug("This is a debug...")
logger.warning("This is a debug...")

一行 add 语句搞定,运行之后会发现目录下 runtime.log 里面同样出现了刚刚控制台输出的 DEBUG 信息。

2020-05-03 09:26:09.212 | DEBUG    | __main__:<module>:4 - This is a debug...
2020-05-03 09:26:09.212 | WARNING | __main__:<module>:5 - This is a debug...

3. 使用

既然是日志,那么最常见的就是输出到文件了。loguru 对输出到文件的配置有非常强大的支持,比如支持输出到多个文件,分级别分别输出,过大创建新文件,过久自动删除等等。

下面我们分别看看这些怎样来实现,这里基本上就是 add 方法的使用介绍。因为这个 add 方法就相当于给 logger 添加了一个 Handler,它给我们暴露了许多参数来实现 Handler 的配置,下面我们来详细介绍下。

首先看看它的方法定义吧:

def add(
self,
sink,
*,
level=_defaults.LOGURU_LEVEL,
format=_defaults.LOGURU_FORMAT,
filter=_defaults.LOGURU_FILTER,
colorize=_defaults.LOGURU_COLORIZE,
serialize=_defaults.LOGURU_SERIALIZE,
backtrace=_defaults.LOGURU_BACKTRACE,
diagnose=_defaults.LOGURU_DIAGNOSE,
enqueue=_defaults.LOGURU_ENQUEUE,
catch=_defaults.LOGURU_CATCH,
**kwargs
)

看看它的源代码,它支持这么多的参数,如 levelformatfiltercolor 等等,另外我们还注意到它有个非常重要的参数 sink,我们看看官方文档:sink,可以了解到通过 sink 我们可以传入多种不同的数据结构,汇总如下:

  • sink 可以传入一个 file 对象,例如 sys.stderr 或者 open('file.log', 'w') 都可以。

  • sink 可以直接传入一个 str 字符串或者 pathlib.Path 对象,其实就是代表文件路径的,如果识别到是这种类型,它会自动创建对应路径的日志文件并将日志输出进去。

  • sink 可以是一个方法,可以自行定义输出实现。

  • sink 可以是一个 logging 模块的 Handler,比如 FileHandlerStreamHandler 等等,或者上文中我们提到的 CMRESHandler 照样也是可以的,这样就可以实现自定义 Handler 的配置。

  • sink 还可以是一个自定义的类,具体的实现规范可以参见官方文档。

所以说,刚才我们所演示的输出到文件,仅仅给它传了一个 str 字符串路径,他就给我们创建了一个日志文件,就是这个原理。

3.1 基本参数

下面我们再了解下它的其他参数,例如 formatfilterlevel 等等。

其实它们的概念和格式和 logging 模块都是基本一样的了,例如这里使用formatfilterlevel来规定输出的格式:

logger.add('runtime.log', format="{time} {level} {message}", filter="my_module", level="INFO")

3.2 删除sink

另外添加 sink 之后我们也可以对其进行删除,相当于重新刷新并写入新的内容。

删除的时候根据刚刚 add 方法返回的 id 进行删除即可,看下面的例子:

from loguru import logger

trace = logger.add('runtime.log')
logger.debug('this is a debug message')
logger.remove(trace)
logger.debug('this is another debug message')

看这里,我们首先 add 了一个 sink,然后获取它的返回值,赋值为 trace。随后输出了一条日志,然后将 trace 变量传给remove 方法,再次输出一条日志,看看结果是怎样的。

控制台输出如下:

2020-05-03 09:55:11.005 | DEBUG    | __main__:<module>:4 - this is a debug message
2020-05-03 09:55:11.005 | DEBUG | __main__:<module>:6 - this is another debug message

日志文件 runtime.log 内容如下:

2020-05-03 09:55:11.005 | DEBUG    | __main__:<module>:4 - this is a debug message

可以发现,在调用 remove 方法之后,确实将历史 log 删除了。

这样我们就可以实现日志的刷新重新写入操作。

3.3 rotation配置

用了 loguru 我们还可以非常方便地使用rotation 配置,比如我们想一天输出一个日志文件,或者文件太大了自动分隔日志文件,我们可以直接使用 add 方法的 rotation 参数进行配置。

我们看看下面的例子:

logger.add('runtime_{time}.log', rotation="500 MB")

通过这样的配置我们就可以实现每 500MB 存储一个文件,每个 log 文件过大就会新创建一个 log 文件。我们在配置 log 名字时加上了一个 time 占位符,这样在生成时可以自动将时间替换进去,生成一个文件名包含时间的 log 文件。

另外我们也可以使用 rotation 参数实现定时创建 log 文件,例如:

logger.add('runtime_{time}.log', rotation='00:00')

这样就可以实现每天 0 点新创建一个 log 文件输出了。

另外我们也可以配置 log 文件的循环时间,比如每隔一周创建一个 log 文件,写法如下:

logger.add('runtime_{time}.log', rotation='1 week')

这样我们就可以实现一周创建一个 log 文件了。

3.4 retention 配置

很多情况下,一些非常久远的 log 对我们来说并没有什么用处了,它白白占据了一些存储空间,不清除掉就会非常浪费。retention 这个参数可以配置日志的最长保留时间。

比如我们想要设置日志文件最长保留 10 天,可以这么来配置:

logger.add('runtime.log', retention='10 days')

Examples: "1 week, 3 days", "2 months"

这样 log 文件里面就会保留最新 10 天的 log,妈妈再也不用担心 log 沉积的问题啦。

3.5 compression配置

loguru 还可以配置文件的压缩格式,比如使用 zip 文件格式保存,示例如下:

logger.add('runtime.log', compression='zip')

可选格式为"gz", "bz2", "xz", "lzma", "tar", "tar.gz", "tar.bz2",

"tar.xz", "zip"

3.6 enqueue配置

loguru可以配置在多进程同时往日志文件写日志的时候使用队列达到异步功效。

logger.add("somefile.log", enqueue=True)  # 异步写入

要记录的消息是否应该在到达接收器之前首先通过一个多进程安全的队列。这在通过多个进程记录文件时非常有用。

3.7 字符串格式化

loguru 在输出 log 的时候还提供了非常友好的字符串格式化功能,像这样:

logger.info('If you are using Python {}, prefer {feature} of course!', 3.6, feature='f-strings')

输出:

2020-05-03 10:24:34.200 | INFO     | __main__:<module>:3 - If you are using Python 3.6, prefer f-strings of course!

3.8 Traceback 记录

在很多情况下,如果遇到运行错误,而我们在打印输出 log 的时候万一不小心没有配置好 Traceback 的输出,很有可能我们就没法追踪错误所在了。

但用了 loguru 之后,我们用它提供的装饰器就可以直接进行 Traceback 的记录,类似这样的配置即可:

@logger.catch
def my_function(x, y, z):
# An error? It's caught anyway!
return 1 / (x + y + z)

我们做个测试,我们在调用时三个参数都传入 0,直接引发除以 0 的错误,看看会出现什么情况

my_function(0, 0, 0)

运行完毕之后,可以发现 log 里面就出现了 Traceback 信息,而且给我们输出了当时的变量值,真的是不能再赞了!结果如下:

> File "run.py", line 15, in <module>
my_function(0, 0, 0)
└ <function my_function at 0x1171dd510> File "/private/var/py/logurutest/demo5.py", line 13, in my_function
return 1 / (x + y + z)
│ │ └ 0
│ └ 0
└ 0 ZeroDivisionError: division by zero

『Python』优雅的记录日志——loguru的更多相关文章

  1. 『Python』__getattr__()特殊方法

    self的认识 & __getattr__()特殊方法 将字典调用方式改为通过属性查询的一个小class, class Dict(dict): def __init__(self, **kw) ...

  2. 『Python』 ThreadPool 线程池模板

    Python 的 简单多线程实现 用 dummy 模块 一句话就可以搞定,但需要对线程,队列做进一步的操作,最好自己写个线程池类来实现. Code: # coding:utf-8 # version: ...

  3. 『Python』Python 调用 ZoomEye API 批量获取目标网站IP

    #### 20160712 更新 原API的访问方式是以 HTTP 的方式访问的,根据官网最新文档,现在已经修改成 HTTPS 方式,测试可以正常使用API了. 0x 00 前言 ZoomEye 的 ...

  4. 『Python』为什么调用函数会令引用计数+2

    一.问题描述 Python中的垃圾回收是以引用计数为主,分代收集为辅,引用计数的缺陷是循环引用的问题.在Python中,如果一个对象的引用数为0,Python虚拟机就会回收这个对象的内存. sys.g ...

  5. 『Python』库安装

    1.安装指定版本的tensorflow 虽然官网有4种安装方式,并且推荐用anaconda的方式,但是有时候我们需要指定版本的tensorflow,而pip可以做到. 比如我装的是anaconda3. ...

  6. 『Python』装饰器

    一.参考 作者:zhijun liu 链接:https://www.zhihu.com/question/26930016/answer/99243411 来源:知乎 建议大家去原答案浏览 二.装饰器 ...

  7. 『Python』多进程处理

    尝试学习python的多进程模组,对比多线程,大概的区别在: 1.多进程的处理速度更快 2.多进程的各个子进程之间交换数据很不方便 多进程调用方式 进程基本使用multicore() 进程池优化进程的 ...

  8. 『Python』内存分析_list和array

    零.预备知识 在Python中,列表是一个动态的指针数组,而array模块所提供的array对象则是保存相同类型的数值的动态数组.由于array直接保存值,因此它所使用的内存比列表少.列表和array ...

  9. 『Python』VS2015编译源码注意事项

    一.2.5.6版本源码编译 解压 Python-2.5.6.tgz 进入 Pcbuild8 文件夹,使用 vs 2013 打开 pybuild.sln (vs 解决方案),进入 vs2015IDE 环 ...

随机推荐

  1. CSS Transform完全指南(第二版) #flight.Archives007

    Title/ CSS Transform完全指南(第二版) #flight.Archives007 序: 第7天了! 终身学习, 坚持创作, 为生活埋下微小的信仰. 我是忘我思考,共同进步! 简介: ...

  2. NOIP 模拟 $29\; \rm 完全背包问题$

    题解 \(by\;zj\varphi\) 一道 \(\rm dp\) 题. 现将所有种类从小到大排序,然后判断,若最小的已经大于了 \(\rm l\),那么直接就是一个裸的完全背包,因为选的总数量有限 ...

  3. ingress-nginx-controller 部署以及优化

    一.说明 本文使用的ingress-nginx v1.0 最新版本,v1.0 适用于 Kubernetes 版本 >= v1.19 小于这个版本的k8s集群,请降级ingress-nginx. ...

  4. 根据当前设备的宽度,动态计算出rem的换算比例,实现页面中元素的等比缩放

    ~function anonymous(window){ //根据当前设备的宽度,动态计算出rem的换算比例,实现页面中元素的等比缩放 let computedREM = function compu ...

  5. Element form表单方法resetFields无效

    之前遇到resetFields无效时都是自己手动用this.ruleForm = Object.assign({}, this.ruleForm, this.$options.data().ruleF ...

  6. k8s笔记0528-基于KUBERNETES构建企业容器云手动部署集群记录-4

    部署kubelet 1.二进制包准备 将软件包从linux-node1复制到linux-node2中去. [root@linux-node1 ~]# cd /usr/local/src/kuberne ...

  7. 痞子衡嵌入式:MCUXpresso Config Tools初体验(Pins, Clocks, Peripherals)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso Config Tools三大件(Pins, Clocks, Peripherals). 不知道大家有没有这样的感受 ...

  8. Linux常用命令(二)之权限管理、文件搜索、帮助、压缩命令及管道

    在(一)中提到过rwx的含义,但是我们还需深入理解,明白其真正的含义和权限,对于文件和目录,rwx权限是不同的,尤其是目录的权限往往是被忽略的: 对于目录,其权限和对应的操作: r-ls w-touc ...

  9. proto buffer

    protobuf是一种高效的数据格式,平台无关.语言无关.可扩展,可用于 RPC 系统和持续数据存储系统. protobuf介绍 Protobuf是Protocol Buffer的简称,它是Googl ...

  10. vue js 手写 正则判断 手机号码 和 密码

    const phoneOrEmails = /^1[3|4|5|6|7|8|9][0-9]\d{8}$/             if(this.ruleForms.phoneOrEmail  ==  ...