【Rust】使用日志记录利器flexi_logger

Flexi_logger简介

flexi_logger​是一个功能强大且灵活的日志记录库,用于Rust语言的应用程序。它提供了丰富的配置选项和功能,适用于各种日志记录需求,从简单的控制台输出到复杂的文件日志管理。以下是对flexi_logger​的一些关键功能和特性的简介:

主要功能

  • 多种日志目标:支持将日志输出到控制台、文件或同时输出到多个目标
  • 日志文件滚动:支持基于文件大小或时间的日志文件滚动,可以按大小、时间(每天、每小时等)进行切分
  • 日志文件清理:可以配置保留的日志文件数量,自动删除过期的日志文件
  • 日志格式自定义:支持自定义日志格式,可以包含时间戳、日志级别、目标模块等信息
  • 日志级别过滤:支持设置不同的日志级别(如info​、warn​、error​等),只记录满足级别要求的日志消息
  • 异步日志:支持异步写日志,提高性能
  • 日志复制:可以将日志复制到标准输出(stdout)或标准错误(stderr)

使用示例

创建项目

cargo new rs_demo

Cargo.toml

[package]
name = "rs_demo"
version = "0.1.0"
edition = "2021"[dependencies]
log = "0.4"
flexi_logger = "0.22"
time = "0.3"

main.rs

use log::{trace, debug, info, warn, error};
use flexi_logger::{Duplicate, FileSpec, Logger, WriteMode, Criterion, Naming, Cleanup, detailed_format};// 定义一个结构体 `Rectangle`
struct Rectangle {width: u32,height: u32,
}// 为 `Rectangle` 实现方法
impl Rectangle {// 关联函数(类似于静态方法)fn new(width: u32, height: u32) -> Rectangle {Rectangle { width, height }}// 实例方法fn area(&self) -> u32 {self.width * self.height}// 实例方法fn perimeter(&self) -> u32 {2 * (self.width + self.height)}// 修改实例的方法fn set_width(&mut self, width: u32) {self.width = width;}
}fn main() {// 初始化日志记录,配置输出到文件,设置文件大小限制和滚动日志let logger = Logger::try_with_str("trace").unwrap().log_to_file(FileSpec::default().directory("logs") // 设置日志文件目录.basename("app")   // 设置日志文件前缀.suffix("log")     // 设置日志文件后缀).rotate(Criterion::Size(10_000_000), // 设置日志文件大小限制为 10 MBNaming::Numbers,             // 使用数字序号进行文件命名Cleanup::KeepLogFiles(3),    // 保留最近的 3 个日志文件).write_mode(WriteMode::BufferAndFlush) // 设置日志写入模式.duplicate_to_stderr(Duplicate::Warn)  // 将警告级别的日志复制到标准错误输出.format_for_files(detailed_format)     // 使用详细格式,包含时间戳.start().unwrap();// 记录不同级别的日志消息trace!("This is a trace message.");debug!("This is a debug message.");info!("This is an info message.");warn!("This is a warning message.");error!("This is an error message.");// 使用关联函数创建一个 `Rectangle`let mut rect = Rectangle::new(30, 50);// 调用实例方法info!("The area of the rectangle is {} square pixels.", rect.area());info!("The perimeter of the rectangle is {} pixels.", rect.perimeter());// 修改实例的字段rect.set_width(40);info!("After resizing, the area of the rectangle is {} square pixels.", rect.area());// 强制刷新日志缓冲区logger.flush();
}

这里的配置包括:

  • 日志文件目录:日志文件将被保存到logs目录中
  • 日志文件前缀:日志文件将以app作为前缀
  • 日志文件后缀:日志文件将以.log作为后缀
  • 日志文件滚动策略:当日志文件大小达到10 MB时,日志文件将滚动,新的日志文件将使用时间戳命名
  • 日志文件保留策略:只保留最近的3个日志文件
  • 日志写入模式:使用缓冲并在写入时刷新
  • 日志复制到标准错误输出:将警告级别的日志消息复制到标准错误输出
  • 日志格式:使用详细格式,包含时间戳

在Rust的log库中,不同的日志宏可以记录不同级别的日志消息。这些日志级别分别是:

  • trace!:最详细的日志信息,通常用于跟踪程序的细节流程
  • debug!:用于调试时的信息,比 trace! 略少,但仍然非常详细
  • info!:一般信息,不含调试细节,适合普通运行时的信息
  • warn!:警告信息,表明某些事情可能会出问题,但程序可以继续运行
  • error!:错误信息,表明发生了严重的问题,程序可能无法继续运行

日志文件数据:

