自己做网站转发新闻违法么,泰安做网站的,wordpress 卢晓松,吉林市网站建设公司目录 使用场景filter函数bind函数赋予日志记录一个label的属性实际案例代码 使用场景
在运行程序的过程中#xff0c;通常需要使用设置日志信息来方便追踪程序运行状态或者是调试#xff0c;也常常需要进行多次运算并将计算结果进行保存。一般来说#xff0c;日志信息可以通… 目录 使用场景filter函数bind函数赋予日志记录一个label的属性实际案例代码 使用场景
在运行程序的过程中通常需要使用设置日志信息来方便追踪程序运行状态或者是调试也常常需要进行多次运算并将计算结果进行保存。一般来说日志信息可以通过logging模块保存而计算数据的记录常常是基于文本文件的读写功能实现的。如果要统一的实现两个功能可以通过改造loguru模块进行实现。
这个实现主要是基于filter机制和bind方法
filter函数
使用 loguru 库进行 Python 日志记录时可以通过定义自定义 filter 函数来收集特定的日志信息。该函数接受一个记录作为参数并返回一个布尔值如果返回 True则记录该日志如果返回 False则不记录。
这个 filter 函数可以基于
日志消息的内容:record[message]级别:record[level]或者其他任何可用的日志属性来决定是否应该记录该条日志
注意filter是要在添加handler时进行配置将 filter函数作为handler的filter参数。
from loguru import loggerdef important_log_filter(record):# 只有当日志消息中包含 重要 关键字时才记录该日志return 重要 in record[message]# 配置 logger添加一个 handler仅记录通过 filter 函数筛选的日志
logger.add(important_logs.log, filterimportant_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, filteruser_filter)# 绑定 user_id 并尝试记录几条消息
logger.bind(user_id123).info(这条消息会被记录因为用户ID匹配)
logger.bind(user_id456).info(这条消息不会被记录因为用户ID不匹配) format字符串or函数中 # 自定义日志格式包括绑定的上下文信息
format {time} | {level} | {extra[user_id]} | {message}# 添加一个 handler使用上述格式
logger.add(my_log.log, formatformat)# 使用绑定的 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_id123)# 使用新的 logger 实例记录消息
logger_with_context.info(这条消息包含上下文信息)# 再次使用原始 logger 实例记录消息
logger.info(这又是一条没有上下文信息的日志消息) 注意
使用 loguru 的 bind() 方法时不需要重新指定日志文件路径。需要在应用的不同部分添加不同的上下文信息时可以在各个部分使用 bind() 方法这样可以确保日志消息包含了正确的上下文信息而不需要为每个上下文重新配置日志路径。bind() 和 .add() 在 loguru 中扮演了不同的角色.add() 用于配置日志的输出目标和格式而 bind() 用于为日志消息添加上下文信息。
赋予日志记录一个label的属性 这里的意图是通过一个labeldata的标签实现重要数据和程序运行信息分离的功能 在 loguru 库中直接给日志消息指定一个标签如 label 属性并不是内置的功能但是可以通过自定义消息格式来间接实现这个目的。要达到这个目的需要联合filter和bind 只使用 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, filtertag_logger, format{time} | {level} | {extra[label]} | {message})# 发送日志消息
logger.info(这是一条普通消息)
logger.error(这是一条包含错误的消息) 通过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, formatlog_format, levelINFO)# 发送一条带有标签的日志消息
logger.bind(label特别).info(这是一条带有标签的日志) 在这个例子中通过 .bind() 方法为日志消息附加了额外的上下文信息 label 标签然后在自定义日志格式中引用了这个标签并设定格式。
实际案例代码 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, formatlog_format)
logger.add(./log/app_trace.log, formatlog_format,filteronly_trace, levelDEBUG)
data_format {time:YYYY-MM-DD HH:mm:ss}\t{message}# 写模式每次程序启动并添加 handler 时app_data.csv 将会被新内容覆盖。
logger.add(./log/app_data.csv, formatdata_format,filteronly_data, levelDEBUG,modew)
data_loggerlogger.bind(dataTrue)def get_logger():return logger
def get_datalogger():return data_logger注意这里没有添加label标签而是直接给dataTrue这样的上下文方便filter函数的构造