1use tracing_subscriber::{fmt, EnvFilter, prelude::*, registry};
7use tracing_appender::non_blocking::WorkerGuard;
8use tracing_subscriber::fmt::format::{FormatEvent, FormatFields};
9use tracing_subscriber::fmt::FmtContext;
10use tracing::{Event, Subscriber, Level};
11use std::fmt as std_fmt;
12use colored::*;
13
14struct CustomFormatter;
15
16impl<S, N> FormatEvent<S, N> for CustomFormatter
17where
18 S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>,
19 N: for<'a> FormatFields<'a> + 'static,
20{
21 fn format_event(
22 &self,
23 _ctx: &FmtContext<'_, S, N>,
24 mut writer: fmt::format::Writer<'_>,
25 event: &Event<'_>,
26 ) -> std_fmt::Result {
27 let metadata = event.metadata();
28 let level = metadata.level();
29 let timestamp = chrono::Local::now().format("%Y-%m-%dT%H:%M:%S%.6fZ");
30
31 let level_str = format!("[{}]", level);
33 let level_colored = match *level {
34 Level::ERROR => level_str.red().bold(),
35 Level::WARN => level_str.yellow().bold(),
36 Level::INFO => level_str.green().bold(),
37 Level::DEBUG => level_str.blue().bold(),
38 Level::TRACE => level_str.magenta().bold(),
39 };
40
41 write!(writer, "{} {} ", level_colored, timestamp.to_string().dimmed())?;
42
43 _ctx.format_fields(writer.by_ref(), event)?;
44 writeln!(writer)
45 }
46}
47
48pub fn init() -> WorkerGuard {
49 let file_appender = tracing_appender::rolling::daily("storage/logs", "rustbasic.log");
50 let (non_blocking_file, guard) = tracing_appender::non_blocking(file_appender);
51
52 let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_|
53 "rustbasic=debug,tower_http=debug,axum_session=warn,sqlx=warn".into()
54 );
55
56 registry()
57 .with(env_filter)
58 .with(fmt::layer().event_format(CustomFormatter).with_ansi(true))
59 .with(fmt::layer().with_target(false).with_ansi(false).with_writer(non_blocking_file))
60 .init();
61
62 print_banner();
63 guard
64}
65
66fn print_banner() {
67 println!(r#"
68
69 ██████╗ ██╗ ██╗███████╗████████╗██████╗ █████╗ ███████╗██╗ ██████╗
70 ██╔══██╗██║ ██║██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██╔════╝██║██╔════╝
71 ██████╔╝██║ ██║███████╗ ██║ ██████╔╝███████║███████╗██║██║
72 ██╔══██╗██║ ██║╚════██║ ██║ ██╔══██╗██╔══██║╚════██║██║██║
73 ██║ ██║╚██████╔╝███████║ ██║ ██████╔╝██║ ██║███████║██║╚██████╗
74 ╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═════╝
75 "#);
76 println!(" >> RustBasic Full-stack Framework - Version 2026 <<\n");
77}