tower_http/trace/
on_failure.rs1use super::{Latency, DEFAULT_ERROR_LEVEL};
2use crate::LatencyUnit;
3use std::{fmt, time::Duration};
4use tracing::{Level, Span};
5
6pub trait OnFailure<FailureClass> {
13 fn on_failure(&mut self, failure_classification: FailureClass, latency: Duration, span: &Span);
25}
26
27impl<FailureClass> OnFailure<FailureClass> for () {
28 #[inline]
29 fn on_failure(&mut self, _: FailureClass, _: Duration, _: &Span) {}
30}
31
32impl<F, FailureClass> OnFailure<FailureClass> for F
33where
34 F: FnMut(FailureClass, Duration, &Span),
35{
36 fn on_failure(&mut self, failure_classification: FailureClass, latency: Duration, span: &Span) {
37 self(failure_classification, latency, span)
38 }
39}
40
41#[derive(Clone, Debug)]
45pub struct DefaultOnFailure {
46 level: Level,
47 latency_unit: LatencyUnit,
48}
49
50impl Default for DefaultOnFailure {
51 fn default() -> Self {
52 Self {
53 level: DEFAULT_ERROR_LEVEL,
54 latency_unit: LatencyUnit::Millis,
55 }
56 }
57}
58
59impl DefaultOnFailure {
60 pub fn new() -> Self {
62 Self::default()
63 }
64
65 pub fn level(mut self, level: Level) -> Self {
71 self.level = level;
72 self
73 }
74
75 pub fn latency_unit(mut self, latency_unit: LatencyUnit) -> Self {
79 self.latency_unit = latency_unit;
80 self
81 }
82}
83
84impl<FailureClass> OnFailure<FailureClass> for DefaultOnFailure
85where
86 FailureClass: fmt::Display,
87{
88 fn on_failure(&mut self, failure_classification: FailureClass, latency: Duration, _: &Span) {
89 let latency = Latency {
90 unit: self.latency_unit,
91 duration: latency,
92 };
93 event_dynamic_lvl!(
94 self.level,
95 classification = %failure_classification,
96 %latency,
97 "response failed"
98 );
99 }
100}