找回密码
 立即注册
首页 资源区 代码 Rust 实现日志记录功能

Rust 实现日志记录功能

艾曼语 前天 14:44
目录

  • log 日志库标准

    • 简单示例
    • 使用方法

      • 库的开发者
      • 应用开发者
      • 日志库开发者


  • 使用 log4rs

    • 添加依赖
    • 配置文件
    • 运行项目

  • 参考文章

log 日志库标准

log 是 Rust 的日志门面库,由官方积极维护可以放心使用。它是Rust的日志门面,相应的日志 API 已成为事实上的标准被其它日志框架所使用,有了日志门面开发者可以很方便切换自己的日志框架。
简单示例

创建一个名为 log_test 二进制项目:
  1. cargo new log_test
复制代码
执行以下命令,引入 log 依赖:
  1. cargo add log
复制代码
修改 main.rs 的代码如下:
  1. use log::{info, warn,error,trace};
  2. fn main() {
  3.     // 记录日志
  4.     info!("This is an info message");
  5.     warn!("This is a warning message");
  6.     error!("This is an error message");
  7.     trace!("This is an trace message");
  8. }
复制代码
运行上面的示例,实际上看不到任何输出。因为 log 仅仅是日志门面库,它并不具备完整的日志库功能
使用方法

因为 log 仅仅是日志门面库,对于库和应用的开发者来说使用方法是有区别的,这也是 log 包这么设计的优势所在。
库的开发者

作为库的开发者,你只要在库中使用门面库即可,将具体的日志库交给用户去选择和绑定:
  1. use log::{info, trace, warn};
  2. pub fn deal_with_something() {
  3.     // 开始处理
  4.     // 记录一些日志
  5.     trace!("a trace log");
  6.     info!("a info long: {}", "abc");
  7.     warn!("a warning log: {}, retrying", err);
  8.     // 结束处理
  9. }
复制代码
应用开发者

如果是应用开发者,就需要去选择一个具体的日志库了。
目前已经有了不少日志库实现,官方在 github 上也推荐了一些 ,主要分为以下几类:

  • 简单的最小记录器,如 env_logger 等
  • 复杂的可配置框架,如 log4rs 等
  • 其他设施的适配器,如 syslog、db_logger 等
  • 对于 WebAssembly 二进制文件:console_log
  • 对于动态库:需要在日志上构造一个 FFI 安全包装器,以便在库中进行初始化。
  • 实用程序,如 alterable_logger 等
log 还提供了 set_logger 函数用于设置日志库,set_max_level 用于设置最大日志级别。但是选用的具体日志库往往会提供更高级的 API,无需手动调用这两个函数。
日志库开发者

对于日志库开发者而言,自然要实现自己的 Log 特征:
  1. use log::{Record, Level, Metadata};
  2. struct SimpleLogger;
  3. impl log::Log for SimpleLogger {
  4.     fn enabled(&self, metadata: &Metadata) -> bool {
  5.         metadata.level() <= Level::Info
  6.     }
  7.     fn log(&self, record: &Record) {
  8.         if self.enabled(record.metadata()) {
  9.             println!("{} - {}", record.level(), record.args());
  10.         }
  11.     }
  12.     fn flush(&self) {}
  13. }
复制代码
然后再main函数里面设置全局记录器:
  1. use log::{SetLoggerError, LevelFilter};
  2. static LOGGER: SimpleLogger = SimpleLogger;
  3. pub fn init() -> Result<(), SetLoggerError> {
  4.     log::set_logger(&LOGGER)
  5.         .map(|()| log::set_max_level(LevelFilter::Info))
  6. }
复制代码
运行后终端输出如下,因为设置日志等级为Info,所以没有输出Trace等级日志:
  1. use log::{info, warn,error,trace};
  2. fn main() {
  3.     //设置日志
  4.     init();
  5.     // 记录日志
  6.     info!("This is an info message");
  7.     warn!("This is a warning message");
  8.     error!("This is an error message");
  9.     trace!("This is an trace message");
  10. }
复制代码
使用 log4rs

log4rs 是一个高度可配置的日志框架,以 Java 的 Logback 和 log4j 库为模型。
添加依赖

为项目添加 log4rs 依赖:
  1. INFO - This is an info message
  2. WARN - This is a warning message
  3. ERROR - This is an error message
复制代码
配置文件

在项目根目录下,创建一个 log4rs.yaml 配置文件,并添加以下内容:
  1. cargo add log4rs
复制代码
上面配置文件设定日志输出到控制台、文件,文件按10 mb大小滚动,只保留最近五个文件。各个配置字段的具体含义可以参考配置:

  • refresh_rate:用于确定 log4rs 扫描配置文件以查找更改的频率,如果发现更改,记录器将自动重新配置
  • appender: 负责将日志收集到文件、控制台或系统日志, 可配置多个
  • stdout、rolling_file:追加器的唯一标识字符串,自己随便定义,它的 kind 字段只支持console、file、rolling_file 三种实现
  • encoder: 负责将 log 信息转换为合适的格式, 如固定格式的平文本或json
  • pattern:编码模板,格式可配置,具体格式详见pattern
  • policy:策略字段,策略必须具有 kind 字段,默认(且仅受支持)策略为 kind: compound
  • trigger:触发器字段用于指示何时滚动日志文件,支持 sizetime 两种类型,这里使用的是按大小
运行项目

修改main.rs内容如下:
  1. refresh_rate: 30 seconds
  2. appenders:
  3.   stdout:
  4.     kind: console
  5.     encoder:
  6.       pattern: "{d(%Y-%m-%d %H:%M:%S.%f)} [{l}] {t} - {m}{n}"
  7.   
  8.   rolling_file:
  9.     kind: rolling_file
  10.     path: logs/test.log
  11.     append: true
  12.     encoder:
  13.       pattern: "{d(%Y-%m-%d %H:%M:%S.%f)} [{l}] {t} - {m}{n}"
  14.     policy:
  15.       kind: compound
  16.       trigger:
  17.         kind: size
  18.         limit: 10 mb
  19.       roller:        
  20.         kind: fixed_window
  21.         pattern: logs/test.{}.log
  22.         base: 1
  23.         count: 5
  24.         
  25. root:
  26.   level: info
  27.   appenders:
  28.     - stdout
  29.     - rolling_file
复制代码
运行结果:
  1. use log::*;
  2. use log4rs;
  3. fn main() {
  4.     log4rs::init_file("log4rs.yaml", Default::default()).unwrap();
  5.     for i in 1..=1000 {
  6.         info!("This is loop iteration {}", i);
  7.     }
  8. }
复制代码
参考文章


  • 日志门面 log
  • Crate log
  • rust输出日志文件
  • [Rust Crate] log4rs Rust log 库

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册