timber_rust/service/
fallback.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Dante Doménech Martinez dante19031999@gmail.com
3
4use crate::Message;
5use crate::service::ServiceError;
6use chrono::{SecondsFormat, Utc};
7
8/// A strategy for handling log delivery failures.
9///
10/// The `Fallback` trait defines how the system should react when a log service
11/// is unable to process a [message][`Message`] after exhausting all retry attempts.
12///
13/// ### Use Cases
14/// - **Local Logging**: Writing failed logs to `stdout`, `stderr`, or a local file.
15/// - **Alerting**: Triggering a secondary notification system if critical logs are lost.
16/// - **Buffering**: Storing failed [messages][`Message`] in a persistent queue for later recovery.
17///
18/// ### Thread Safety
19/// Since the worker thread calls this trait's method, implementations must be
20/// thread-safe if they involve shared state.
21pub trait Fallback {
22    /// Handles a [message][`Message`] that could not be delivered to the primary service.
23    ///
24    /// This method is invoked by the background worker when a [`ServiceError`] occurs
25    /// that cannot be recovered through retries.
26    ///
27    /// # Default Implementation
28    ///
29    /// The default implementation prints a formatted critical error message to **stderr**.
30    /// It includes:
31    /// 1. The specific [`ServiceError`] description.
32    /// 2. An RFC3339-compliant timestamp with nanosecond precision.
33    /// 3. The log level and the original message content.
34    ///
35    /// This ensures that even if the remote collector is unreachable,
36    /// the logs are preserved in the system's standard error stream.
37    ///
38    /// # Parameters
39    /// - `error`: The specific error that caused the delivery failure.
40    /// - `message`: The original log [message][`Message`] that failed to be delivered.
41    fn fallback(&self, error: &ServiceError, message: &Message) {
42        let now: chrono::DateTime<Utc> = message.instant().into();
43        eprintln!(
44            "[CRITICAL LOGGER FAILURE] {}: {} [ {} ] {}",
45            error,
46            now.to_rfc3339_opts(SecondsFormat::Nanos, true),
47            message.level(),
48            message.content()
49        );
50    }
51}