timber_rust/factory/
awscout.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Dante Doménech Martinez dante19031999@gmail.com
3
4#![cfg(feature = "awscout")]
5#![cfg_attr(docsrs, doc(cfg(feature = "awscout")))]
6
7use crate::{Concurrency, DirectLogger, Logger, QueuedLogger, service};
8
9/// A factory for creating various AWS CloudWatch logging implementations.
10///
11/// This factory provides entry points for three primary CloudWatch logging strategies:
12/// 1. **Config-based**: Explicitly providing AWS credentials and region.
13/// 2. **Env-based**: Automatic credential discovery using the standard AWS environment variables.
14/// 3. **Cout-based**: JSON-formatted stdout logging for Lambda, ECS, and Fargate.
15pub struct CloudWatch {}
16
17impl CloudWatch {
18    /// Begins building a CloudWatch `stdout` JSON logger.
19    ///
20    /// This is recommended for AWS Lambda and containerized services where the
21    /// log driver handles the actual AWS API interaction.
22    pub fn cout(self) -> CloudWatchCout {
23        CloudWatchCout::default()
24    }
25}
26
27/// A builder state for the high-performance JSON-to-stdout logging service.
28///
29/// Defaults to 3 retries and 1 background worker to ensure ordered log ingestion.
30pub struct CloudWatchCout {
31    max_retries: usize,
32    worker_count: usize,
33}
34
35impl CloudWatchCout {
36    /// Creates a new Cout factory with specific retry and worker settings.
37    pub fn new(max_retries: usize, worker_count: usize) -> Self {
38        Self {
39            max_retries,
40            worker_count,
41        }
42    }
43
44    /// Returns the configured background worker count.
45    pub fn get_worker_count(&self) -> usize {
46        self.worker_count
47    }
48
49    /// Returns the configured maximum retry attempts.
50    pub fn get_max_retries(&self) -> usize {
51        self.max_retries
52    }
53
54    /// Sets the number of background workers (only applicable for [`Concurrency::Async`]).
55    pub fn worker_count(self, worker_count: usize) -> CloudWatchCout {
56        CloudWatchCout {
57            worker_count,
58            ..self
59        }
60    }
61
62    /// Sets the maximum retry attempts if the standard output write fails.
63    pub fn max_retries(self, max_retries: usize) -> CloudWatchCout {
64        CloudWatchCout {
65            max_retries,
66            ..self
67        }
68    }
69
70    /// Finalizes the logger using the specified [`Concurrency`] model.
71    pub fn build(self, concurrency: Concurrency) -> Logger {
72        match concurrency {
73            Concurrency::Sync => self.build_direct(),
74            Concurrency::Async => self.build_queued(),
75        }
76    }
77
78    /// Shortcut for building a synchronous [`DirectLogger`].
79    pub fn build_direct(self) -> Logger {
80        Logger::new(self.build_impl_direct())
81    }
82
83    /// Shortcut for building an asynchronous [`QueuedLogger`].
84    pub fn build_queued(self) -> Logger {
85        Logger::new(self.build_impl_queued())
86    }
87
88    /// Builds the underlying [`DirectLogger`] implementation.
89    pub fn build_impl_direct(self) -> Box<DirectLogger> {
90        DirectLogger::new(service::CloudWatchCout::new(), self.max_retries)
91    }
92
93    /// Builds the underlying [`QueuedLogger`] implementation.
94    pub fn build_impl_queued(self) -> Box<QueuedLogger> {
95        QueuedLogger::new(
96            service::CloudWatchCout::new(),
97            self.max_retries,
98            self.worker_count,
99        )
100    }
101}
102
103impl Default for CloudWatchCout {
104    /// Provides default settings: 3 retries and 1 worker thread.
105    fn default() -> Self {
106        CloudWatchCout {
107            worker_count: 1,
108            max_retries: 3,
109        }
110    }
111}