文盘Rust -- 给程序加个日志

rust,程序,日志 · 浏览次数 : 17

小编点评

## 使用 log4rs 记录系统日志和业务日志的示例 本代码展示了如何在 Rust 中使用 log4rs 记录系统日志和业务日志,并通过 `target` 变量区分输出到不同的 logger。 ```rust use log4rs::init_config; use log4rs::Logger; fn main() { // 初始化日志配置 let config = init_config("./src/logger/logger.rs").unwrap(); // 初始化 logger let sys_logger = Logger::builder() .appender("sys", Logger::builder() .appender(Appender::builder().build("syslog", LevelFilter::Info)) .build()) .logger(Logger::builder().appender("syslog", LevelFilter::Info).build("syslog")) .unwrap(); let business_logger = Logger::builder() .appender("business", Logger::builder() .appender(Appender::builder().build("businesslog", LevelFilter::Info)) .build()) .logger(Logger::builder().appender("businesslog", LevelFilter::Info).build("businesslog")) .unwrap(); // 输出日志 uselog!("Hello, world!"); new_use_log_cmd(); // 输出 sys日志 new_use_business_log_cmd(); // 输出 business日志 } fn new_use_log_cmd() { let cmd = clap::Command::new("uselog"); cmd.about("append to syslog"); cmd.subcommand("syslog").about("Input sys log"); cmd.run(); } fn new_use_business_log_cmd() { let cmd = clap::Command::new("uselog"); cmd.about("append to business log"); cmd.subcommand("businesslog").about("Input business log"); cmd.run(); } ``` **运行结果:** ``` Hello, world! using log4rs::Logger; using log4rs::Appender; uselog!("Hello, world!"); new_use_log_cmd(); new_use_business_log_cmd(); ``` **代码说明:** 1. 使用 `log4rs::init_config` 初始化日志配置。 2. 创建三个 logger:`sys_logger` 用于记录系统日志,`business_logger` 用于记录业务日志。 3. 使用 `uselog` 函数记录日志消息。 4. `new_use_log_cmd` 和 `new_use_business_log_cmd` 函数使用 `clap` 库执行使用命令的功能。 5. `target` 变量用于区分输出到不同的 logger。 **注意:** * `src/logger/logger.rs` 中定义了 `syslog` 和 `businesslog` 的 Appender。 * `new_use_log_cmd` 和 `new_use_business_log_cmd` 函数使用 `subcommand` 方法执行使用命令的功能。 * `target` 的命名可以根据实际需求进行调整。

正文

日志是应用程序的重要组成部分。无论是服务端程序还是客户端程序都需要日志做为错误输出或者业务记录。在这篇文章中,我们结合log4rs聊聊rust 程序中如何使用日志。
log4rs类似java生态中的log4j,使用方式也很相似

log4rs中的基本概念

log4rs 的功能组件也由 appender 和 logger构成。

  • appender
    负责向指定文件或控制台追加日志

  • logger
    包含多个 appender ,比如一条日志既要输出到控制台也要持久化到日志文件中,就可以在logger中同时绑定 ConsoleAppender 和 FileAppender

log4rs 使用示例

  • 示例描述
    我们需要在工程中记录系统日志和业务日志,分别记录在logs/sys.log 和 logs/business.log

  • 定义 appender 和 logger 并初始化
    代码位置 src/logger/logger.rs

    
      let sys_file = FileAppender::builder()
          .encoder(Box::new(PatternEncoder::new("{d} - {m}{n}")))
          .build("logs/sys.log")
          .unwrap();
      let business_file = FileAppender::builder()
          .encoder(Box::new(PatternEncoder::new("{d} - {m}{n}")))
          .build("logs/business.log")
          .unwrap();
    
      let stdout = ConsoleAppender::builder().build();
    
      let config = Config::builder()
          .appender(Appender::builder().build("stdout", Box::new(stdout)))
          .appender(Appender::builder().build("sys", Box::new(sys_file)))
          .appender(Appender::builder().build("business", Box::new(business_file)))
          .logger(
              Logger::builder()
                  .appender("sys")
                  .build("syslog", LevelFilter::Info),
          )
          .logger(
              Logger::builder()
                  .appender("business")
                  .build("businesslog", LevelFilter::Info),
          )
          .build(
              Root::builder()
                  .appender("stdout")
                  .appender("file_out")
                  .build(LevelFilter::Info),
          )
          .unwrap();
    
      let _ = log4rs::init_config(config).unwrap();
    
    
    

代码中定义了 sys_file 和 business_file 两个FileAppender 分别用于像sys.log 和 business.log中追加日志。

