lambda_otel_lite/
mode.rs

1use crate::logger::Logger;
2
3/// Module-specific logger
4static LOGGER: Logger = Logger::const_new("mode");
5
6use std::env;
7
8/// Controls how spans are processed and exported.
9///
10/// This enum determines when and how OpenTelemetry spans are flushed from the buffer
11/// to the configured exporter. Each mode offers different tradeoffs between latency,
12/// reliability, and flexibility.
13///
14/// # Modes
15///
16/// - `Sync`: Immediate flush in handler thread
17///   - Spans are flushed before handler returns
18///   - Direct export without extension coordination
19///   - May be more efficient for small payloads and low memory configurations
20///   - Guarantees span delivery before response
21///
22/// - `Async`: Flush via Lambda extension
23///   - Spans are flushed after handler returns
24///   - Requires coordination with extension process
25///   - Additional overhead from IPC with extension
26///   - Provides retry capabilities through extension
27///
28/// - `Finalize`: Delegated to processor
29///   - Spans handled by configured processor
30///   - Compatible with BatchSpanProcessor
31///   - Best for custom export strategies
32///   - Full control over export timing
33///
34/// # Configuration
35///
36/// The mode can be configured using the `LAMBDA_EXTENSION_SPAN_PROCESSOR_MODE` environment variable:
37/// - "sync" for Sync mode (default)
38/// - "async" for Async mode
39/// - "finalize" for Finalize mode
40///
41/// # Example
42///
43/// ```no_run
44/// use lambda_otel_lite::ProcessorMode;
45/// use std::env;
46///
47/// // Set mode via environment variable
48/// env::set_var("LAMBDA_EXTENSION_SPAN_PROCESSOR_MODE", "async");
49///
50/// // Get mode from environment
51/// let mode = ProcessorMode::from_env();
52/// assert!(matches!(mode, ProcessorMode::Async));
53/// ```
54#[derive(Debug, Clone, PartialEq)]
55pub enum ProcessorMode {
56    /// Synchronous flush in handler thread. Best for development and debugging.
57    Sync,
58    /// Asynchronous flush via extension. Best for production use to minimize latency.
59    Async,
60    /// Let processor handle flushing. Best with BatchSpanProcessor for custom export strategies.
61    Finalize,
62}
63
64impl ProcessorMode {
65    /// Create ProcessorMode from environment variable.
66    ///
67    /// Uses LAMBDA_EXTENSION_SPAN_PROCESSOR_MODE environment variable.
68    /// Defaults to Sync mode if not set or invalid.
69    pub fn from_env() -> Self {
70        match env::var("LAMBDA_EXTENSION_SPAN_PROCESSOR_MODE")
71            .map(|s| s.to_lowercase())
72            .as_deref()
73        {
74            Ok("sync") => {
75                LOGGER.debug("ProcessorMode.from_env: using sync processor mode");
76                ProcessorMode::Sync
77            }
78            Ok("async") => {
79                LOGGER.debug("ProcessorMode.from_env: using async processor mode");
80                ProcessorMode::Async
81            }
82            Ok("finalize") => {
83                LOGGER.debug("ProcessorMode.from_env: using finalize processor mode");
84                ProcessorMode::Finalize
85            }
86            Ok(value) => {
87                LOGGER.warn(format!(
88                    "ProcessorMode.from_env: invalid processor mode: {}, defaulting to sync",
89                    value
90                ));
91                ProcessorMode::Sync
92            }
93            Err(_) => {
94                LOGGER.debug("ProcessorMode.from_env: no processor mode set, defaulting to sync");
95                ProcessorMode::Sync
96            }
97        }
98    }
99}
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104    use serial_test::serial;
105    use std::env;
106
107    /// Test-specific logger
108
109    #[test]
110    #[serial]
111    fn test_processor_mode_from_env() {
112        // Default to sync mode
113        env::remove_var("LAMBDA_EXTENSION_SPAN_PROCESSOR_MODE");
114        assert!(matches!(ProcessorMode::from_env(), ProcessorMode::Sync));
115
116        // Explicit sync mode
117        env::set_var("LAMBDA_EXTENSION_SPAN_PROCESSOR_MODE", "sync");
118        assert!(matches!(ProcessorMode::from_env(), ProcessorMode::Sync));
119
120        // Async mode
121        env::set_var("LAMBDA_EXTENSION_SPAN_PROCESSOR_MODE", "async");
122        assert!(matches!(ProcessorMode::from_env(), ProcessorMode::Async));
123
124        // Finalize mode
125        env::set_var("LAMBDA_EXTENSION_SPAN_PROCESSOR_MODE", "finalize");
126        assert!(matches!(ProcessorMode::from_env(), ProcessorMode::Finalize));
127
128        // Invalid mode defaults to sync
129        env::set_var("LAMBDA_EXTENSION_SPAN_PROCESSOR_MODE", "invalid");
130        assert!(matches!(ProcessorMode::from_env(), ProcessorMode::Sync));
131    }
132}