【Python】不会优雅的记日志,你又又Out了!!!

1. 引言

在日常开发中,大家经常使用 print 函数来调试我们写的的代码。然而,随着打印语句数量的增加,由于缺乏行号或函数名称,很难确定输出来自何处。而且随着print语句的增多,调试完代码删除这些信息的时候也比较麻烦。

Python中的logging模块为这一问题提供了完美的解决方案,允许大家为相应的输出指定不同的级别(DEBUGINFOWARNINGERROR)。由于日志中包含时间戳、函数名称和行号等附加信息,可以帮助大家快速确定日志信息的来源。而且还可以将日志级别设置为 "INFO "或更高,以排除调试日志,从而保持日志的简洁性和相关性。

本文重点介绍Python开源库 Loguru的基本使用方法,以及这些特性如何使其成为标准日志库的logging模块的绝佳替代品。

2. 开箱即用特性

一般情况下,标准日志库logging模块的输出比较朴素平淡无奇,而Loguru默认生成的日志内容丰富、颜色鲜明。
我们来看二者的对比,首先是标准日志库的默认输出:

import logging
logger = logging.getLogger(__name__)def main():logger.debug("This is a debug message")logger.info("This is an info message")logger.warning("This is a warning message")logger.error("This is an error message")if __name__ == "__main__":main()

运行上述代码,结果如下:
在这里插入图片描述

接着是我们Loguru库的默认输出:

from loguru import loggerdef main():logger.debug("This is a debug message")logger.info("This is an info message")logger.warning("This is a warning message")logger.error("This is an error message")if __name__ == "__main__":main()

运行上述代码,结果如下:
在这里插入图片描述
可以直观的对比下上述两种输出,看看你更喜欢哪种?

3. 控制输出格式

有的同学看了上述的输出后,会说事实上logging模块也可以控制指定输出格式,比如指定诸如时间戳、日志级别、模块名称、函数名称和行号。代码如下:

import logging
# Create a logger and set the logging level
logging.basicConfig(level=logging.INFO,format="%(asctime)s | %(levelname)s | %(module)s:%(funcName)s:%(lineno)d - %(message)s",datefmt="%Y-%m-%d %H:%M:%S",
)
logger = logging.getLogger(__name__)def main():logger.debug("This is a debug message")logger.info("This is an info message")logger.warning("This is a warning message")logger.error("This is an error message")if __name__ == "__main__":main()

运行上述代码,结果如下:
在这里插入图片描述
可以看到,传统的日志记录方法使用 % 制定格式,使用起来并不直观;与之对比,Loguru 使用的{}来指定格式更易读、更易用:

from loguru import loggerlogger.add(sys.stdout,level="INFO",format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {module}:{function}:{line} - {message}",
)

4. 将日志保存到文件

使用传统日志模块logging将日志保存到文件并打印到终端需要两个额外的类 FileHandler StreamHandler, 示例代码如下:

import logging
logging.basicConfig(level=logging.DEBUG,format="%(asctime)s | %(levelname)s | %(module)s:%(funcName)s:%(lineno)d - %(message)s",datefmt="%Y-%m-%d %H:%M:%S",handlers=[logging.FileHandler(filename="info.log", level=logging.INFO),logging.StreamHandler(level=logging.DEBUG),],
)logger = logging.getLogger(__name__)
def main():logging.debug("This is a debug message")logging.info("This is an info message")logging.warning("This is a warning message")logging.error("This is an error message")if __name__ == "__main__":main()

不过,有了 Loguru之后,大家只需使用add函数就能实现相同的功能。代码如下:

from loguru import logger
logger.add('info.log',format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {module}:{function}:{line} - {message}",level="INFO",
)def main():logger.debug("This is a debug message")logger.info("This is an info message")logger.warning("This is a warning message")logger.error("This is an error message")
if __name__ == "__main__":main()

5. 日志过滤

日志过滤功能可以让大家根据特定条件有选择性地控制输出哪些日志记录。在日志库logging 中,过滤日志需要创建一个自定义日志过滤类。

