Skip to content

Commit 66ad1dc

Browse files
committed
add tide-log
1 parent a50668f commit 66ad1dc

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
members = [
33
"tide",
44
"examples",
5+
"tide-log",
56
]
67

78
[patch.crates-io]

tide-log/Cargo.toml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[package]
2+
authors = [
3+
"Tide Developers"
4+
]
5+
description = "Tide middleware for logging"
6+
documentation = "https://docs.rs/tide"
7+
keywords = ["tide", "http", "web", "framework", "async", "middleware"]
8+
categories = [
9+
"network-programming",
10+
"asynchronous",
11+
"web-programming::http-server"
12+
]
13+
edition = "2018"
14+
license = "MIT OR Apache-2.0"
15+
name = "tide-log"
16+
readme = "README.md"
17+
repository = "https://github.com/rustasync/tide"
18+
version = "0.1.0"
19+
20+
[dependencies]
21+
tide = { path = "../tide" }
22+
futures-preview = "0.3.0-alpha.16"
23+
http = "0.1"
24+
log = "0.4.6"

tide-log/src/lib.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#![feature(async_await)]
2+
#![deny(
3+
nonstandard_style,
4+
rust_2018_idioms,
5+
future_incompatible,
6+
missing_debug_implementations
7+
)]
8+
9+
use futures::future::BoxFuture;
10+
use log::{info, trace};
11+
use tide::{
12+
middleware::{Middleware, Next},
13+
Context, Response,
14+
};
15+
16+
macro_rules! box_async {
17+
{$($t:tt)*} => {
18+
::futures::future::FutureExt::boxed(async move { $($t)* })
19+
};
20+
}
21+
22+
/// A simple requests logger
23+
///
24+
/// # Examples
25+
///
26+
/// ```rust
27+
///
28+
/// let mut app = tide::App::new();
29+
/// app.middleware(tide_log::RequestLogger::new());
30+
/// ```
31+
#[derive(Debug, Clone, Default)]
32+
pub struct RequestLogger;
33+
34+
impl RequestLogger {
35+
pub fn new() -> Self {
36+
Self::default()
37+
}
38+
39+
async fn log_basic<'a, Data: Send + Sync + 'static>(
40+
&'a self,
41+
ctx: Context<Data>,
42+
next: Next<'a, Data>,
43+
) -> tide::Response {
44+
let path = ctx.uri().path().to_owned();
45+
let method = ctx.method().as_str().to_owned();
46+
trace!("IN => {} {}", method, path);
47+
let start = std::time::Instant::now();
48+
let res = next.run(ctx).await;
49+
let status = res.status();
50+
info!(
51+
"{} {} {} {}ms",
52+
method,
53+
path,
54+
status.as_str(),
55+
start.elapsed().as_millis()
56+
);
57+
res
58+
}
59+
}
60+
61+
impl<Data: Send + Sync + 'static> Middleware<Data> for RequestLogger {
62+
fn handle<'a>(&'a self, ctx: Context<Data>, next: Next<'a, Data>) -> BoxFuture<'a, Response> {
63+
box_async! { self.log_basic(ctx, next).await }
64+
}
65+
}

0 commit comments

Comments
 (0)