当前位置: 首页 > news >正文

Rust中记录日志:fast_log

在Rust程序中记录日志,可以使用fast_log

根据fast_log 的介绍,这是一个性能非常高的日志实现,还支持文件追加模式、压缩、切分与回滚等操作。

而且,这个库记录日志是异步的,即不会因为日志而影响程序的运行。只有当必要的时候,才需要应用层手动调用log::logger().flush()刷到文件。

引入

使用cargo管理的项目,只要通过cargo的add命令即可引入fast_log,当然还需要log

cargo add fast_log
cargo add log

初始化

使用的方法也非常简单,只要通过它的init()函数进行初始化,之后就可以使用日志记录相关的宏了。

init()的参数为一个fast_log::config::Config结构。

这个结构使用了Builder模式,它的new()函数只是调用了它的default()函数,生成了一个默认的结构,之后就可以调用Build的函数进行自定义。

如以下代码,构造了一个输出到终端的Config。

use fast_log::{self, config::Config};fn main() {let config = Config::new().console();fast_log::init(config).expect("init log error");info!("test log info !!!");
}

Config支持各种日志输出。

如:

  • console() 输出到终端
  • file() 输出到文件
  • file_loop() 输出到循环的文件
  • file_split() 输出到回滚文件
  • custom() 自定义输出

输出到回滚文件

输出到回滚文件的时候,file_split()的原型如下:

pub fn file_split<  R: CanRollingPack + 'static,  K: Keep + 'static,  P: Packer + Sync + 'static,  
>(  self,  file_path: &str,  rolling: R,  keeper: K,  packer: P,  
) -> Self

其中,file_path是文件路径,CanRollingKeepPacker分别是三个特性。一般地,我们可以使用fast_log中预定义的结构就好。

如以下代码,定义了一个按照文件大小回滚的输出,每个文件200M,保存5个:

file_split("target/logs/",Rolling::new(RollingType::BySize(LogSize::MB(200))),KeepType::KeepNum(5),LogPacker {},))

以下代码,定义了一个按照日期回滚的输出,保存30天:

file_split("target/logs/",Rolling::new(RollingType::ByDate(DateType::Day)),KeepType::KeepNum(30),LogPacker {},))

自定义输出

自定义输出的时候,使用custom()方法,注册一个实现了LogAppender特性的结构。

LogAppender特定的定义如下:

pub trait LogAppender:Send {  /// Batch write log, or do nothing  fn do_logs(&mut self, records: &[FastLogRecord]);  
}

可以看到,就是实现do_logs方法。其中,records是一个FastLogRecord的数组。

FastLogRecord结构的定义如下:

#[derive(Clone, Debug)]  
pub struct FastLogRecord {  pub command: Command,  pub level: log::Level,  pub target: String,  pub args: String,  pub module_path: String,  pub file: String,  pub line: Option<u32>,  pub now: SystemTime,  pub formated: String,  
}

其中,level是日志的等级,file和line分别是相应的源代码文件与行数,now是日志时间,formated是日志信息。

以下的自定义输出,按照不同的等级,打印了不同格式的信息到标准输出:

struct CustomLog {}impl LogAppender for CustomLog {fn do_logs(&mut self, records: &[FastLogRecord]) {for record in records {let now = DateTime::from(record.now);let data;match record.level {Level::Warn | Level::Error => {data = format!("{} {} {} - {}  {}\n",now, record.level, record.module_path, record.args, record.formated);}_ => {data = format!("{} {} {} - {}\n",&now, record.level, record.module_path, record.args);}}print!("{}", data);}}
}

日志等级

fast_log::config::Config结构的构造方法里有一个level(),可以设置日志等级,参数类型是LevelFilter。

LevelFilter是一个enum。

#[repr(usize)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub enum LevelFilter {Error = 1,Warn,Info,Debug,Trace,
}

以下代码设置了日志等级为Info:

let config = Config::new().console().level(LogLevel::Info);

记录日志的宏log!,第一个参数就是日志等级。当等级高于设置的级别时,不会被记录。

以上代码设置了Info级,则只有Error、Warn、Info会被记录,Debug和Trace等级的日志都被抛弃了。

相对应的,有几个宏可以替代log!宏,分别是:error!warn!info!debug!trace!

如果使用log!宏,就需要在第一个参数中指定日志级别,其它几个宏是log!的简化版。

名字空间

需要注意的是,fast_log的名字空间有点儿复杂 。

比如,file_split一个函数,就需要use几行东西。

其中,Rolling相关的、日期类型(DateType)、保存类型(KeepType)在fast_log::plugin::file_split里,LogSize在fast_log::consts里,而LogPacker又在fast_log::plugin::packer里。

use fast_log::plugin::file_split::{Rolling, RollingType, DateType, KeepType};  
use fast_log::plugin::packer::LogPacker;  
use fast_log::consts::LogSize;

而记录日志的过滤等级,又直接使用的log模块里的定义,配置Config的时候,需要:

use fast_log::config::Config;
use log::LevelFilter;let config = Config::new().level(LevelFilter::Info);

相关文章:

  • 什么是分布式光伏系统?屋顶分布式光伏如何并网?
  • 软件测试的概念
  • 老旧 LabVIEW 系统升级改造
  • HTML字符串转换为React元素实现
  • 基于Transformer与SHAP可解释性分析的神经网络回归预测模型【MATLAB】
  • 基于HTML+JavaScript+CSS实现教学网站
  • 基础RNN网络详解
  • 基于大模型的母婴ABO血型不合溶血病全方位预测与诊疗方案研究
  • 红黑树算法笔记
  • 8b10b编解码仿真
  • 【计算机网络-数据链路层】以太网、MAC地址、MTU与ARP协议
  • Java面向对象三大特性:封装、继承、多态
  • 理解 `.sln` 和 `.csproj`:从项目结构到构建发布的一次梳理
  • C++23 中的 views::chunk:深入探索与应用
  • 网络安全体系架构:核心框架与关键机制解析
  • 阿里云服务器数据库故障排查指南?
  • Spring Boot中的拦截器!
  • 从电动化到智能化,法雷奥“猛攻”中国汽车市场
  • JVM——即时编译
  • Jenkins集成Maven
  • 国际足联女子世界杯再次扩军,2031年起增至48支球队
  • 视频丨雄姿英发!中国仪仗队步入莫斯科红场
  • 马克思主义理论研究教学名师系列访谈|董雅华:让学生感知马克思主义理论存在于社会生活中
  • 昆明阳宗海风景名胜区19口井违规抽取地热水,整改后用自来水代替温泉
  • 绍兴柯桥:用一块布托起中国制造的新经纬
  • 巴基斯坦信德省首府卡拉奇发生爆炸