import logging
logging.basicConfig(filename="hello.log",format="%(asctime)s | %(levelname)-8s | %(module)s:%(funcName)s:%(lineno)d - %(message)s",level=logging.INFO,
)class CustomFilter(logging.Filter):def filter(self, record):return "Hello" in record.msg
# Create a custom logging filter
custom_filter = CustomFilter()# Get the root logger and add the custom filter to it
logger = logging.getLogger()
logger.addFilter(custom_filter)def main():logger.info("Hello World")logger.info("Bye World")if __name__ == "__main__":main()

对比在Loguru 中,我们只需使用 lambda 函数即可实现同样的过滤功能,代码如下:

from loguru import loggerlogger.add("hello.log", filter=lambda x: "Hello" in x["message"], level="INFO")def main():logger.info("Hello World")logger.info("Bye World")if __name__ == "__main__":main()

运行上述代码后,我们可以在终端看到以下输出:

在这里插入图片描述
同时在日志文件hello.log中,只保存我们过滤后的信息,如下所示:
在这里插入图片描述

6. 总结

虽然将Loguru 纳入项目需要使用pip install loguru来额外进行安装,但它非常轻便,占用的磁盘空间也很小。此外,它还有助于减少记日志的代码量,而且使用起来更加直观和便捷,推荐大家在日常工作中多多使用!

您学废了嘛?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/803352.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实现首选目标|国内博士后赴新加坡继续从事博士后研究

