use crate::error::JobError;
use super::{LatencyUnit, DEFAULT_ERROR_LEVEL};
use std::time::Duration;
use tracing::{Level, Span};
pub trait OnFailure {
fn on_failure(&mut self, error: &JobError, latency: Duration, span: &Span);
}
impl OnFailure for () {
#[inline]
fn on_failure(&mut self, _: &JobError, _: Duration, _: &Span) {}
}
impl<F> OnFailure for F
where
F: FnMut(&JobError, Duration, &Span),
{
fn on_failure(&mut self, error: &JobError, latency: Duration, span: &Span) {
self(error, latency, span)
}
}
#[derive(Clone, Debug)]
pub struct DefaultOnFailure {
level: Level,
latency_unit: LatencyUnit,
}
impl Default for DefaultOnFailure {
fn default() -> Self {
Self {
level: DEFAULT_ERROR_LEVEL,
latency_unit: LatencyUnit::Millis,
}
}
}
impl DefaultOnFailure {
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
}
}
macro_rules! log_pattern_match {
(
$this:expr, $span:expr, $error:expr, $latency:expr, [$($level:ident),*]
) => {
match ($this.level, $this.latency_unit) {
$(
(Level::$level, LatencyUnit::Seconds) => {
tracing::event!(
parent: $span,
Level::$level,
done_in = format_args!("{} s", $latency.as_secs_f64()),
"{}",
format_args!("{}", $error)
);
}
(Level::$level, LatencyUnit::Millis) => {
tracing::event!(
parent: $span,
Level::$level,
done_in = format_args!("{} ms", $latency.as_millis()),
"{}",
format_args!("{}", $error)
);
}
(Level::$level, LatencyUnit::Micros) => {
tracing::event!(
parent: $span,
Level::$level,
done_in = format_args!("{} μs", $latency.as_micros()),
"{}",
format_args!("{}", $error)
);
}
(Level::$level, LatencyUnit::Nanos) => {
tracing::event!(
parent: $span,
Level::$level,
done_in = format_args!("{} ns", $latency.as_nanos()),
"{}",
format_args!("{}", $error)
);
}
)*
}
};
}
impl OnFailure for DefaultOnFailure {
fn on_failure(&mut self, error: &JobError, latency: Duration, span: &Span) {
log_pattern_match!(
self,
span,
error,
latency,
[ERROR, WARN, INFO, DEBUG, TRACE]
);
}
}