Rust Tracing使用:按日期切分日志,存储不同日志文件

最近再学RUST,练手项目选择 Web方向,写到日志这块的时候,发现两个库,一个是Log4rs,这个库使用还是挺方便的,但是我想实现日志按照日期切割就不行了,我再 github issuse 中发现有人提出来要支持文件按照日期命名,但是发现需求搁置了,所以我换了另一个库 tracing,但是文档和示例确实不太直观,查了多篇文章实现出来的功能,在这记录一下给有同样需求的同志们做个参考。直接上代码:

Cargo.toml

[dependencies]
chrono = "0.4.39"
colored = "3.0.0"
serde_json = "1.0.135"
tracing = "0.1.41"
tracing-appender = "0.2.3"
tracing-log = "0.2.0"
tracing-subscriber = {version = "0.3.19",features =["json"]}
use tracing_subscriber::{prelude::*};
use tracing_log::LogTracer;
use tracing::{info, span, Level};
use colored::Colorize;
use tracing_subscriber::fmt::time::{FormatTime};
use tracing_subscriber::fmt::format::Writer;
use chrono::Local;
use tracing::instrument::WithSubscriber;
use tracing_appender::non_blocking::WorkerGuard;

struct LocalTimer;

const fn east8() -> Option<chrono::FixedOffset> {
  chrono::FixedOffset::east_opt(8 * 3600)
}

impl FormatTime for LocalTimer {
  fn format_time(&self, w: &mut Writer<'_>) -> std::fmt::Result {
    let now = chrono::Utc::now().with_timezone(&east8().unwrap());
    write!(w, "{}", now.format("%Y-%m-%d %H:%M:%S"))
  }
}

struct LogTarget{}
impl LogTarget {
  pub const WEB_LOG:&'static str = "web-log";
  pub const API_LOG:&'static str = "api-log";
}

fn main() {
  // 日志配置初始化
  // 这里需要接收 guard 否则文件输出内容会是空的
  let _guard = init_log();
  info!(target: LogTarget::API_LOG,"api log message");
  info!(target: LogTarget::WEB_LOG,"web log message");
  info!("hello world");
}



///
/// 日志配置初始化
///
fn init_log() -> Vec<WorkerGuard> {
  let mut guards = Vec::new();

  // 消费log门面日志 转为 tracing Event日志
  LogTracer::builder()
    // .with_max_level(log::LevelFilter::Error)
    .init()
    .expect("[PEAR] LogTracer 初始化失败");

  // 输出日志
  let console_subscriber = tracing_subscriber::fmt
  ::layer().with_writer(std::io::stdout).with_timer(LocalTimer);

  // 特别定制web日志输出
  let file_appender = tracing_appender::rolling
  ::daily("logs/", LogTarget::WEB_LOG);
  // 生成非阻塞写入器
  let (non_blocking, guard1) = tracing_appender
  ::non_blocking(file_appender);
  guards.push(guard1);
  let file_subscriber = tracing_subscriber::fmt::layer().json()
      .with_writer(non_blocking)
      .with_ansi(false)
      .with_timer(LocalTimer)
      .with_filter(tracing_subscriber::filter::filter_fn(|metadata| {
        // Only enable spans or events with the target "interesting_things"
        metadata.target() == LogTarget::WEB_LOG
      }));

  // 特别定制api日志输出
  let file_appender_api = tracing_appender::rolling
  ::daily("logs/", LogTarget::API_LOG);
  // 生成非阻塞写入器
  let (non_blocking_api, guard) = tracing_appender
  ::non_blocking(file_appender_api);
  guards.push(guard);
  let file_subscriber_api = tracing_subscriber::fmt::layer().json()
      .with_writer(non_blocking_api)
      .with_ansi(false)
      .with_timer(LocalTimer)
      .with_filter(tracing_subscriber::filter::filter_fn(|metadata| {
        // Only enable spans or events with the target "interesting_things"
        metadata.target() == LogTarget::API_LOG
      }));

  // 集合
  let subscriber = tracing_subscriber::registry()
      .with(console_subscriber)
      .with(file_subscriber)
      .with(file_subscriber_api);

    tracing::subscriber::set_global_default(subscriber)
        .expect("setting default subscriber failed");

  guards
}

后期的其他一些模块的用法和代码会写到这个项目里,有兴趣的可以关注一下:GitHub - gphper/rustadmin: Rust 开发脚手架

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值