1use fstdout_logger::LoggerConfig;
2use log::{LevelFilter, debug, error, info, warn};
3use std::fmt::Write;
4use std::thread::sleep;
5use std::time::Duration;
6
7fn main() {
8 println!("=== PRODUCTION LOGGER SIMULATION ===");
10 let prod_config = LoggerConfig::production();
12 println!("Production settings:");
13 println!(" - Log level: Info (no Debug or Trace messages)");
14 println!(" - File info: Hidden (cleaner logs)");
15 println!(" - Colors: Enabled (for better readability)");
16 println!(" - Date in console: Hidden (time only for brevity)\n");
17
18 format_and_print_logs("Production", &prod_config);
20
21 println!("\n\n=== DEVELOPMENT LOGGER SIMULATION ===");
23 let dev_config = LoggerConfig::development();
25 println!("Development settings:");
26 println!(" - Log level: Debug (includes debug messages)");
27 println!(" - File info: Shown (helps with debugging)");
28 println!(" - Colors: Enabled (for better readability)");
29 println!(" - Date in console: Hidden (time only for brevity)\n");
30
31 format_and_print_logs("Development", &dev_config);
33
34 println!("\nNote: In production mode, logs are more concise (no file info, only time)");
35 println!(
36 "but the log file still contains complete information including date and file details."
37 );
38
39 println!("\n=== ACTUAL LOGGER IMPLEMENTATION ===");
41 println!("Initializing a real logger with production settings...");
42 if let Err(e) = fstdout_logger::init_production_logger(Some("prod.log")) {
43 eprintln!("Failed to initialize logger: {e}");
44 return;
45 }
46
47 info!("This message was logged with the actual logger");
49 debug!("Debug info won't appear in production mode");
50 warn!("Warnings will appear");
51 error!("Errors will appear too");
52
53 println!("\nCheck 'prod.log' to see the file output format with full details!");
54}
55
56fn format_and_print_logs(context: &str, config: &LoggerConfig) {
58 let now = chrono::Local::now();
59 let timestamp = if config.show_date_in_stdout {
60 now.format("%Y-%m-%d %H:%M:%S").to_string()
61 } else {
62 now.format("%H:%M:%S").to_string()
63 };
64
65 let format_log = |level: &str, colored: bool, file_info: bool, msg: &str| {
67 let mut output = String::new();
68
69 let level_str = match (colored, level) {
71 (true, "ERROR") => "\x1b[1;31mERROR\x1b[0m", (true, "WARN") => "\x1b[1;33mWARN\x1b[0m", (true, "INFO") => "\x1b[1;34mINFO\x1b[0m", (true, "DEBUG") => "\x1b[32mDEBUG\x1b[0m", (true, "TRACE") => "TRACE", (_, _) => level, };
78
79 let time_part = if colored {
81 format!("\x1b[90m{timestamp}\x1b[0m") } else {
83 timestamp.clone()
84 };
85
86 if file_info {
88 let file_str = if colored {
89 "\x1b[90mexamples/production.rs:42\x1b[0m" } else {
91 "examples/production.rs:42"
92 };
93
94 write!(output, "[{time_part} {level_str} {file_str}] {msg}").unwrap();
95 } else {
96 write!(output, "[{time_part} {level_str}] {msg}").unwrap();
97 }
98
99 output
100 };
101
102 let msg = format!("{context} process starting up");
104 println!(
105 "{}",
106 format_log("INFO", config.use_colors, config.show_file_info, &msg)
107 );
108
109 let debug_msg = "Initializing subsystems with memory pool of 1024 bytes";
111 if config.level <= LevelFilter::Debug {
112 println!(
113 "{}",
114 format_log("DEBUG", config.use_colors, config.show_file_info, debug_msg)
115 );
116 }
117
118 for i in 1..=3 {
120 let msg = format!("Processing batch #{i}");
121 println!(
122 "{}",
123 format_log("INFO", config.use_colors, config.show_file_info, &msg)
124 );
125
126 if i == 2 {
127 let warn_msg = "Resource usage above threshold (82%)";
128 println!(
129 "{}",
130 format_log("WARN", config.use_colors, config.show_file_info, warn_msg)
131 );
132 }
133 sleep(Duration::from_millis(100)); }
135
136 let error_msg = "Failed to connect to database: timeout after 5 seconds";
138 println!(
139 "{}",
140 format_log("ERROR", config.use_colors, config.show_file_info, error_msg)
141 );
142
143 let end_msg = format!("{context} process completed");
145 println!(
146 "{}",
147 format_log("INFO", config.use_colors, config.show_file_info, &end_msg)
148 );
149}