dhttp/services/
log.rs

1use chrono_lite::{Tm, time, localtime};
2use crate::core::{HttpLogger, HttpError};
3use crate::reqres::{HttpRequest, HttpResponse};
4use crate::util::escape;
5
6/// Default logger implementation
7pub struct DefaultLogger;
8impl DefaultLogger {
9    fn format(&self, req: &HttpRequest, res: &HttpResponse) -> String {
10        let addr = req.addr;
11        let method = escape::control_sequences(req.method.as_str());
12        let route = escape::control_sequences(&req.route);
13
14        let code = res.code;
15        let desc = code.as_str();
16
17        let Tm { tm_mday, tm_mon, tm_year, tm_hour, tm_min, tm_sec, .. } = localtime(time()).expect("date out of range");
18        let year = tm_year + 1900;
19        let month = tm_mon + 1;
20        let date = format_args!("{tm_hour:02}:{tm_min:02}:{tm_sec:02} {tm_mday:02}-{month:02}-{year}");
21
22        // User-Agents are long, print only first segment
23        let agent = req.get_header("User-Agent").and_then(|a| a.split(' ').next()).unwrap_or("-");
24        let agent = escape::control_sequences(agent);
25        format!("[{date}] {addr} {agent} {method} {route} -> {code} {desc}")
26    }
27}
28
29impl HttpLogger for DefaultLogger {
30    fn log(&self, req: &HttpRequest, res: &HttpResponse) {
31        println!("{}", self.format(req, res));
32    }
33
34    fn err(&self, req: &HttpRequest, res: &HttpResponse, error: &dyn HttpError) {
35        println!("{} ({}: {})", self.format(req, res), error.name(), error);
36    }
37}