use super::LatencyUnit;
use super::DEFAULT_MESSAGE_LEVEL;
use std::fmt::Debug;
use std::time::Duration;
use tracing::Level;
use tracing::Span;
pub trait OnResponse<Res> {
fn on_response(self, res: &Res, done_in: Duration, span: &Span);
}
impl<Res> OnResponse<Res> for () {
#[inline]
fn on_response(self, _: &Res, _: Duration, _: &Span) {}
}
impl<F, Res> OnResponse<Res> for F
where
F: FnOnce(&Res, Duration, &Span),
{
fn on_response(self, response: &Res, done_in: Duration, span: &Span) {
self(response, done_in, span)
}
}
#[derive(Clone, Debug)]
pub struct DefaultOnResponse {
level: Level,
latency_unit: LatencyUnit,
}
impl Default for DefaultOnResponse {
fn default() -> Self {
Self {
level: DEFAULT_MESSAGE_LEVEL,
latency_unit: LatencyUnit::Millis,
}
}
}
impl DefaultOnResponse {
pub fn new() -> Self {
Self::default()
}
pub fn level(mut self, level: Level) -> Self {
self.level = level;
self
}
pub fn latency_unit(mut self, latency_unit: LatencyUnit) -> Self {
self.latency_unit = latency_unit;
self
}
}
#[allow(unused_macros)]
macro_rules! log_pattern_match {
(
$this:expr, $res:expr, $done_in:expr, [$($level:ident),*]
) => {
match ($this.level, $this.latency_unit) {
$(
(Level::$level, LatencyUnit::Seconds) => {
tracing::event!(
Level::$level,
done_in = format_args!("{}s", $done_in.as_secs_f64()),
result = format_args!("{:?}", $res),
"job.done"
);
}
(Level::$level, LatencyUnit::Millis) => {
tracing::event!(
Level::$level,
done_in = format_args!("{}ms", $done_in.as_millis()),
result = format_args!("{:?}", $res),
"job.done"
);
}
(Level::$level, LatencyUnit::Micros) => {
tracing::event!(
Level::$level,
done_in = format_args!("{}μs", $done_in.as_micros()),
result = format_args!("{:?}", $res),
"job.done"
);
}
(Level::$level, LatencyUnit::Nanos) => {
tracing::event!(
Level::$level,
done_in = format_args!("{}ns", $done_in.as_nanos()),
result = format_args!("{:?}", $res),
"job.done"
);
}
)*
}
};
}
impl<Res: Debug> OnResponse<Res> for DefaultOnResponse {
fn on_response(self, response: &Res, done_in: Duration, _: &Span) {
log_pattern_match!(self, response, done_in, [ERROR, WARN, INFO, DEBUG, TRACE]);
}
}