1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
use tower_http::trace::HttpMakeClassifier;
use tracing::Level;

#[derive(Clone)]
pub struct MakeSpan;

impl<B> tower_http::trace::MakeSpan<B> for MakeSpan {
    fn make_span(&mut self, request: &axum::http::Request<B>) -> tracing::Span {
        use synd_o11y::opentelemetry::extension::*;
        let cx = synd_o11y::opentelemetry::http::extract(request.headers());

        let request_id = cx
            .baggage()
            .get(synd_o11y::REQUEST_ID_KEY)
            .map_or("?".into(), |v| v.as_str());

        let span = tracing::span!(
            Level::INFO,
            "http",
            method = %request.method(),
            uri = %request.uri(),
            %request_id,
        );

        span.set_parent(cx);
        span
    }
}

#[derive(Clone)]
pub struct OnRequest;

impl<B> tower_http::trace::OnRequest<B> for OnRequest {
    fn on_request(&mut self, _request: &axum::http::Request<B>, _span: &tracing::Span) {
        // do nothing
    }
}

pub fn layer() -> tower_http::trace::TraceLayer<
    HttpMakeClassifier,
    MakeSpan,
    OnRequest,
    tower_http::trace::DefaultOnResponse,
> {
    tower_http::trace::TraceLayer::new_for_http()
        .make_span_with(MakeSpan)
        .on_request(OnRequest)
        .on_response(tower_http::trace::DefaultOnResponse::default().level(Level::INFO))
}