config 中定义了两个logger 分别绑定 sys appender 和 business appender。
最后通过 init_config 初始化 log4rs。

  • 在程序中输出日志

    • 定义 uselog 命令及两个子命令,分别输入sys 日志和 business 日志。
      代码位置 src/cmd/cmdusedifflogger.rs

      pub fn new_use_log_cmd() -> Command<'static> {
          clap::Command::new("uselog")
              .about("use diffrent target log")
              .subcommand(new_use_sys_log_cmd())
              .subcommand(new_use_business_log_cmd())
      }
      
      pub fn new_use_sys_log_cmd() -> Command<'static> {
          clap::Command::new("syslog").about("append to syslog")
      }
      
      pub fn new_use_business_log_cmd() -> Command<'static> {
          clap::Command::new("businesslog").about("append to business log")
      }
      
      
      
    • 解析命令并输出日志
      代码位置 src/cmd/rootcmd.rs

      if let Some(ref log) = matches.subcommand_matches("uselog") {
          println!("use log");
          if let Some(_) = log.subcommand_matches("syslog") {
              log::info!(target:"syslog","Input sys log");
          }  
          if let Some(_) = log.subcommand_matches("businesslog") {
              log::info!(target:"businesslog","Input business log");
          }
      }
      
      
      

输出时,通过 target 来区分输出到不同的logger。

本问代码的github地址:https://github.com/jiashiwen/interactcli-rs

下期见

作者:京东科技 贾世闻

来源:京东云开发者社区 转载请注明来源

与文盘Rust -- 给程序加个日志相似的内容:

文盘Rust -- 给程序加个日志

日志是应用程序的重要组成部分。无论是服务端程序还是客户端程序都需要日志做为错误输出或者业务记录。在这篇文章中,我们结合log4rs聊聊rust 程序中如何使用日志。

文盘Rust -- 给程序加个日志

作者:贾世闻 日志是应用程序的重要组成部分。无论是服务端程序还是客户端程序都需要日志做为错误输出或者业务记录。在这篇文章中,我们结合[log4rs](https://github.com/estk/log4rs)聊聊rust 程序中如何使用日志。 [log4rs](https://github.co

文盘Rust -- 把程序作为守护进程启动

当我们写完一个服务端程序,需要上线部署的时候,或多或少都会和操作系统的守护进程打交道,毕竟谁也不希望shell关闭既停服。今天我们就来聊聊这个事儿。 最早大家部署应用的通常操作是 “nohup xxxx &”,别说像weblogic 或者其他java 容器有启动脚本,里面其实也差不多;很喜欢 ngi

文盘Rust -- r2d2 实现redis连接池

作者:贾世闻 我们在开发应用后端系统的时候经常要和各种数据库、缓存等资源打交道。这一期,我们聊聊如何访问redis 并将资源池化。 在一个应用后端程序访问redis主要要做的工作有两个,单例和池化。 在后端应用集成redis,我们主要用到以下几个crate:​ ​once_cell​​​、​ ​re

文盘Rust -- rust 连接云上数仓 starwift

最近想看看 rust 如何集成 clickhouse,又犯了好吃懒做的心理(不想自己建环境),刚好京东云发布了兼容ck 的云原生数仓 Starwfit,于是搞了个实例折腾一番。 Starwfit 是京东云自主研发的新一代云原生数据仓库,通过存算分离降低了存储成本,同时兼具性能和扩展弹性。其写入和查询速度可达到传统数据仓库的数倍,为用户提供实时数据分析能力。广泛应用于流量分析、精准营销、用户画像、广

文盘Rust -- 领域交互模式如何实现

书接上文,上回说到如何通过interactcli-rs四步实现一个命令行程序。但是 shell 交互模式在有些场景下用户体验并不是很好。比如我们要连接某个服务,比如 mysql 或者 redis 这样的服务。如果每次交互都需要输入地址、端口、用户名等信息,交互起来太麻烦。通常的做法是一次性输入和连接相关的信息或者由统一配置文件进行管理,然后进入领域交互模式,所有的命令和反馈都和该领域相关。inte

文盘Rust -- 本地库引发的依赖冲突

clickhouse 的原生 rust 客户端目前比较好的有两个clickhouse-rs 和 clickhouse.rs 。两个库在单独使用时没有任何问题,但是,在同一工程同时引用时会报错。本篇内容主要讲解如何用rust语言解决本地库引发的依赖冲突问题

文盘Rust -- 安全连接 TiDB/Mysql

最近在折腾rust与数据库集成,选了Tidb Cloud Serverless Tier 作为数据源。Tidb 无疑是近五年来最优秀的国产开源分布式数据库,Tidb Cloud Serverless Tier作为pingcap旗下的云产品方便又经济,这次使用还有一些小惊喜。

文盘Rust -- FFI 浅尝

rust FFI 是rust与其他语言互调的桥梁,通过FFI rust 可以有效继承 C 语言的历史资产。本期通过几个例子来聊聊rust与C 语言交互的具体步骤

文盘Rust -- Mutex解决并发写文件乱序问题

在实际开发过程中,我们可能会遇到并发写文件的场景,如果处理不当很可能出现文件内容乱序问题。下面我们通过一个示例程序描述这一过程并给出解决该问题的方法。