1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
// SPDX-License-Identifier: Apache-2.0
// Copyright 2026 Dante Doménech Martinez dante19031999@gmail.com
use crateCloudWatch as CloudWatchService;
use crate;
use crate;
use crate::;
use Any;
use Arc;
use Sender;
use thread;
use JoinHandle;
use ;
/// A high-level, thread-safe logger implementation for AWS CloudWatch.
///
/// This structure acts as a bridge between the application's logging calls and the
/// asynchronous AWS SDK. It implements a **producer-consumer pattern** using a
/// dedicated background worker thread to ensure that logging operations do not
/// block the main application execution.
///
/// # Architecture
/// 1. **Producer ([`log`][Self::log])**: Receives [`Message`] objects, timestamps them,
/// and pushes them into an internal MPSC (Multi-Producer, Single-Consumer) channel.
/// 2. **Consumer (`worker`)**: A dedicated background thread that
/// drains the channel using a **greedy-drain** strategy, batching logs to
/// optimize network throughput to AWS.
/// 3. **Service Layer**: Handles the actual communication with the CloudWatch API
/// via the internal Tokio runtime.
///
/// # Performance & Thread Safety
/// - **Non-blocking**: The `log` method is essentially non-blocking, as it only
/// performs a channel send operation.
/// - **Graceful Shutdown**: Implements [`Drop`] to ensure that the channel is closed
/// and all pending logs are flushed to AWS before the thread joins and the
/// application terminates.
///
/// # Alternative: CloudWatch via Standard Output (Cout)
///
/// While this [`CloudWatch`] implementation provides a robust, SDK-based integration
/// with the AWS API, many modern AWS environments are optimized for "Log Driver"
/// ingestion.
///
/// If your application runs in **AWS Lambda**, **ECS** (with the `awslogs` driver),
/// or **Fargate**, you may prefer using the [`CloudWatchCout`][`crate::service::CloudWatchCout`] service.
///
/// ### Why use the `Cout` Alternative?
/// * **Performance**: Writing to `stdout` is significantly faster than performing
/// HTTPS requests, even with background workers. It avoids the CPU and memory
/// overhead of the AWS SDK and TLS stack.
/// * **Security**: You do not need to provide AWS IAM credentials (like Access Keys)
/// to your application code. The execution environment (e.g., the Lambda Role)
/// automatically handles the permissions for the captured stream.
/// * **Resilience**: If the network is unstable, logs are buffered by the container
/// runtime or orchestrator rather than occupying your application's heap memory.
///
/// ### Comparison
/// | Feature | SDK Logger ([`CloudWatch`][Self]) | Stdout Logger ([`CloudWatchCout`][crate::service::aws::CloudWatchCout]) |
/// | :--------------- | :------------------------------- | :-------------------------------------------------------------------- |
/// | **Transport** | HTTPS (AWS SDK) | Standard Output (`stdout`) |
/// | **Binary Size** | Larger (SDK + TLS) | Minimal (No AWS dependencies) |
/// | **IAM Config** | Handled in-app | Handled by Execution Environment |
/// | **Best For** | On-premise, EC2, Legacy | Lambda, ECS, Fargate, Kubernetes |
///
/// ### Usage
/// You can quickly initialize the alternative via the factory:
/// ```rust
/// use timber_rust::LoggerFactory;
/// use timber_rust::Concurrency;
///
/// // Direct (Sync) for Lambda
/// let logger = LoggerFactory::cloudwatch().cout().build(Concurrency::Sync);
///
/// // Queued (Async) for ECS/Fargate
/// let logger = LoggerFactory::cloudwatch().cout().build(Concurrency::Async);
/// ```
///
/// See also: [`CloudWatchCoutMessageFormatter`][crate::service::CloudWatchCoutMessageFormatter]
/// for the JSON schema used by the alternative.
///
/// # Example
/// ```rust
/// use timber_rust::Logger;
/// use timber_rust::logger::CloudWatch;
/// use timber_rust::service::aws::Config;
///
/// let config = Config::new("access", "secret", "my-group", "us-east-1");
/// let logger = CloudWatch::new(config);
/// let logger = Logger::new(logger);
/// ```
/// Ensures a graceful shutdown of the logging pipeline.
///
/// When the [`CloudwatchLogger`][`CloudWatch`] goes out of scope, the following sequence occurs:
/// 1. **Channel Closure**: The `sender` is dropped (`None`). This signals the background
/// worker that no more messages will be sent.
/// 2. **Worker Drain**: The worker's `receiver.recv()` will return an error once
/// the channel is empty, allowing its loop to terminate naturally.
/// 3. **Thread Join**: The main thread blocks until the worker thread has finished
/// processing and sending the final batch of logs.
///
/// This mechanism prevents data loss during application shutdown or restarts.