[2024-07-17 21:08:07.689886 +08:00] TRACE [rs_demo] src/main.rs:55: This is a trace message.
[2024-07-17 21:08:07.691157 +08:00] DEBUG [rs_demo] src/main.rs:56: This is a debug message.
[2024-07-17 21:08:07.691170 +08:00] INFO [rs_demo] src/main.rs:57: This is an info message.
[2024-07-17 21:08:07.697314 +08:00] WARN [rs_demo] src/main.rs:58: This is a warning message.
[2024-07-17 21:08:07.707785 +08:00] ERROR [rs_demo] src/main.rs:59: This is an error message.
[2024-07-17 21:08:07.707804 +08:00] INFO [rs_demo] src/main.rs:65: The area of the rectangle is 1500 square pixels.
[2024-07-17 21:08:07.707809 +08:00] INFO [rs_demo] src/main.rs:66: The perimeter of the rectangle is 160 pixels.
[2024-07-17 21:08:07.707814 +08:00] INFO [rs_demo] src/main.rs:70: After resizing, the area of the rectangle is 2000 square pixels.

自定义日志的输出格式

使用format_for_files函数可以用于自定义日志的输出格式。定义一个名为custom_format的函数,并将其传递给format_for_files以使用自定义格式记录日志

custom_format中:

  • w:一个实现了Write trait的可写对象,日志消息将被写入这个对象
  • record:一个Record对象,包含了日志记录的详细信息
use log::{info};
use flexi_logger::{DeferredNow, Duplicate, FileSpec, Logger, Record, WriteMode, Criterion, Naming, Cleanup};
use std::io::Write;
use time::format_description::well_known::Rfc3339;
use time::OffsetDateTime;// 定义一个结构体 `Rectangle`
struct Rectangle {width: u32,height: u32,
}// 为 `Rectangle` 实现方法
impl Rectangle {// 关联函数(类似于静态方法)fn new(width: u32, height: u32) -> Rectangle {Rectangle { width, height }}// 实例方法fn area(&self) -> u32 {self.width * self.height}// 实例方法fn perimeter(&self) -> u32 {2 * (self.width + self.height)}// 修改实例的方法fn set_width(&mut self, width: u32) {self.width = width;}
}fn custom_format(w: &mut dyn Write,_now: &mut DeferredNow,record: &Record,
) -> std::io::Result<()> {let now = OffsetDateTime::now_utc().format(&Rfc3339).unwrap();write!(w,"{} [{}] - {} - {}",now,record.level(),record.target(),record.args())
}fn main() {// 初始化日志记录,配置输出到文件,设置文件大小限制和滚动日志let logger = Logger::try_with_str("info").unwrap().log_to_file(FileSpec::default().directory("logs") // 设置日志文件目录.basename("app")   // 设置日志文件前缀.suffix("log")     // 设置日志文件后缀).rotate(Criterion::Size(10_000_000), // 设置日志文件大小限制为 10 MBNaming::Numbers,             // 使用数字序号进行文件命名Cleanup::KeepLogFiles(3),    // 保留最近的 3 个日志文件).write_mode(WriteMode::BufferAndFlush) // 设置日志写入模式.duplicate_to_stderr(Duplicate::Warn)  // 将警告级别的日志复制到标准错误输出.format_for_files(custom_format)       // 使用自定义格式.start().unwrap();// 记录不同级别的日志消息info!("This is an info message.");// 使用关联函数创建一个 `Rectangle`let mut rect = Rectangle::new(30, 50);// 调用实例方法info!("The area of the rectangle is {} square pixels.", rect.area());info!("The perimeter of the rectangle is {} pixels.", rect.perimeter());// 修改实例的字段rect.set_width(40);info!("After resizing, the area of the rectangle is {} square pixels.", rect.area());// 强制刷新日志缓冲区logger.flush();
}
2024-07-17T12:28:34.701362Z [INFO] - rs_demo - This is an info message.
2024-07-17T12:28:34.7024068Z [INFO] - rs_demo - The area of the rectangle is 1500 square pixels.
2024-07-17T12:28:34.7024153Z [INFO] - rs_demo - The perimeter of the rectangle is 160 pixels.
2024-07-17T12:28:34.7024181Z [INFO] - rs_demo - After resizing, the area of the rectangle is 2000 square pixels.

验证日志文件大小和保留日志文件个数

下面通过一个无限循环不断地写入日志消息,从而测试日志文件的滚动和清理功能。这种设置在实际应用中可能用于持续记录应用程序的运行状态或调试信息

