tracing_plus/
lib.rs

1//! 该库是对[tracing](https://docs.rs/tracing/latest/tracing/)库的增强
2//!
3//! 在项目的的根目录创建一个文件名为`tracing-log.toml`或`tracing-log.yaml`或`tracing-log.yml`的文件,
4//! 该库会根据配置文件动态的注册日志,然后调用`init_tracing_log`方法即可完成日志的初始化工作
5//!
6//! > 优先级
7//! > toml > yaml > yml
8//! # 示例
9//!
10//! ```toml
11//! # 文件名 tracing-log.toml
12//! # 控制台输出配置
13//! [console]
14//! # 日志级别, 必填(可选值:`error`、`warn`、`info`、`debug`、`trace`)
15//! level = "info"
16//! # 是否打印线程名 默认为 true
17//! thread = true
18//! # 时间格式 默认为 "%Y-%m-%d %H:%M:%S"
19//! format = "%Y-%m-%d %H:%M:%S"
20//! # 是否打印行号  默认为 false
21//! line-number = true
22//!
23//! # 文件输出配置
24//! [[file]]
25//! # 日志级别, 必填(可选值:`error`、`warn`、`info`、`debug`、`trace`)
26//! level = "info"
27//! # 是否打印线程名 默认为 true
28//! thread = true
29//! # 时间格式 默认为 "%Y-%m-%d %H:%M:%S"
30//! format = "%Y-%m-%d %H:%M:%S"
31//! # 是否打印行号 默认为 false
32//! line-number = true
33//! # 保留的最大文件数量 默认为 30
34//! max-files = 60
35//! # 日志文件滚动的固定时间段,可选值: "minutely"、"hourly"、"daily"、"never", 默认值为: "daily"
36//! rotation = "daily"
37//! # 生成的文件名前缀, 必填
38//! prefix = "info"
39//! # 生成的文件名后缀, 默认值为: "log"
40//! suffix = "log"
41//! # 生成的文件所在目录前缀, 默认值为: "logs"
42//! directory = "logs"
43//! # 只记录`target`指定的值的日志 (不配置,则记录全部)
44//! target = "abc"
45//!
46//! [[file]]
47//! level = "error"
48//! thread = false
49//! format = "%Y-%m-%d %H:%M:%S"
50//! line-number = true
51//! max-files = 60
52//! rotation = "daily"
53//! prefix = "error"
54//! directory = "logs"
55//!
56//! [[file]]
57//! level = "worker"
58//! thread = false
59//! format = "%Y-%m-%d %H:%M:%S"
60//! line-number = true
61//! max-files = 60
62//! rotation = "daily"
63//! prefix = "error"
64//! directory = "logs"
65//! target = "worker"
66//! ```
67#[cfg(feature = "blocking")]
68mod blocking_layer;
69mod config;
70#[cfg(not(feature = "blocking"))]
71mod non_blocking_layer;
72
73use tracing::level_filters::LevelFilter;
74use tracing_appender::rolling::Rotation;
75#[cfg(feature = "blocking")]
76use crate::blocking_layer::{get_console_layer, get_file_layer};
77use crate::config::TracingLog;
78
79#[cfg(not(feature = "blocking"))]
80use crate::non_blocking_layer::{get_console_layer, get_file_layer};
81use tracing_subscriber::Registry;
82use tracing_subscriber::layer::SubscriberExt;
83use tracing_subscriber::util::SubscriberInitExt;
84
85pub fn init_tracing_log() {
86    let config = TracingLog::config();
87    let console = &config.console;
88    let files = &config.file;
89
90    let console = get_console_layer(console);
91
92    let file_layers = files
93        .iter()
94        .map(|file| get_file_layer(file))
95        .collect::<Vec<_>>();
96
97    Registry::default().with(console).with(file_layers).init();
98
99    #[cfg(feature = "blocking")]
100    tracing::debug!("blocking log enabled");
101
102    #[cfg(not(feature = "blocking"))]
103    tracing::debug!("non blocking log enabled");
104}
105
106
107
108fn level_from_str(level: &str) -> LevelFilter {
109    match level {
110        s if s.eq_ignore_ascii_case("error") => LevelFilter::ERROR,
111        s if s.eq_ignore_ascii_case("warn") => LevelFilter::WARN,
112        s if s.eq_ignore_ascii_case("info") => LevelFilter::INFO,
113        s if s.eq_ignore_ascii_case("debug") => LevelFilter::DEBUG,
114        s if s.eq_ignore_ascii_case("trace") => LevelFilter::TRACE,
115        _ => panic!("未知的`level`属性值, 可选值:`error`、`warn`、`info`、`debug`、`trace`"),
116    }
117}
118
119fn rotation_from_str(rotation: &str) -> Rotation {
120    match rotation {
121        s if s.eq_ignore_ascii_case("minutely") => Rotation::MINUTELY,
122        s if s.eq_ignore_ascii_case("hourly") => Rotation::HOURLY,
123        s if s.eq_ignore_ascii_case("daily") => Rotation::DAILY,
124        s if s.eq_ignore_ascii_case("never") => Rotation::NEVER,
125        _ => panic!("未知的`rotation`属性值, 可选值:`minutely`、`hourly`、`daily`、`never`"),
126    }
127}