rama_core/layer/
trace_err.rs1use crate::{Context, Layer, Service};
2use rama_utils::macros::define_inner_service_accessors;
3use std::fmt;
4
5pub struct TraceErr<S> {
8 inner: S,
9 level: tracing::Level,
10}
11
12impl<S> fmt::Debug for TraceErr<S>
13where
14 S: fmt::Debug,
15{
16 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17 f.debug_struct("TraceErr")
18 .field("inner", &self.inner)
19 .field("level", &self.level)
20 .finish()
21 }
22}
23
24impl<S> Clone for TraceErr<S>
25where
26 S: Clone,
27{
28 fn clone(&self) -> Self {
29 Self {
30 inner: self.inner.clone(),
31 level: self.level,
32 }
33 }
34}
35
36#[derive(Clone, Debug)]
40pub struct TraceErrLayer {
41 level: tracing::Level,
42}
43
44impl<S> TraceErr<S> {
45 pub const fn new(inner: S) -> Self {
47 Self::with_level(inner, tracing::Level::ERROR)
48 }
49
50 pub const fn with_level(inner: S, level: tracing::Level) -> Self {
52 TraceErr { inner, level }
53 }
54
55 define_inner_service_accessors!();
56}
57
58impl<S, State, Request> Service<State, Request> for TraceErr<S>
59where
60 Request: Send + 'static,
61 S: Service<State, Request, Error: std::fmt::Display + Send + Sync + 'static>,
62 State: Clone + Send + Sync + 'static,
63{
64 type Response = S::Response;
65 type Error = S::Error;
66
67 #[inline]
68 async fn serve(
69 &self,
70 ctx: Context<State>,
71 req: Request,
72 ) -> Result<Self::Response, Self::Error> {
73 let level = self.level;
74 let res = self.inner.serve(ctx, req).await;
75 if let Err(ref err) = res {
76 match level {
77 tracing::Level::TRACE => tracing::trace!(error = %err, "rama service failed"),
78 tracing::Level::DEBUG => tracing::debug!(error = %err, "rama service failed"),
79 tracing::Level::INFO => tracing::info!(error = %err, "rama service failed"),
80 tracing::Level::WARN => tracing::warn!(error = %err, "rama service failed"),
81 tracing::Level::ERROR => tracing::error!(error = %err, "rama service failed"),
82 }
83 }
84 res
85 }
86}
87
88impl TraceErrLayer {
89 pub const fn new() -> Self {
91 Self::with_level(tracing::Level::ERROR)
92 }
93
94 pub const fn with_level(level: tracing::Level) -> Self {
96 TraceErrLayer { level }
97 }
98}
99
100impl Default for TraceErrLayer {
101 fn default() -> Self {
102 Self::new()
103 }
104}
105
106impl<S> Layer<S> for TraceErrLayer {
107 type Service = TraceErr<S>;
108
109 fn layer(&self, inner: S) -> Self::Service {
110 TraceErr::with_level(inner, self.level)
111 }
112}