tracing_plus/
lib.rs

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