loguru模块bind和filter的联合使用案例:将loguru改造为csv数据记录器

目录

    • 使用场景
    • filter函数
    • bind函数
    • 赋予日志记录一个`label`的属性
      • 实际案例代码

使用场景

在运行程序的过程中,通常需要使用设置日志信息来方便追踪程序运行状态或者是调试,也常常需要进行多次运算并将计算结果进行保存。一般来说,日志信息可以通过logging模块保存,而计算数据的记录常常是基于文本文件的读写功能实现的。如果要统一的实现两个功能,可以通过改造loguru模块进行实现。

这个实现主要是基于filter机制和bind方法

filter函数

使用 loguru 库进行 Python 日志记录时,可以通过定义自定义 filter 函数来收集特定的日志信息。该函数接受一个记录作为参数,并返回一个布尔值:如果返回 True,则记录该日志;如果返回 False,则不记录。

这个 filter 函数可以基于:

  • 日志消息的内容:record["message"]
  • 级别:record["level"]
  • 或者其他任何可用的日志属性来决定是否应该记录该条日志

注意,filter是要在添加``handler时进行配置,将 filter函数作为handlerfilter`参数。

from loguru import loggerdef important_log_filter(record):# 只有当日志消息中包含 "重要" 关键字时,才记录该日志return "重要" in record["message"]# 配置 logger,添加一个 handler,仅记录通过 filter 函数筛选的日志
logger.add("important_logs.log", filter=important_log_filter)# 使用示例
logger.info("这是一条普通日志,不会被记录")
logger.info("这是一条重要日志,将会被记录")

bind函数

bind() 方法是一个强大的功能,用于向日志记录附加额外的上下文信息。这种方法非常有用,因为它允许为日志消息添加元数据,而无需在每次记录日志时重复这些信息。

bind() 的特点是不接受一组预定义的参数,而是接受任意数量的关键字参数,这些参数随后会成为日志消息的一部分,增加了日志的描述性和可追溯性,如用户ID、请求ID或任何其他对理解或分析日志有帮助的数据。而这些字段都会添加到 record["extra"]中,然后可以在:

  • filter函数

    from loguru import loggerdef user_filter(record):# 假设我们只对 user_id 为 "123" 的日志消息感兴趣return record["extra"].get("user_id") == "123"# 配置 logger,添加一个 handler,仅记录通过 user_filter 函数筛选的日志
    logger.add("filtered_logs.log", filter=user_filter)# 绑定 user_id 并尝试记录几条消息
    logger.bind(user_id="123").info("这条消息会被记录,因为用户ID匹配")
    logger.bind(user_id="456").info("这条消息不会被记录,因为用户ID不匹配")
  • format字符串or函数中

    # 自定义日志格式,包括绑定的上下文信息
    format = "{time} | {level} | {extra[user_id]} | {message}"# 添加一个 handler,使用上述格式
    logger.add("my_log.log", format=format)# 使用绑定的 logger 记录日志
    logger.info("完成了一个任务")

    用户ID是通过 bind() 方法绑定到日志记录器上的。

通过record["extra"][key"]进行使用。

bind() 方法返回一个新的 logger 实例,这个实例在其所有日志记录中自动包含了绑定的上下文信息。这意味着可以在程序的特定部分创建一个带有特定上下文的 logger,而不会影响全局 logger 实例或其他带有不同上下文的 logger 实例。

就是说,bind方法不会影响原来的logger实例的上下文信息

from loguru import logger# 原始 logger 实例
logger.info("这是一条没有上下文信息的日志消息")# 使用 bind() 添加上下文信息,创建一个新的 logger 实例
logger_with_context = logger.bind(user_id="123")# 使用新的 logger 实例记录消息
logger_with_context.info("这条消息包含上下文信息")# 再次使用原始 logger 实例记录消息
logger.info("这又是一条没有上下文信息的日志消息")

注意

  • 使用 logurubind() 方法时,不需要重新指定日志文件路径。
  • 需要在应用的不同部分添加不同的上下文信息时,可以在各个部分使用 bind() 方法,这样可以确保日志消息包含了正确的上下文信息,而不需要为每个上下文重新配置日志路径。
  • bind().add()loguru 中扮演了不同的角色:.add() 用于配置日志的输出目标和格式,而 bind() 用于为日志消息添加上下文信息。

赋予日志记录一个label的属性

这里的意图是,通过一个label="data"的标签,实现重要数据和程序运行信息分离的功能

loguru 库中,直接给日志消息指定一个标签(如 label 属性)并不是内置的功能,但是可以通过自定义消息格式来间接实现这个目的。要达到这个目的,需要联合filterbind

  1. 只使用 Filter 函数动态添加标签

    通过自定义函数,确实可以达到动态添加label属性的方法,但是这种方法比较低效,因为要通过判断reord的一些属性来实现,另外就是不方便手动控制:

    from loguru import loggerdef tag_logger(record):# 假设我们根据消息的内容动态添加标签if "错误" in record["message"]:record["extra"]["label"] = "错误"else:record["extra"]["label"] = "通用"# 配置 logger,添加一个 handler,并使用自定义的 filter 函数
    logger.add("tagged_logs.log", filter=tag_logger, format="{time} | {level} | {extra[label]} | {message}")# 发送日志消息
    logger.info("这是一条普通消息")
    logger.error("这是一条包含错误的消息")
  2. 通过bind添加上下文信息,并进行显示格式化。

    这个方法,添加label属性,就比较方便,只要引用bind后的logger实例就行。

    from loguru import logger# 定义一个自定义的日志格式,其中包含了消息的标签
    log_format = "<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{extra[label]}</cyan> | <white>{message}</white>"# 配置 logger,使用自定义的格式
    # 注意:需要确保所有的日志消息都添加了相应的 `label`,否则会抛出 KeyError
    logger.add("labeled_logs.log", format=log_format, level="INFO")# 发送一条带有标签的日志消息
    logger.bind(label="特别").info("这是一条带有标签的日志")

    在这个例子中,通过 .bind() 方法为日志消息附加了额外的上下文信息( label 标签),然后在自定义日志格式中引用了这个标签,并设定格式。

实际案例代码

  1. bind和filter联合使用。

    这样组合,能完成的功能更丰富。也很实现运行记录和计算数据的分别记录器。

    from loguru import logger
    import sysdef only_trace(record):'''只保存程序的运行记录:param record::return:'''return "data" not in record["extra"]def only_data(record):return "data" in record["extra"]# 移除默认的控制台输出
    logger.remove()# 自定义日志格式
    log_format = "<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level}</level> | <cyan>{name}</cyan>: <cyan>{line}</cyan> - <level>{message}</level>"
    # 添加控制台handler,使用自定义格式
    logger.add(sys.stdout, format=log_format)
    logger.add("./log/app_trace.log", format=log_format,filter=only_trace, level="DEBUG")
    data_format = "{time:YYYY-MM-DD HH:mm:ss}\t{message}"# 写模式,每次程序启动并添加 handler 时,app_data.csv 将会被新内容覆盖。
    logger.add("./log/app_data.csv", format=data_format,filter=only_data, level="DEBUG",mode="w")
    data_logger=logger.bind(data=True)def get_logger():return logger
    def get_datalogger():return data_logger
    

注意,这里没有添加``label标签,而是直接给data=True这样的上下文,方便filter函数的构造

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

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

相关文章

『论文阅读|研究用于视障人士户外障碍物检测的 YOLO 模型』

研究用于视障人士户外障碍物检测的 YOLO 模型 摘要1 引言2 相关工作2.1 障碍物检测的相关工作2.2 物体检测和其他基于CNN的模型 3 问题的提出4 方法4.1 YOLO4.2 YOLOv54.3 YOLOv64.4 YOLOv74.5 YOLOv84.6 YOLO-NAS 5 实验和结果5.1 数据集和预处理5.2 训练和实现细节5.3 性能指…

【内网穿透】如何在小米4A中刷OpenWRT并实现公网访问本地路由器

文章目录 前言1. 安装Python和需要的库2. 使用 OpenWRTInvasion 破解路由器3. 备份当前分区并刷入新的Breed4. 安装cpolar内网穿透4.1 注册账号4.2 下载cpolar客户端4.3 登录cpolar web ui管理界面4.4 创建公网地址 5. 固定公网地址访问 前言 OpenWRT是一个高度模块化、高度自…

motplotlib图例案例1:通过多个legend完全控制图例显示顺序(指定按行排序 or 按列排序)

这个方法的核心&#xff0c;是手动的获得图中的handlers和labels&#xff0c;然后对它们进行切分和提取&#xff0c;最后分为几个legend进行显示。代码如下&#xff1a; 后来对下面的代码进行修改&#xff0c;通过handlers, labels get_legend_handles_labels(axs[axis])自动的…

新年红包的题解

目录 原题描述&#xff1a; 题目描述 题目背景 题目描述 输入格式 输出格式 样例 Input 1 Output 1 Input 2 Output 2 数据范围 主要思路&#xff1a; 代码code&#xff1a; 原题描述&#xff1a; 题目描述 题目背景 龙飞凤舞迎跨年&#xff0c;瑞雪飘飘送祝愿…

PS的常用快捷方式有哪些?

Adobe Photoshop&#xff08;简称 PS&#xff09;是一款流行的图像处理软件。以下是一些常用的 Photoshop 快捷方式&#xff1a; 文件操作&#xff1a; 新建文件&#xff1a;Ctrl N&#xff08;Windows&#xff09;/ Command N&#xff08;Mac&#xff09;打开文件&#xff1…

Spring Boot 笔记 024 登录页面

1.1 登录接口 //导入request.js请求工具 import request from /utils/request.js//提供调用注册接口的函数 export const userRegisterService (registerData)>{//借助于UrlSearchParams完成传递const params new URLSearchParams()for(let key in registerData){params.a…

LabVIEW风力机智能叶片控制系统

​LabVIEW风力机智能叶片控制系统 介绍了一种风力机智能叶片控制系统的开发。通过利用LabVIEW软件与CDS技术&#xff0c;该系统能够实时监测并调整风力机叶片的角度&#xff0c;优化风能转换效率。此项技术不仅提高了风力发电的稳定性和效率&#xff0c;而且为风力机的智能化管…

SpringBoot源码解读与原理分析(五)SpringBoot的装配机制

文章目录 2.5 Spring Boot的装配机制2.5.1 ComponentScan2.5.1.1 ComponentScan的基本使用方法2.5.1.2 TypeExcludeFilter(类型排除过滤器)2.5.1.3 AutoConfigurationExcludeFilter(自动配置类排除过滤器) 2.5.2 SpringBootConfiguration2.5.3 EnableAutoConfiguration2.5.3.1 …

世界顶级名校计算机专业,都在用哪些书当教材?

前言 在当今信息化、数字化时代&#xff0c;计算机科学已成为全球最为热门和重要的学科之一。世界顶级名校的计算机专业&#xff0c;更是培养未来行业领袖和创新人才的重要基地。那么&#xff0c;这些名校的计算机专业究竟使用哪些教材呢&#xff1f;这些教材又具有哪些特色和…

LabVIEW智能家居控制系统

LabVIEW智能家居控制系统 介绍了一个基于LabVIEW的智能家居控制系统的开发过程。该系统利用LabVIEW软件与硬件设备相结合&#xff0c;通过无线网络技术实现家居环境的实时监控与控制&#xff0c;提升居住舒适度和能源使用效率。 项目背景&#xff1a;随着科技的发展和生活水平…

BIO、NIO、Netty演化总结之二(手撸一个极简版netty)

之前的一片文章里面总结了一下IO模型的演进&#xff08;BIO、NIO、Netty演化总结-CSDN博客&#xff09;&#xff0c;里面给了一个示例AsyncNonBlockingServerWithThreadPool&#xff0c;最近想了想&#xff0c;发现这个代码跟netty的模型还是有一些出入&#xff0c;说是netty的…

【MATLAB】BiGRU神经网络回归预测算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 BiGRU神经网络回归预测算法是一种基于双向门控循环单元&#xff08;GRU&#xff09;的多变量时间序列预测方法。该方法结合了双向模型和门控机制&#xff0c;旨在有效地捕捉时间序列数据中…

【设计模式】详细聊聊软件设计的七大原则

软件设计原则 软件设计原则是指在进行软件系统设计时所遵循的一系列指导原则&#xff0c;它们旨在帮助软件工程师设计出高质量、易维护、可扩展和可重用的软件系统。这些原则是经过实践验证的&#xff0c;能够在软件开发的各个阶段提供指导和支持。七大软件设计原则&#xff0c…

高级前端面试题及详解

当准备高级前端面试时&#xff0c;除了掌握基本的前端知识外&#xff0c;还需要深入了解一些更高级的概念和技术。以下是一些常见的高级前端面试题及其详解&#xff0c;希望能帮助你更好地准备面试。 什么是闭包&#xff1f;请举一个闭包的例子并解释其工作原理。 闭包是指函数…

如何利用Idea创建一个Servlet项目(新手向)

&#x1f495;"Echo"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;如何利用Idea创建一个Servlet项目(新手向) Servlet是tomcat的api,利用Servlet进行webapp开发很方便,本文将介绍如何通过Idea创建一个Servlet项目(一共分为七步,这可能是我们写过的…

Kotlin函数和对象

1.高阶函数 如果一个函数的参数是函数类型或者返回值是函数类型&#xff0c;那么这个函数就是高阶函数。 在kotlin中函数也是有类型的&#xff0c;跟整型、字符串类型是同样的性质&#xff0c;函数类型就是将函数的“输入参数类型”和“返回值类型”的抽象表达&#xff0c;如&…

C#使用MiniExcel导入导出数据到Excel/CSV文件

MiniExcel简介 简单、高效避免OOM的.NET处理Excel查、写、填充数据工具。 目前主流框架大多需要将数据全载入到内存方便操作&#xff0c;但这会导致内存消耗问题&#xff0c;MiniExcel 尝试以 Stream 角度写底层算法逻辑&#xff0c;能让原本1000多MB占用降低到几MB&#xff…

论文阅读,ProtoGen: Automatically Generating Directory Cache Coherence Protocols(三)

目录 一、Article:文献出处&#xff08;方便再次搜索&#xff09; &#xff08;1&#xff09;作者 &#xff08;2&#xff09;文献题目 &#xff08;3&#xff09;文献时间 &#xff08;4&#xff09;引用 二、Data:文献数据&#xff08;总结归纳&#xff0c;方便理解&am…

扫地机器人与项目管理

最近家里新装了一台扫地机器人&#xff0c;可以远程操控&#xff0c;每次回家前&#xff0c;都让它扫拖一遍&#xff0c;非常的干净。家里东西摆放比较杂乱&#xff0c;每次它要清理的面积都是一个不规则图形。通过几次的观察&#xff0c;发现它总是把要清理的区域先整个画一个…

1057:简单计算器

题目描述】 一个最简单的计算器&#xff0c;支持, -, *, / 四种运算。仅需考虑输入输出为整数的情况&#xff0c;数据和运算结果不会超过int表示的范围。然而&#xff1a; 1. 如果出现除数为0的情况&#xff0c;则输出&#xff1a;Divided by zero! 2. 如果出现无效的操作符(即…