mirror of
https://github.com/tokio-rs/tracing.git
synced 2026-03-30 11:21:27 +00:00
* subscriber: add less-verbose configuration APIs Signed-off-by: Eliza Weisman <eliza@buoyant.io> * even nicer easymode Signed-off-by: Eliza Weisman <eliza@buoyant.io> * wip## Motivation Users have said fairly frequently that configuring new subscribers in an application is unnecessarily verbose and confusing. We should try to make this nicer, especially as it's a common "on ramp" for new `tracing` users. ## Solution This branch adds new APIs, inspired by `tonic` and `warp`, that should make setting up a subscriber a little less verbose. This includes: - Many modules in `tracing-subscriber` now expose free functions that construct default instances of various types. This makes configuring subscribers using these types more concise, a la `warp`. - An extension trait for adding `.set_default`, `.init`, and `.try_init` methods to subscribers. This generalizes the similar functions on `fmt`'s `SubscriberBuilder` to work with other subscribers. All the old APIs are still left as they were previously. The new APIs just provide shorthand for them. Signed-off-by: Eliza Weisman <eliza@buoyant.io>
123 lines
3.9 KiB
Rust
123 lines
3.9 KiB
Rust
#![deny(rust_2018_idioms)]
|
|
|
|
use http::{Method, Request, Response, StatusCode};
|
|
use hyper::{
|
|
service::{make_service_fn, service_fn},
|
|
Body, Server,
|
|
};
|
|
use std::str;
|
|
use tracing::{debug, info, span, Level};
|
|
use tracing_futures::Instrument;
|
|
|
|
async fn echo(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
|
|
let span = span!(
|
|
Level::INFO,
|
|
"request",
|
|
method = ?req.method(),
|
|
uri = ?req.uri(),
|
|
headers = ?req.headers()
|
|
);
|
|
let _enter = span.enter();
|
|
info!("received request");
|
|
let mut response = Response::new(Body::empty());
|
|
|
|
let (rsp_span, resp) = match (req.method(), req.uri().path()) {
|
|
// Serve some instructions at /
|
|
(&Method::GET, "/") => {
|
|
const BODY: &str = "Try POSTing data to /echo";
|
|
*response.body_mut() = Body::from(BODY);
|
|
(span!(Level::INFO, "response", body = %(&BODY)), response)
|
|
}
|
|
|
|
// Simply echo the body back to the client.
|
|
(&Method::POST, "/echo") => {
|
|
let span = span!(Level::INFO, "response", response_kind = %"echo");
|
|
*response.body_mut() = req.into_body();
|
|
(span, response)
|
|
}
|
|
|
|
// Convert to uppercase before sending back to client.
|
|
(&Method::POST, "/echo/uppercase") => {
|
|
let body = hyper::body::to_bytes(req).await?;
|
|
let upper = body
|
|
.iter()
|
|
.map(|byte| byte.to_ascii_uppercase())
|
|
.collect::<Vec<u8>>();
|
|
debug!(
|
|
body = ?str::from_utf8(&body[..]),
|
|
uppercased = ?str::from_utf8(&upper[..]),
|
|
"uppercased request body"
|
|
);
|
|
|
|
*response.body_mut() = Body::from(upper);
|
|
(
|
|
span!(Level::INFO, "response", response_kind = %"uppercase"),
|
|
response,
|
|
)
|
|
}
|
|
|
|
// Reverse the entire body before sending back to the client.
|
|
(&Method::POST, "/echo/reversed") => {
|
|
let span = span!(Level::TRACE, "response", response_kind = %"reversed");
|
|
let _enter = span.enter();
|
|
let body = hyper::body::to_bytes(req).await?;
|
|
let reversed = body.iter().rev().cloned().collect::<Vec<u8>>();
|
|
debug!(
|
|
body = ?str::from_utf8(&body[..]),
|
|
"reversed request body"
|
|
);
|
|
*response.body_mut() = Body::from(reversed);
|
|
(
|
|
span!(Level::INFO, "reversed", body = ?(&response.body())),
|
|
response,
|
|
)
|
|
}
|
|
|
|
// The 404 Not Found route...
|
|
_ => {
|
|
*response.status_mut() = StatusCode::NOT_FOUND;
|
|
(
|
|
span!(
|
|
Level::TRACE,
|
|
"response",
|
|
body = ?(),
|
|
status = ?StatusCode::NOT_FOUND,
|
|
),
|
|
response,
|
|
)
|
|
}
|
|
};
|
|
let f = async { resp }.instrument(rsp_span);
|
|
Ok(f.await)
|
|
}
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
use tracing_log::env_logger::BuilderExt;
|
|
|
|
let subscriber = tracing_subscriber::fmt()
|
|
.with_max_level(Level::TRACE)
|
|
.finish();
|
|
let mut builder = env_logger::Builder::new();
|
|
builder
|
|
.filter(Some("hyper_echo"), log::LevelFilter::Off)
|
|
.filter(Some("hyper"), log::LevelFilter::Trace)
|
|
.emit_traces() // from `tracing_log::env_logger::BuilderExt`
|
|
.try_init()?;
|
|
tracing::subscriber::set_global_default(subscriber)?;
|
|
|
|
let local_addr: std::net::SocketAddr = ([127, 0, 0, 1], 3000).into();
|
|
let server_span = span!(Level::TRACE, "server", %local_addr);
|
|
let _enter = server_span.enter();
|
|
|
|
let service = make_service_fn(|_| async { Ok::<_, hyper::Error>(service_fn(echo)) });
|
|
let server = Server::bind(&local_addr)
|
|
.serve(service)
|
|
.instrument(server_span.clone());
|
|
|
|
info!("listening...");
|
|
server.await?;
|
|
|
|
Ok(())
|
|
}
|