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

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);
http://www.xdnf.cn/news/4907.html

相关文章:

  • 第一天——贪心算法——分饼干
  • 【软件设计师:软件】20.软件设计概述
  • Oracle链接服务器导致SQL Server异常终止
  • PHP会话技术
  • 机器学习与深度学习的区别与联系:多角度详细分析
  • Java 模板引擎 Thymeleaf JSP FreeMarker
  • 【物联网】基于树莓派的物联网开发【1】——初识树莓派
  • 塔能工业互联节能方案:数据驱动工业制造绿色转型
  • 遗传算法(GA)
  • MiM: Mask in Mask Self-SupervisedPre-Training for 3D Medical Image Analysis
  • 基于公共卫生大数据收集与智能整合AI平台构建测试:从概念到实践
  • 【C++进阶】第2课—多态
  • 数据统计的意义:钱包余额变动
  • C++八股 —— map/unordered_map
  • 发那科机器人5(异常事件和程序备份加载+ROBOGUIDE离线仿真)
  • 服务器多客户端连接核心要点(1)
  • 计算机视觉】OpenCV项目实战:eye_mouse_movement:基于opencv实战眼睛控制鼠标
  • 【Python】Pycharm中安装库可靠的方法
  • 从AI到新能源:猎板PCB的HDI技术如何定义高端制造新标准?
  • Java设计模式之单例模式:从入门到精通
  • 大数据狙击金融欺诈——技术如何守护交易安全?
  • c++:双向链表容器(std::list)
  • C语言—指针3
  • 集群/微服务/分布式
  • 地平线rdk x5部署yolo11
  • el-form的label星号位置如何修改
  • 一个开源的快速准确地将 PDF 转换为 markdown工具
  • 动态规划-62.不同路径-力扣(LeetCode)
  • 量化解析美英协议的非对称冲击:多因子模型与波动率曲面重构
  • 支持向量机案例