mas_tower/tracing/
layer.rs

1// Copyright 2024 New Vector Ltd.
2// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
3//
4// SPDX-License-Identifier: AGPL-3.0-only
5// Please see LICENSE in the repository root for full details.
6
7use tower::Layer;
8use tracing::Span;
9
10use crate::{enrich_span_fn, make_span_fn, utils::FnWrapper};
11
12#[derive(Clone, Debug)]
13pub struct TraceLayer<MakeSpan, OnResponse = (), OnError = ()> {
14    make_span: MakeSpan,
15    on_response: OnResponse,
16    on_error: OnError,
17}
18
19impl<F> TraceLayer<FnWrapper<F>> {
20    #[must_use]
21    pub fn from_fn<T>(f: F) -> TraceLayer<FnWrapper<F>>
22    where
23        F: Fn(&T) -> Span,
24    {
25        TraceLayer::new(make_span_fn(f))
26    }
27}
28
29impl<MakeSpan> TraceLayer<MakeSpan> {
30    #[must_use]
31    pub fn new(make_span: MakeSpan) -> Self {
32        Self {
33            make_span,
34            on_response: (),
35            on_error: (),
36        }
37    }
38}
39
40impl<MakeSpan, OnResponse, OnError> TraceLayer<MakeSpan, OnResponse, OnError> {
41    #[must_use]
42    pub fn on_response<NewOnResponse>(
43        self,
44        on_response: NewOnResponse,
45    ) -> TraceLayer<MakeSpan, NewOnResponse, OnError> {
46        TraceLayer {
47            make_span: self.make_span,
48            on_response,
49            on_error: self.on_error,
50        }
51    }
52
53    #[must_use]
54    pub fn on_response_fn<F, T>(self, f: F) -> TraceLayer<MakeSpan, FnWrapper<F>, OnError>
55    where
56        F: Fn(&Span, &T),
57    {
58        self.on_response(enrich_span_fn(f))
59    }
60
61    #[must_use]
62    pub fn on_error<NewOnError>(
63        self,
64        on_error: NewOnError,
65    ) -> TraceLayer<MakeSpan, OnResponse, NewOnError> {
66        TraceLayer {
67            make_span: self.make_span,
68            on_response: self.on_response,
69            on_error,
70        }
71    }
72
73    pub fn on_error_fn<F, E>(self, f: F) -> TraceLayer<MakeSpan, OnResponse, FnWrapper<F>>
74    where
75        F: Fn(&Span, &E),
76    {
77        self.on_error(enrich_span_fn(f))
78    }
79}
80
81impl<S, MakeSpan, OnResponse, OnError> Layer<S> for TraceLayer<MakeSpan, OnResponse, OnError>
82where
83    MakeSpan: Clone,
84    OnResponse: Clone,
85    OnError: Clone,
86{
87    type Service = super::service::TraceService<S, MakeSpan, OnResponse, OnError>;
88
89    fn layer(&self, inner: S) -> Self::Service {
90        super::service::TraceService::new(
91            inner,
92            self.make_span.clone(),
93            self.on_response.clone(),
94            self.on_error.clone(),
95        )
96    }
97}