iron_slog/
lib.rs

1//!
2//! Logger middleware for Iron framework, with slog-rs
3//!
4
5#![deny(missing_docs, warnings)]
6
7#[macro_use]
8extern crate slog;
9extern crate chrono;
10extern crate iron;
11
12mod format;
13pub use format::{LogContext, LogFormatter, DefaultLogFormatter};
14
15use std::fmt;
16use iron::{Request, Response, IronResult, Handler};
17use slog::Logger;
18
19
20struct Format<'req, 'res, 'a: 'req, 'b: 'a, 's, 'e, 'f, F: ?Sized + LogFormatter> {
21    context: LogContext<'req, 'res, 'a, 'b, 's, 'e>,
22    formatter: &'f F,
23}
24
25impl<'req, 'res, 'a: 'req, 'b: 'a, 's, 'e, 'f, F: ?Sized + LogFormatter> fmt::Display
26    for Format<'req, 'res, 'a, 'b, 's, 'e, 'f, F> {
27    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28        self.formatter.format(f, &self.context)
29    }
30}
31
32
33/// Middleware for logging information of request and response, to certain logger.
34pub struct LoggerMiddleware<H: Handler, F: LogFormatter> {
35    formatter: F,
36    handler: H,
37    logger: Logger,
38}
39
40impl<H: Handler, F: LogFormatter> LoggerMiddleware<H, F> {
41    /// Create a `LoggerMiddleware` middleware with specified `logger` and `formatter`.
42    ///
43    /// ```ignore
44    /// let handler = create_your_handler();
45    /// let logger: slog::Logger = create_your_logger();
46    /// let formatter = DefaultLogFormatter;
47    /// let logged_handler = LoggerHandler::new(handler, logger, formatter);
48    /// ```
49    pub fn new(handler: H, logger: Logger, formatter: F) -> Self {
50        LoggerMiddleware {
51            handler,
52            logger,
53            formatter,
54        }
55    }
56}
57
58impl<H: Handler, F: LogFormatter> Handler for LoggerMiddleware<H, F> {
59    fn handle(&self, req: &mut Request) -> IronResult<Response> {
60        let start_time = chrono::Local::now();
61        let result = self.handler.handle(req);
62        let end_time = chrono::Local::now();
63
64        match result {
65            Ok(res) => {
66                info!(self.logger,
67                      "{}",
68                      Format {
69                          context: LogContext {
70                              req,
71                              res: &res,
72                              start_time: &start_time,
73                              end_time: &end_time,
74                          },
75                          formatter: &self.formatter,
76                      });
77                Ok(res)
78            }
79            Err(err) => {
80                error!(self.logger,
81                       "{}",
82                       Format {
83                           context: LogContext {
84                               req,
85                               res: &err.response,
86                               start_time: &start_time,
87                               end_time: &end_time,
88                           },
89                           formatter: &self.formatter,
90                       });
91                Err(err)
92            }
93        }
94    }
95}