diff --git a/bottlecap/src/lifecycle/invocation/context.rs b/bottlecap/src/lifecycle/invocation/context.rs index 325fd3cd3..d90a798b9 100644 --- a/bottlecap/src/lifecycle/invocation/context.rs +++ b/bottlecap/src/lifecycle/invocation/context.rs @@ -314,7 +314,7 @@ mod tests { total_user_time_ms: 100.0, total_system_time_ms: 53.0, total_idle_time_ms: 20.0, - individual_cpu_idle_times: individual_cpu_idle_times, + individual_cpu_idle_times, }); let uptime_offset = Some(50.0); diff --git a/bottlecap/src/lifecycle/invocation/triggers/mod.rs b/bottlecap/src/lifecycle/invocation/triggers/mod.rs index a989ce009..f65a9155a 100644 --- a/bottlecap/src/lifecycle/invocation/triggers/mod.rs +++ b/bottlecap/src/lifecycle/invocation/triggers/mod.rs @@ -52,7 +52,8 @@ where pub mod test_utils { use std::fs; + #[must_use] pub fn read_json_file(file_name: &str) -> String { - fs::read_to_string(format!("tests/payloads/{}", file_name)).expect("Failed to read file") + fs::read_to_string(format!("tests/payloads/{file_name}")).expect("Failed to read file") } } diff --git a/bottlecap/src/metrics/enhanced/lambda.rs b/bottlecap/src/metrics/enhanced/lambda.rs index 13dd203a9..b11427e96 100644 --- a/bottlecap/src/metrics/enhanced/lambda.rs +++ b/bottlecap/src/metrics/enhanced/lambda.rs @@ -663,7 +663,7 @@ mod tests { total_idle_time_ms: 10.0, individual_cpu_idle_times: individual_cpu_idle_time_offsets, }; - let uptime_offset = 1891100.0; + let uptime_offset = 1_891_100.0; let mut individual_cpu_idle_times_end = HashMap::new(); individual_cpu_idle_times_end.insert("cpu0".to_string(), 570.0); @@ -674,7 +674,7 @@ mod tests { total_idle_time_ms: 1130.0, individual_cpu_idle_times: individual_cpu_idle_times_end, }; - let uptime_data = 1891900.0; + let uptime_data = 1_891_900.0; Lambda::generate_cpu_utilization_enhanced_metrics( &cpu_offset, diff --git a/bottlecap/src/proc/mod.rs b/bottlecap/src/proc/mod.rs index 1a74a2b9d..23d6680ec 100644 --- a/bottlecap/src/proc/mod.rs +++ b/bottlecap/src/proc/mod.rs @@ -189,26 +189,26 @@ mod tests { #[allow(clippy::float_cmp)] fn test_get_network_data() { let path = "./tests/proc/net/valid_dev"; - let network_data_result = get_network_data_from_path(&path); - assert!(!network_data_result.is_err()); + let network_data_result = get_network_data_from_path(path); + assert!(network_data_result.is_ok()); let network_data_result = network_data_result.unwrap(); assert_eq!(network_data_result.rx_bytes, 180.0); assert_eq!(network_data_result.tx_bytes, 254.0); let path = "./tests/proc/net/invalid_dev_malformed"; - let network_data_result = get_network_data_from_path(&path); + let network_data_result = get_network_data_from_path(path); assert!(network_data_result.is_err()); let path = "./tests/proc/net/invalid_dev_non_numerical_value"; - let network_data_result = get_network_data_from_path(&path); + let network_data_result = get_network_data_from_path(path); assert!(network_data_result.is_err()); let path = "./tests/proc/net/missing_interface_dev"; - let network_data_result = get_network_data_from_path(&path); + let network_data_result = get_network_data_from_path(path); assert!(network_data_result.is_err()); let path = "./tests/proc/net/nonexistent_dev"; - let network_data_result = get_network_data_from_path(&path); + let network_data_result = get_network_data_from_path(path); assert!(network_data_result.is_err()); } @@ -216,12 +216,12 @@ mod tests { #[allow(clippy::float_cmp)] fn test_get_cpu_data() { let path = "./tests/proc/stat/valid_stat"; - let cpu_data_result = get_cpu_data_from_path(&path); - assert!(!cpu_data_result.is_err()); + let cpu_data_result = get_cpu_data_from_path(path); + assert!(cpu_data_result.is_ok()); let cpu_data = cpu_data_result.unwrap(); assert_eq!(cpu_data.total_user_time_ms, 23370.0); assert_eq!(cpu_data.total_system_time_ms, 1880.0); - assert_eq!(cpu_data.total_idle_time_ms, 178380.0); + assert_eq!(cpu_data.total_idle_time_ms, 178_380.0); assert_eq!(cpu_data.individual_cpu_idle_times.len(), 2); assert_eq!( *cpu_data @@ -239,27 +239,27 @@ mod tests { ); let path = "./tests/proc/stat/invalid_stat_non_numerical_value_1"; - let cpu_data_result = get_cpu_data_from_path(&path); + let cpu_data_result = get_cpu_data_from_path(path); assert!(cpu_data_result.is_err()); let path = "./tests/proc/stat/invalid_stat_non_numerical_value_2"; - let cpu_data_result = get_cpu_data_from_path(&path); + let cpu_data_result = get_cpu_data_from_path(path); assert!(cpu_data_result.is_err()); let path = "./tests/proc/stat/invalid_stat_malformed_first_line"; - let cpu_data_result = get_cpu_data_from_path(&path); + let cpu_data_result = get_cpu_data_from_path(path); assert!(cpu_data_result.is_err()); let path = "./tests/proc/stat/invalid_stat_malformed_per_cpu_line"; - let cpu_data_result = get_cpu_data_from_path(&path); + let cpu_data_result = get_cpu_data_from_path(path); assert!(cpu_data_result.is_err()); let path = "./tests/proc/stat/invalid_stat_missing_cpun_data"; - let cpu_data_result = get_cpu_data_from_path(&path); + let cpu_data_result = get_cpu_data_from_path(path); assert!(cpu_data_result.is_err()); let path = "./tests/proc/stat/nonexistent_stat"; - let cpu_data_result = get_cpu_data_from_path(&path); + let cpu_data_result = get_cpu_data_from_path(path); assert!(cpu_data_result.is_err()); } @@ -267,21 +267,21 @@ mod tests { #[allow(clippy::float_cmp)] fn test_get_uptime_data() { let path = "./tests/proc/uptime/valid_uptime"; - let uptime_data_result = get_uptime_from_path(&path); - assert!(!uptime_data_result.is_err()); + let uptime_data_result = get_uptime_from_path(path); + assert!(uptime_data_result.is_ok()); let uptime_data = uptime_data_result.unwrap(); - assert_eq!(uptime_data, 3213103123000.0); + assert_eq!(uptime_data, 3_213_103_123_000.0); let path = "./tests/proc/uptime/invalid_data_uptime"; - let uptime_data_result = get_uptime_from_path(&path); + let uptime_data_result = get_uptime_from_path(path); assert!(uptime_data_result.is_err()); let path = "./tests/proc/uptime/malformed_uptime"; - let uptime_data_result = get_uptime_from_path(&path); + let uptime_data_result = get_uptime_from_path(path); assert!(uptime_data_result.is_err()); let path = "./tests/proc/uptime/nonexistent_uptime"; - let uptime_data_result = get_uptime_from_path(&path); + let uptime_data_result = get_uptime_from_path(path); assert!(uptime_data_result.is_err()); } } diff --git a/bottlecap/src/traces/mod.rs b/bottlecap/src/traces/mod.rs index d8facd07c..9c87051cf 100644 --- a/bottlecap/src/traces/mod.rs +++ b/bottlecap/src/traces/mod.rs @@ -8,3 +8,24 @@ pub mod stats_processor; pub mod trace_agent; pub mod trace_flusher; pub mod trace_processor; + +// URL for a call to the Lambda runtime API. The value may be replaced if `AWS_LAMBDA_RUNTIME_API` is set. +const LAMBDA_RUNTIME_URL_PREFIX: &str = "http://127.0.0.1:9001"; + +// URL for a call from the Datadog Lambda Library to the Lambda Extension +const LAMBDA_EXTENSION_URL_PREFIX: &str = "http://127.0.0.1:8124"; + +// the first part of a URL for a call from Statsd +const LAMBDA_STATSD_URL_PREFIX: &str = "http://127.0.0.1:8125"; + +// the first part of a URL from the non-routable address for DNS traces +const DNS_NON_ROUTABLE_ADDRESS_URL_PREFIX: &str = "0.0.0.0"; + +// the first part of a URL from the localhost address for DNS traces +const DNS_LOCAL_HOST_ADDRESS_URL_PREFIX: &str = "127.0.0.1"; + +// URL from the `_AWS_XRAY_DAEMON_ADDRESS` for DNS traces +const AWS_XRAY_DAEMON_ADDRESS_URL_PREFIX: &str = "169.254.79.129"; + +// Name of the placeholder invocation span set by Java and Go tracers +const INVOCATION_SPAN_RESOURCE: &str = "dd-tracer-serverless-span"; diff --git a/bottlecap/src/traces/propagation/mod.rs b/bottlecap/src/traces/propagation/mod.rs index e25e9d35d..723666406 100644 --- a/bottlecap/src/traces/propagation/mod.rs +++ b/bottlecap/src/traces/propagation/mod.rs @@ -212,7 +212,7 @@ pub mod tests { use super::*; lazy_static! { - static ref TRACE_ID: u128 = 171395628812617415352188477958425669623; + static ref TRACE_ID: u128 = 171_395_628_812_617_415_352_188_477_958_425_669_623; static ref TRACE_ID_LOWER_ORDER_BITS: u64 = *TRACE_ID as u64; static ref TRACE_ID_HEX: String = String::from("80f198ee56343ba864fe8b2a57d3eff7"); @@ -365,7 +365,7 @@ pub mod tests { None, VALID_DATADOG_HEADERS.clone(), SpanContext { - trace_id: 13088165645273925489, + trace_id: 13_088_165_645_273_925_489, span_id: 5678, sampling: Some(Sampling { priority: Some(1), @@ -382,7 +382,7 @@ pub mod tests { None, VALID_DATADOG_HEADERS_NO_PRIORITY.clone(), SpanContext { - trace_id: 13088165645273925489, + trace_id: 13_088_165_645_273_925_489, span_id: 5678, sampling: Some(Sampling { priority: Some(2), @@ -404,7 +404,7 @@ pub mod tests { Some(vec![TracePropagationStyle::Datadog]), VALID_DATADOG_HEADERS.clone(), SpanContext { - trace_id: 13088165645273925489, + trace_id: 13_088_165_645_273_925_489, span_id: 5678, sampling: Some(Sampling { priority: Some(1), @@ -440,8 +440,8 @@ pub mod tests { Some(vec![TracePropagationStyle::TraceContext]), VALID_TRACECONTEXT_HEADERS_BASIC.clone(), SpanContext { - trace_id: 7277407061855694839, - span_id: 67667974448284343, + trace_id: 7_277_407_061_855_694_839, + span_id: 67_667_974_448_284_343, sampling: Some(Sampling { priority: Some(2), mechanism: None, @@ -460,8 +460,8 @@ pub mod tests { Some(vec![TracePropagationStyle::TraceContext]), VALID_TRACECONTEXT_HEADERS_RUM_NO_SAMPLING_DECISION.clone(), SpanContext { - trace_id: 7277407061855694839, - span_id: 67667974448284343, + trace_id: 7_277_407_061_855_694_839, + span_id: 67_667_974_448_284_343, sampling: Some(Sampling { priority: Some(0), mechanism: None, @@ -484,7 +484,7 @@ pub mod tests { None, ALL_VALID_HEADERS.clone(), SpanContext { - trace_id: 13088165645273925489, + trace_id: 13_088_165_645_273_925_489, span_id: 5678, sampling: Some(Sampling { priority: Some(1), @@ -496,9 +496,9 @@ pub mod tests { ]), links: vec![ SpanLink { - trace_id: 7277407061855694839, + trace_id: 7_277_407_061_855_694_839, trace_id_high: 0, - span_id: 67667974448284343, + span_id: 67_667_974_448_284_343, flags: 1, tracestate: "dd=s:2;o:rum;t.dm:-4;t.usr.id:baz64,congo=t61rcWkgMz".to_string(), attributes: HashMap::from([ @@ -513,7 +513,7 @@ pub mod tests { Some(vec![TracePropagationStyle::Datadog, TracePropagationStyle::TraceContext]), ALL_VALID_HEADERS.clone(), SpanContext { - trace_id: 13088165645273925489, + trace_id: 13_088_165_645_273_925_489, span_id: 5678, sampling: Some(Sampling { priority: Some(1), @@ -525,9 +525,9 @@ pub mod tests { ]), links: vec![ SpanLink { - trace_id: 7277407061855694839, + trace_id: 7_277_407_061_855_694_839, trace_id_high: 0, - span_id: 67667974448284343, + span_id: 67_667_974_448_284_343, flags: 1, tracestate: "dd=s:2;o:rum;t.dm:-4;t.usr.id:baz64,congo=t61rcWkgMz".to_string(), attributes: HashMap::from([ @@ -543,7 +543,7 @@ pub mod tests { Some(vec![TracePropagationStyle::Datadog]), ALL_VALID_HEADERS.clone(), SpanContext { - trace_id: 13088165645273925489, + trace_id: 13_088_165_645_273_925_489, span_id: 5678, sampling: Some(Sampling { priority: Some(1), @@ -568,7 +568,7 @@ pub mod tests { Some(vec![TracePropagationStyle::Datadog, TracePropagationStyle::None]), ALL_VALID_HEADERS.clone(), SpanContext { - trace_id: 13088165645273925489, + trace_id: 13_088_165_645_273_925_489, span_id: 5678, sampling: Some(Sampling { priority: Some(1), @@ -591,8 +591,8 @@ pub mod tests { Some(vec![TracePropagationStyle::Datadog, TracePropagationStyle::TraceContext]), DATADOG_TRACECONTEXT_MATCHING_TRACE_ID_HEADERS.clone(), SpanContext { - trace_id: 7277407061855694839, - span_id: 67667974448284343, + trace_id: 7_277_407_061_855_694_839, + span_id: 67_667_974_448_284_343, sampling: Some(Sampling { priority: Some(1), mechanism: None, @@ -612,7 +612,7 @@ pub mod tests { Some(vec![TracePropagationStyle::Datadog, TracePropagationStyle::TraceContext]), NO_TRACESTATE_SUPPORT_NOT_MATCHING_TRACE_ID.clone(), SpanContext { - trace_id: 13088165645273925489, + trace_id: 13_088_165_645_273_925_489, span_id: 5678, sampling: Some(Sampling { priority: Some(1), @@ -624,9 +624,9 @@ pub mod tests { ]), links: vec![ SpanLink { - trace_id: 7277407061855694839, + trace_id: 7_277_407_061_855_694_839, trace_id_high: 0, - span_id: 67667974448284343, + span_id: 67_667_974_448_284_343, flags: 0, tracestate: "dd=o:rum".to_string(), attributes: HashMap::from([ @@ -653,7 +653,7 @@ pub mod tests { ("traceparent".to_string(), "00-000000000000000080f198ee56343ba8-000000000000000a-01".to_string()), ]), SpanContext { - trace_id: 9291375655657946024, + trace_id: 9_291_375_655_657_946_024, span_id: 10, sampling: Some(Sampling { priority: Some(2), @@ -672,8 +672,8 @@ pub mod tests { Some(vec![TracePropagationStyle::TraceContext, TracePropagationStyle::Datadog]), ALL_HEADERS_CHAOTIC_2.clone(), SpanContext { - trace_id: 7277407061855694839, - span_id: 67667974448284343, + trace_id: 7_277_407_061_855_694_839, + span_id: 67_667_974_448_284_343, sampling: Some(Sampling { priority: Some(2), mechanism: None, @@ -688,11 +688,11 @@ pub mod tests { ]), links: vec![ SpanLink { - trace_id: 13088165645273925489, + trace_id: 13_088_165_645_273_925_489, trace_id_high: 0, span_id: 5678, flags: 1, - tracestate: "".to_string(), + tracestate: String::new(), attributes: HashMap::from([ ("reason".to_string(), "terminated_context".to_string()), ("context_headers".to_string(), "datadog".to_string()), @@ -705,8 +705,8 @@ pub mod tests { Some(vec![TracePropagationStyle::TraceContext, TracePropagationStyle::Datadog]), ALL_VALID_HEADERS.clone(), SpanContext { - trace_id: 7277407061855694839, - span_id: 67667974448284343, + trace_id: 7_277_407_061_855_694_839, + span_id: 67_667_974_448_284_343, sampling: Some(Sampling { priority: Some(2), mechanism: None, @@ -721,11 +721,11 @@ pub mod tests { ]), links: vec![ SpanLink { - trace_id: 13088165645273925489, + trace_id: 13_088_165_645_273_925_489, trace_id_high: 0, span_id: 5678, flags: 1, - tracestate: "".to_string(), + tracestate: String::new(), attributes: HashMap::from([ ("reason".to_string(), "terminated_context".to_string()), ("context_headers".to_string(), "datadog".to_string()), @@ -739,7 +739,7 @@ pub mod tests { Some(vec![TracePropagationStyle::Datadog, TracePropagationStyle::TraceContext]), ALL_VALID_HEADERS.clone(), SpanContext { - trace_id: 13088165645273925489, + trace_id: 13_088_165_645_273_925_489, span_id: 5678, sampling: Some(Sampling { priority: Some(1), @@ -751,11 +751,11 @@ pub mod tests { ]), links: vec![ SpanLink { - trace_id: 7277407061855694839, + trace_id: 7_277_407_061_855_694_839, // this should be `9291375655657946024` not `0`, but we don't have this data // with the current definition of `SpanContext` trace_id_high: 0, - span_id: 67667974448284343, + span_id: 67_667_974_448_284_343, flags: 1, tracestate: "dd=s:2;o:rum;t.dm:-4;t.usr.id:baz64,congo=t61rcWkgMz".to_string(), attributes: HashMap::from([ diff --git a/bottlecap/src/traces/propagation/text_map_propagator.rs b/bottlecap/src/traces/propagation/text_map_propagator.rs index 1a0803aac..34b482643 100644 --- a/bottlecap/src/traces/propagation/text_map_propagator.rs +++ b/bottlecap/src/traces/propagation/text_map_propagator.rs @@ -505,8 +505,8 @@ mod test { .extract(&headers) .expect("couldn't extract trace context"); - assert_eq!(context.trace_id, 7277407061855694839); - assert_eq!(context.span_id, 67667974448284343); + assert_eq!(context.trace_id, 7_277_407_061_855_694_839); + assert_eq!(context.span_id, 67_667_974_448_284_343); assert_eq!(context.sampling.unwrap().priority, Some(2)); assert_eq!(context.origin, Some("rum".to_string())); assert_eq!( diff --git a/bottlecap/src/traces/trace_processor.rs b/bottlecap/src/traces/trace_processor.rs index 90f41d8cd..5974c7d17 100644 --- a/bottlecap/src/traces/trace_processor.rs +++ b/bottlecap/src/traces/trace_processor.rs @@ -14,7 +14,13 @@ use std::sync::Arc; use tracing::debug; use crate::config; +use crate::traces::{ + AWS_XRAY_DAEMON_ADDRESS_URL_PREFIX, DNS_LOCAL_HOST_ADDRESS_URL_PREFIX, + DNS_NON_ROUTABLE_ADDRESS_URL_PREFIX, INVOCATION_SPAN_RESOURCE, LAMBDA_EXTENSION_URL_PREFIX, + LAMBDA_RUNTIME_URL_PREFIX, LAMBDA_STATSD_URL_PREFIX, +}; use datadog_trace_obfuscation::obfuscate::obfuscate_span; +use datadog_trace_protobuf::pb::Span; use datadog_trace_utils::trace_utils::SendData; use datadog_trace_utils::trace_utils::{self}; @@ -31,11 +37,10 @@ struct ChunkProcessor { } impl TraceChunkProcessor for ChunkProcessor { - fn process(&mut self, chunk: &mut datadog_trace_protobuf::pb::TraceChunk, _index: usize) { - chunk.spans.retain(|span| { - (span.resource != "127.0.0.1" || span.resource != "0.0.0.0") - && span.name != "dns.lookup" - }); + fn process(&mut self, chunk: &mut pb::TraceChunk, _index: usize) { + chunk + .spans + .retain(|span| !filter_span_from_lambda_library_or_runtime(span)); for span in &mut chunk.spans { self.tags_provider.get_tags_map().iter().for_each(|(k, v)| { span.meta.insert(k.clone(), v.clone()); @@ -49,6 +54,53 @@ impl TraceChunkProcessor for ChunkProcessor { } } +fn filter_span_from_lambda_library_or_runtime(span: &Span) -> bool { + if let Some(url) = span.meta.get("http.url") { + if url.starts_with(LAMBDA_RUNTIME_URL_PREFIX) + || url.starts_with(LAMBDA_EXTENSION_URL_PREFIX) + || url.starts_with(LAMBDA_STATSD_URL_PREFIX) + { + return true; + } + } + + if let (Some(tcp_host), Some(tcp_port)) = ( + span.meta.get("tcp.remote.host"), + span.meta.get("tcp.remote.port"), + ) { + { + let tcp_lambda_url_prefix = format!("http://{tcp_host}:{tcp_port}"); + if tcp_lambda_url_prefix.starts_with(LAMBDA_RUNTIME_URL_PREFIX) + || tcp_lambda_url_prefix.starts_with(LAMBDA_EXTENSION_URL_PREFIX) + || tcp_lambda_url_prefix.starts_with(LAMBDA_STATSD_URL_PREFIX) + { + return true; + } + } + } + + if let Some(dns_address) = span.meta.get("dns.address") { + if dns_address.starts_with(DNS_NON_ROUTABLE_ADDRESS_URL_PREFIX) + || dns_address.starts_with(DNS_LOCAL_HOST_ADDRESS_URL_PREFIX) + || dns_address.starts_with(AWS_XRAY_DAEMON_ADDRESS_URL_PREFIX) + { + return true; + } + } + if span.resource == INVOCATION_SPAN_RESOURCE { + return true; + } + + if span.name == "dns.lookup" + || span.resource == DNS_LOCAL_HOST_ADDRESS_URL_PREFIX + || span.resource == DNS_NON_ROUTABLE_ADDRESS_URL_PREFIX + { + return true; + } + + false +} + #[allow(clippy::module_name_repetitions)] pub trait TraceProcessor { fn process_traces(