use log::info;
use flexi_logger::{Logger, FileSpec, Criterion, Naming, Cleanup, WriteMode, Duplicate, detailed_format};
use std::thread;
use std::time::Duration;fn main() {// 初始化日志记录,配置输出到文件,设置文件大小限制和滚动日志let _logger = Logger::try_with_str("info").unwrap().log_to_file(FileSpec::default().directory("logs") // 设置日志文件目录.basename("app") // 设置日志文件前缀.suffix("log")     // 设置日志文件后缀).rotate(Criterion::Size(5_000), // 设置日志文件大小限制为 5 KBNaming::Timestamps,         // 使用时间戳进行文件命名Cleanup::KeepLogFiles(3),   // 保留最近的 3 个日志文件).write_mode(WriteMode::BufferAndFlush) // 设置日志写入模式.duplicate_to_stderr(Duplicate::Warn)  // 将警告级别的日志复制到标准错误输出.format_for_files(detailed_format)     // 使用详细格式,包含时间戳.start().unwrap();// 无限循环,不断写入日志loop {info!("This is an info message.");// 模拟一些工作,等待一段时间thread::sleep(Duration::from_secs(1));}
}

运行程序数分钟,查看日志文件夹,文件夹目录结构如下,“rCURRENT.log”代表当前程序正在写入的日志文件,剩余的三个日志文件为程序保留的三个日志文件,日志文件都含有时间戳,并且不会随着程序运行的时间延长而新增文件个数

├─logs
│      app_r2024-07-17_20-44-24.log
│      app_r2024-07-17_20-45-19.log
│      app_r2024-07-17_20-46-15.log
│      app_rCURRENT.log

日志输出到控制台和文件

使用duplicate_to_stdout(Duplicate::All)方法,将所有级别的日志复制到标准输出(控制台)

.duplicate_to_stdout(Duplicate::All)   // 将所有级别的日志复制到标准输出

这样,控制台能看到所有输出到日志文件的日志信息

按时间切分日志文件

Criterion::Age表示按时间切分日志文件,flexi_logger::Age::Day指定了按每天切分日志文件。这样,每天会生成一个新的日志文件

Criterion::Age(flexi_logger::Age::Day), // 设置日志文件按日切分

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

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

相关文章

观察者模式-C#

在C#中实现观察者模式&#xff0c;通常涉及两个主要的组件&#xff1a;主题&#xff08;Subject&#xff09;和观察者&#xff08;Observer&#xff09;。主题负责维护观察者列表&#xff0c;并在其状态发生变化时通知所有注册的观察者。观察者则是对主题状态感兴趣的对象&…

吴恩达大模型系列课程《Prompt Compression and Query Optimization》中文学习打开方式

Prompt Compression and Query Optimization GPT-4o详细中文注释的Colab观看视频1 浏览器下载插件2 打开官方视频 GPT-4o详细中文注释的Colab 中文注释链接&#xff1a;https://github.com/Czi24/Awesome-MLLM-LLM-Colab/tree/master/Courses/Prompt-Compression-and-Query-Op…

防溺水预警系统引领水域安全新篇章

一、系统概述 随着人们对水域活动的需求增加&#xff0c;溺水事故频发&#xff0c;给人们的生命安全带来了严重威胁。然而&#xff0c;如今&#xff0c;一项创新科技正在以强大的功能和无限的潜力引领着水域安全的新篇章。智能防溺水预警系统&#xff0c;作为一种集成了智能感知…

乐鑫ESP-IoT-Bridge方案简化设备智能联网通信,启明云端乐鑫代理商

随着物联网技术的快速发展&#xff0c;设备联网已成为实现智能化的关键一步。然而&#xff0c;不同设备之间的通信协议、接口等差异&#xff0c;使得设备联网变得复杂且困难。 乐鑫推出的ESP-IoT-Bridge联网方案&#xff0c;正是为了解决这一难题&#xff0c;为物联网场景下的…

c字符串转go字符串

【1】问题&#xff1a;如何将带中文的char*转utf8 【2】问题分析&#xff1a; 默认的带中文的char*的编码格式是GBK&#xff0c;也就是中文是占两个字节&#xff0c;而数字、字母和其他字符是占一个字节&#xff0c;如“hao好”就是占5个字节 但是UTF-8&#xff0c;汉字是占…

抖音短视频seo矩阵系统源码(搭建技术开发分享)

#抖音矩阵系统源码开发 #短视频矩阵系统源码开发 #短视频seo源码开发 一、 抖音短视频seo矩阵系统源码开发&#xff0c;需要掌握以下技术&#xff1a; 网络编程&#xff1a;能够使用Python、Java或其他编程语言进行网络编程&#xff0c;比如使用爬虫技术从抖音平台获取数据。…

服务器的80和443端口关闭也能申请SSL证书

一、简介 在服务器的80和443端口关闭的情况下&#xff0c;确实可以申请SSL证书&#xff0c;但申请过程和方法会根据证书类型和验证方式的不同而有所差异。 通常如果是网站域名申请SSL证书&#xff0c;哪怕服务器的80、443端口都打不开&#xff0c;也可以通过DNS解析的方式来验…

