opentelemetry_lambda_tower/extractor.rs
1//! Trait definition for trace context extraction from Lambda events.
2
3use lambda_runtime::Context as LambdaContext;
4use opentelemetry::Context;
5use opentelemetry::trace::Link;
6use tracing::Span;
7
8/// Extracts trace context from Lambda event payloads.
9///
10/// Different event sources carry trace context in different locations:
11/// - HTTP: `traceparent` header using W3C Trace Context
12/// - SQS: `AWSTraceHeader` in message system attributes
13/// - SNS: Similar to SQS
14///
15/// Implementations of this trait provide event-specific extraction logic
16/// and semantic attributes following OpenTelemetry conventions.
17///
18/// # Type Parameters
19///
20/// * `T` - The Lambda event payload type (e.g., `ApiGatewayV2httpRequest`, `SqsEvent`)
21///
22/// # Example
23///
24/// ```ignore
25/// use opentelemetry_lambda_tower::TraceContextExtractor;
26///
27/// struct MyExtractor;
28///
29/// impl TraceContextExtractor<MyEvent> for MyExtractor {
30/// fn extract_context(&self, _payload: &MyEvent) -> opentelemetry::Context {
31/// opentelemetry::Context::current()
32/// }
33///
34/// fn trigger_type(&self) -> &'static str {
35/// "other"
36/// }
37///
38/// fn span_name(&self, _payload: &MyEvent, ctx: &LambdaContext) -> String {
39/// ctx.env_config.function_name.clone()
40/// }
41///
42/// fn record_attributes(&self, _payload: &MyEvent, _span: &tracing::Span) {}
43/// }
44/// ```
45pub trait TraceContextExtractor<T>: Clone + Send + Sync + 'static {
46 /// Extracts parent context for creating child spans.
47 ///
48 /// For HTTP events, this extracts the W3C `traceparent` header.
49 /// For message-based events, this typically returns the current context
50 /// since span links are used instead of parent-child relationships.
51 ///
52 /// Returns `Context::current()` if no valid parent context is found.
53 fn extract_context(&self, payload: &T) -> Context;
54
55 /// Extracts span links for async message correlation.
56 ///
57 /// Used for SQS/SNS where messages may come from different traces.
58 /// Each message's trace context becomes a link rather than a parent,
59 /// preserving the async boundary semantics.
60 ///
61 /// Default implementation returns an empty vector (no links).
62 fn extract_links(&self, _payload: &T) -> Vec<Link> {
63 vec![]
64 }
65
66 /// Returns the FaaS trigger type for semantic conventions.
67 ///
68 /// Valid values per OpenTelemetry spec:
69 /// - `"http"` - HTTP/API Gateway triggers
70 /// - `"pubsub"` - Message queue triggers (SQS, SNS)
71 /// - `"datasource"` - Database triggers (DynamoDB Streams)
72 /// - `"timer"` - Scheduled triggers (EventBridge, CloudWatch Events)
73 /// - `"other"` - Other trigger types
74 fn trigger_type(&self) -> &'static str;
75
76 /// Generates span name based on event and Lambda context.
77 ///
78 /// For HTTP events, this should return `"{method} {route}"` format.
79 /// For SQS events, this should return `"{queue_name} process"` format.
80 /// Falls back to the function name from Lambda context.
81 fn span_name(&self, payload: &T, lambda_ctx: &LambdaContext) -> String;
82
83 /// Records event-specific attributes on the span.
84 ///
85 /// This method is called after span creation to add semantic
86 /// attributes specific to the event type. Implementations should
87 /// use `span.record()` to add attributes.
88 ///
89 /// Common attributes by trigger type:
90 ///
91 /// **HTTP:**
92 /// - `http.request.method`
93 /// - `url.path`
94 /// - `http.route`
95 ///
96 /// **SQS/SNS:**
97 /// - `messaging.system`
98 /// - `messaging.operation.type`
99 /// - `messaging.destination.name`
100 fn record_attributes(&self, payload: &T, span: &Span);
101}