1mod rotation;
2
3use elph_agent::LoggingOptions;
4use tracing_appender::non_blocking::{NonBlockingBuilder, WorkerGuard};
5use tracing_subscriber::{EnvFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt};
6
7pub use rotation::build_writer;
8
9const FILE_WRITER_BUFFER_LINES: usize = 16_384;
12
13pub fn init(options: LoggingOptions) -> Option<WorkerGuard> {
18 if cfg!(test) {
19 return None;
20 }
21
22 install_subscriber(&options)
23}
24
25fn non_blocking_writer(options: &LoggingOptions) -> (tracing_appender::non_blocking::NonBlocking, WorkerGuard) {
26 let writer = build_writer(&options.logs_dir, options.app_name, options.rotation, options.max_files)
27 .expect("failed to initialize rolling log writer");
28 NonBlockingBuilder::default()
29 .buffered_lines_limit(FILE_WRITER_BUFFER_LINES)
30 .finish(writer)
31}
32
33fn install_subscriber(options: &LoggingOptions) -> Option<WorkerGuard> {
34 let env_filter = EnvFilter::new(options.level.clone());
35
36 match (options.file_enabled, options.console_enabled) {
37 (true, true) => {
38 let (non_blocking, guard) = non_blocking_writer(options);
39
40 tracing_subscriber::registry()
41 .with(env_filter)
42 .with(
43 fmt::layer()
44 .json()
45 .with_writer(non_blocking)
46 .with_ansi(false)
47 .with_target(true),
48 )
49 .with(
50 fmt::layer()
51 .with_writer(std::io::stdout)
52 .with_target(true)
53 .with_ansi(true),
54 )
55 .init();
56
57 Some(guard)
58 }
59 (true, false) => {
60 let (non_blocking, guard) = non_blocking_writer(options);
61
62 tracing_subscriber::registry()
63 .with(env_filter)
64 .with(
65 fmt::layer()
66 .json()
67 .with_writer(non_blocking)
68 .with_ansi(false)
69 .with_target(true),
70 )
71 .init();
72
73 Some(guard)
74 }
75 (false, true) => {
76 tracing_subscriber::registry()
77 .with(env_filter)
78 .with(
79 fmt::layer()
80 .with_writer(std::io::stdout)
81 .with_target(true)
82 .with_ansi(true),
83 )
84 .init();
85
86 None
87 }
88 (false, false) => {
89 tracing_subscriber::registry().with(env_filter).init();
90 None
91 }
92 }
93}