申请时,V博士尚为国内在站的博士后,其希望在我们的帮助下,加入国外导师先进的课题组,在拓展学术视野的同时,延续自己的科研项目并结题,目标国家首选新加坡。最终我们用新加坡科技研究局(A*STA&a…

TiDB 实战分享丨第三方支付企业的核心数据库升级之路

本文介绍了一家第三方支付企业在面对市场竞争和监管压力的态势下,通过升级核心数据库来提升业务能力的实践。该企业选择 TiDB 分布式数据库,成功将其应用于核心业务、计费、清结算和交易查询等关键系统。TiDB 的水平扩展能力、高可用性和简化数据栈等优势…

electron打包Vue前端

Electron-Forge 打包Vue项目 效果:electronforge可将前端静态页面打包成.exe、.deb和.rpm等,能适配各种平台 示例:Windows环境下将前端 Vue 项目打包成exe文件 打包后的 exe 文件 运行 exe 文件 一、项目准备 开源项目 RouYi 下载 本…

码蹄集部分题目(第五弹;OJ赛2024年第10期)

🐋🐋🐋竹鼠通讯(钻石;分治思想;模板题:就算几何平面点对问题) 时间限制:3秒 占用内存:128M 🐟题目描述 在真空中,一块无限平坦光滑…

自偏置电流镜、wilson和cascode电流镜、低压自偏置电流镜

1.自偏置电流镜 参考1:正确偏置和自启动电路 正确偏置: 2.自启动电路 参考2:两种自启动电路、cascode低压设计、自启动充放电过程分析 3.低压自偏置电流镜 参考3:电阻偏置分析 VbVgs3VodVgs1Vod 4.电阻偏置和MOS偏置的分…

【C++】动态规划算法

目录 还会持续更新动态规划斐波那契模型三步问题最小花费爬楼梯 路径问题不同路径路径问题Ⅱ 简单多状态按摩师 还会持续更新 动态规划 什么是动态规划? 斐波那契模型 三步问题 class Solution { public: const int N 1000009;int waysToStep(int n) {if(n1) …

服务器远程桌面连接不上怎么办?

随着互联网的发展和远程办公的兴起,服务器远程桌面连接成为了许多企业和个人不可或缺的工具。偶尔我们可能会碰到服务器远程桌面连接不上的情况,这时候我们需要找到解决办法,确保高效地远程访问服务器。 天联组网——突破远程连接障碍 在我们…

前端二维码工具小程序使用说明书

一、产品概述 前端二维码工具小程序是一款便捷、高效、易用的二维码生成与识别工具。本产品支持根据用户输入的文本或链接生成二维码,同时提供扫一扫功能以识别二维码内容,并支持将识别到的内容复制到剪贴板。此外,产品还提供了美化功能&…

Armadillo库:用于线性代数和科学计算的快速C/C++库下载及vs环境下的使用方法

armadillo库的下载及使用 一. armadillo库的下载二. vs2022环境下armadillo库的基本使用方法 一. armadillo库的下载 armadillo库的官方下载连接: https://arma.sourceforge.net/download.html 选择网页中最新版本的armadillo库压缩包文件进行下载。 解压armadillo-12.8.2.ta…

无重复的最长字串

📝个人主页:五敷有你 🔥系列专栏:算法分析与设计 ⛺️稳中求进,晒太阳 问题 给定一个字符串,我们需要找到该字符串中的最长无重复子串的长度。 示例 让我们以一个具体的示例来说明这个问题&#…

场景文本检测识别学习 day02(AlexNet论文阅读、ResNet论文精读)

怎么读论文 在第一遍阅读的时候,只需要看题目,摘要和结论,先看题目是不是跟我的方向有关,看摘要是不是用到了我感兴趣的方法,看结论他是怎么解决摘要中提出的问题,或者怎么实现摘要中的方法,然…

Elementplus 2.6.1表单校验模块开发体验改进

需求 之前的表单代码看了下,写的比较冗长,于是去万能的Github找点轮子,发现了这个: GitHub - aweiu/element-ui-verify: 如果你受够了饿了么ElementUI原生的校验方式,那就来试试它吧!一款更懂你的校验插件…

Taro框架中的H5 模板基本搭建

1.H5 模板框架的搭建 一个h5 的基本框架的搭建 基础template 阿乐/H5 Taro 的基础模板

Java多线程实战-从零手搓一个简易线程池(四)线程池生命周期状态流转实现

🏷️个人主页:牵着猫散步的鼠鼠 🏷️系列专栏:Java全栈-专栏 🏷️本系列源码仓库:多线程并发编程学习的多个代码片段(github) 🏷️个人学习笔记,若有缺误,欢迎评论区指正…

nexus设置s3存储

问题 因为我的nexus是安装在EC2上面,需要利用s3的存储能力,为nexus提供存储服务。 步骤 准备s3桶 输入桶名,创建s3桶,如下图: 创建桶读写策略 具体内容如下: {"Version": "2012-10-1…

c++之代码编译问题

为什么头文件不是编译的对象 1、头文件与包含指令(#include) 那些没有被项目中任何源文件包含的头文件,编译器是不去理会它的,不管它有没有语法错误,也不管它是否已添加到项目中。 2、包含指令的执行 包含指令是一种预编译指令,它…

如何区别进化和演化

在生物学中,"进化"和"演化"这两个词通常可以互换使用,它们都指的是生物种群随时间推移而发生的遗传变化。然而,在某些语境中,这两个词可能会有细微的差别: 进化(Evolution)…

[翻译] 在 CI 或测试环境中使用 Docker-in-Docker,三思而后行

发布日期:2024-04-08 18:01:01 原文地址:Using Docker-in-Docker for your CI or testing environment? Think twice. Docker-in-Docker 的主要目的是帮助 Docker 本身的开发。许多人使用它来运行 CI(例如使用 Jenkins)&#xf…

[NKCTF2024]-PWN:leak解析(中国剩余定理泄露libc地址,汇编覆盖返回地址)

查看保护 查看ida 先放exp 完整exp: from pwn import* from sympy.ntheory.modular import crt context(log_leveldebug,archamd64)while True:pprocess(./leak)ps[101,103,107,109,113,127]p.sendafter(bsecret\n,bytes(ps))cs[0]*6for i in range(6):cs[i]u32(p…

Java 基于微信小程序的校园请教小程序的研究与实现,附源码

博主介绍:✌程序员徐师兄、10年大厂程序员经历。全网粉丝12W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅&#x1f447…