cfun/
c_log.rs

1#[cfg(feature = "log")]
2use tracing::level_filters::LevelFilter;
3#[cfg(feature = "log")]
4use tracing_appender::rolling::{RollingFileAppender, Rotation};
5#[cfg(feature = "log")]
6use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, Layer};
7
8#[cfg(feature = "log")]
9pub enum CLogLevel {
10    Trace,
11    Debug,
12    Info,
13    Warn,
14    Error,
15}
16
17#[cfg(feature = "log")]
18pub use tracing::{debug, error, info, trace, warn};
19
20#[cfg(feature = "log")]
21fn from_cloglevel(level: &CLogLevel) -> LevelFilter {
22    match level {
23        CLogLevel::Trace => LevelFilter::TRACE,
24        CLogLevel::Debug => LevelFilter::DEBUG,
25        CLogLevel::Info => LevelFilter::INFO,
26        CLogLevel::Warn => LevelFilter::WARN,
27        CLogLevel::Error => LevelFilter::ERROR,
28    }
29}
30
31/// only log to console
32#[cfg(feature = "log")]
33pub fn default_console_log(log_level: CLogLevel) {
34    let timer = tracing_subscriber::fmt::time::ChronoLocal::new("%Y-%m-%d %H:%M:%S".to_owned());
35    let console_layer = tracing_subscriber::fmt::layer()
36        .with_timer(timer.clone())
37        .with_target(true)
38        .with_line_number(true)
39        .with_writer(std::io::stdout)
40        .with_ansi(true)
41        .with_filter(from_cloglevel(&log_level));
42    tracing_subscriber::registry().with(console_layer).init();
43}
44
45/// only log to file
46#[cfg(feature = "log")]
47pub fn default_file_log(
48    log_level: CLogLevel,
49    log_path: &str,
50    log_file_name: &str,
51    max_log_files: Option<usize>,
52) {
53    let timer = tracing_subscriber::fmt::time::ChronoLocal::new("%Y-%m-%d %H:%M:%S".to_owned());
54
55    let mut file_appender = RollingFileAppender::builder()
56        .rotation(Rotation::DAILY)
57        .filename_prefix(log_file_name)
58        .filename_suffix("log");
59
60    if let Some(max_log_files) = max_log_files {
61        file_appender = file_appender.max_log_files(max_log_files);
62    };
63    let file_appender = file_appender.build(log_path).unwrap();
64
65    let file_layer = tracing_subscriber::fmt::layer()
66        .with_timer(timer)
67        .with_target(true)
68        .with_line_number(true)
69        .with_ansi(false)
70        .with_writer(file_appender)
71        .with_filter(from_cloglevel(&log_level));
72    tracing_subscriber::registry().with(file_layer).init();
73}
74
75/// log to console and file
76#[cfg(feature = "log")]
77pub fn default_log(
78    log_level: CLogLevel,
79    log_path: &str,
80    log_file_name: &str,
81    max_log_files: Option<usize>,
82) {
83    let timer = tracing_subscriber::fmt::time::ChronoLocal::new("%Y-%m-%d %H:%M:%S".to_owned());
84    let console_layer = tracing_subscriber::fmt::layer()
85        .with_timer(timer.clone())
86        .with_target(true)
87        .with_line_number(true)
88        .with_writer(std::io::stdout)
89        .with_ansi(true)
90        .with_filter(from_cloglevel(&log_level));
91
92    let mut file_appender = RollingFileAppender::builder()
93        .rotation(Rotation::DAILY)
94        .filename_prefix(log_file_name)
95        .filename_suffix("log");
96
97    if let Some(max_log_files) = max_log_files {
98        file_appender = file_appender.max_log_files(max_log_files);
99    };
100    let file_appender = file_appender.build(log_path).unwrap();
101
102    let file_layer = tracing_subscriber::fmt::layer()
103        .with_timer(timer)
104        .with_target(true)
105        .with_line_number(true)
106        .with_ansi(false)
107        .with_writer(file_appender)
108        .with_filter(from_cloglevel(&log_level));
109    tracing_subscriber::registry()
110        .with(file_layer)
111        .with(console_layer)
112        .init();
113}
114
115#[test]
116#[cfg(feature = "log")]
117fn test_console_log() {
118    default_console_log(CLogLevel::Trace);
119    tracing::trace!("trace");
120    tracing::debug!("debug");
121    tracing::info!("info");
122    tracing::warn!("warn");
123    tracing::error!("error");
124}
125
126#[test]
127#[cfg(feature = "log")]
128fn test_file_log() {
129    default_file_log(CLogLevel::Trace, "./", "test", None);
130    tracing::trace!("trace");
131    tracing::debug!("debug");
132    tracing::info!("info");
133    tracing::warn!("warn");
134    tracing::error!("error");
135}
136
137#[test]
138#[cfg(feature = "log")]
139fn test_log() {
140    default_log(CLogLevel::Trace, "./", "test", None);
141    tracing::trace!("trace");
142    tracing::debug!("debug");
143    tracing::info!("info");
144    tracing::warn!("warn");
145    tracing::error!("error");
146}