设计模式-领域逻辑模式-领域模型(Domain Model)

例子 合并了行为和数据的领域的对象模型&#xff0c;如下图所示。 建立收入确认类 建立收入计算策略类 对象的传递过程

EasyExcel 学习之 导出 “WPS 表格在试图打开文件时遇到错误”

目录 1. 版本2. 现象2.1. Postman 文件下载成功且 WPS 可以正常打开2.2. VUE 下载成功但 WPS 无法打开 3. 原因:前端未指定 responseType4. 常见问题4.1. NoSuchMethodError4.1.1. org.apache.logging.log4j.LogBuilder org.apache.logging.log4j.Logger.atTrace()4.1.2. Could…

请解释vue的单页面应用是什么及其优缺点

Vue的单页面应用&#xff08;Single Page Application, SPA&#xff09;是一种使用Vue.js框架构建的Web应用程序&#xff0c;它通过动态加载内容来更新页面&#xff0c;而不是每次用户导航时重新加载整个页面。以下是对Vue单页面应用的详细解释及其优缺点的归纳&#xff1a; V…

河南萌新联赛2024第(一)场:河南农业大学

C-有大家喜欢的零食吗_河南萌新联赛2024第&#xff08;一&#xff09;场&#xff1a;河南农业大学 (nowcoder.com) 思路:匈牙利算法的板子题. 二部图 int n; vector<int> vct[505]; int match[505],vis[505]; bool dfs(int s){for(auto v:vct[s]){if(vis[v]) continue;…

Jmeter关联

案例脚本实现&#xff1a;选择商品加入购物车 客户端发送一个登录的HTTP请求&#xff0c;服务端返回一个带着token的响应&#xff0c;后续发出一个带token信息的加入购物车的HTTP请求&#xff0c;返回响应。 关联&#xff1a;当请求直接由依赖关系的时候&#xff0c;比如一个请…

Python项目中的.gitignore配置

在Git项目中&#xff0c;.gitignore 文件用于指定哪些文件和目录应该被Git忽略&#xff0c;不纳入版本控制。对于Python项目&#xff0c;通常需要忽略一些特定的文件和目录&#xff0c;如编译生成的文件、虚拟环境、日志文件等。以下是一个常见的Python项目 .gitignore 配置示例…

FreeRTOS的中断管理、临界资源保护、任务调度

什么是中断&#xff1f; 简介&#xff1a;让CPU打断正常运行的程序&#xff0c;转而去处理紧急的事件&#xff08;程序&#xff09;&#xff0c;就叫中断。 中断优先级分组设置 ARM Cortex-M 使用了 8 位宽的寄存器来配置中断的优先等级&#xff0c;这个寄存器就是中断优先级…

Python | Leetcode Python题解之第242题有效的字母异位词

题目&#xff1a; 题解&#xff1a; class Solution:def isAnagram(self, s: str, t: str) -> bool:s_c Counter(s)t_c Counter(t)if(len(s_c) ! len(t_c)):return Falseelse:for key, value in s_c.items():if t_c.get(key) ! value:return Falsereturn True

使用Java和Apache Kafka Streams实现实时流处理应用

使用Java和Apache Kafka Streams实现实时流处理应用 大家好&#xff0c;我是微赚淘客系统3.0的小编&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 引言 实时流处理已经成为现代应用开发中不可或缺的一部分。Apache Kafka Streams是一个强大的库…

Halcon机器视觉15种缺陷检测案例_5产中的凹坑检测

效果 代码 *6产中的凹坑检测 dev_update_off ()read_image (Image, 6产中的凹坑检测.png) *分割出环形区域 threshold (Image, Region, 100, 255) *连通 connection (Region, ConnectedRegions) *选择圆环区域 select_shape (ConnectedRegions, SelectedRegions, area, and, 3…

Qt QJson组装数据Sig传递

有时候界面输入的值&#xff0c;不想创建结构体&#xff0c;那么直接用QString类型传输&#xff0c;更便捷方便&#xff0c;速度更快 QJson是你选择的一种方式 组合&#xff1a; #include <QCoreApplication> #include <QJsonDocument> #include <QJsonObjec…

【PostgreSQL】PostgreSQL 教程

博主介绍&#xff1a;✌全网粉丝20W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

音频可视化--柱形波状图

<!--* Author: liszter <liszterqq.com>* Date: 2024-07-11 16:06:39* LastEditTime: 2024-07-11 18:25:36* LastEditors: lishutao* Description: 暂无* FilePath: \vueee\src\components\record-draw\record-draw-html\index.vue--><template><div clas…