production/
production.rs

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    // Step 1: Compare production vs development logger output
9    println!("=== PRODUCTION LOGGER SIMULATION ===");
10    // Production config: no file info, INFO level minimum
11    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    // Manually format some logs with production settings
19    format_and_print_logs("Production", &prod_config);
20
21    // Reset logs
22    println!("\n\n=== DEVELOPMENT LOGGER SIMULATION ===");
23    // Development config: with file info, DEBUG level minimum
24    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    // Manually format logs with development settings
32    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    // Step 2: Initialize a real logger for demonstration
40    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    // Log some real messages
48    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
56// Helper function to format and print example log messages
57fn 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    // Helper function to format a log message
66    let format_log = |level: &str, colored: bool, file_info: bool, msg: &str| {
67        let mut output = String::new();
68
69        // Format the level with appropriate color if needed
70        let level_str = match (colored, level) {
71            (true, "ERROR") => "\x1b[1;31mERROR\x1b[0m", // Bold Red
72            (true, "WARN") => "\x1b[1;33mWARN\x1b[0m",   // Bold Yellow
73            (true, "INFO") => "\x1b[1;34mINFO\x1b[0m",   // Bold Blue
74            (true, "DEBUG") => "\x1b[32mDEBUG\x1b[0m",   // Green
75            (true, "TRACE") => "TRACE",                  // Normal
76            (_, _) => level,                             // No color
77        };
78
79        // Format timestamp
80        let time_part = if colored {
81            format!("\x1b[90m{timestamp}\x1b[0m") // Dimmed
82        } else {
83            timestamp.clone()
84        };
85
86        // Include file info if needed
87        if file_info {
88            let file_str = if colored {
89                "\x1b[90mexamples/production.rs:42\x1b[0m" // Dimmed
90            } 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    // Process start
103    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    // Debug message (will only show in development mode)
110    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    // Processing loop with simulated delay
119    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)); // Shorter delay for demo
134    }
135
136    // Error example
137    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    // Process end
144    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}