diff --git a/.changesets/feat_feat-enhance-error-logging-trace-id.md b/.changesets/feat_feat-enhance-error-logging-trace-id.md new file mode 100644 index 0000000000..27a1311d13 --- /dev/null +++ b/.changesets/feat_feat-enhance-error-logging-trace-id.md @@ -0,0 +1,5 @@ +### Improve error logging for malformed Trace IDs ([PR #8149](https://github.com/apollographql/router/pull/8149)) + +When the router receives an unparseable Trace ID in incoming requests, the logged error message now includes the invalid value. Trace IDs can be unparseable due to invalid hexadecimal characters, incorrect length, or non-standard formats. + +By [@juancarlosjr97](https://github.com/juancarlosjr97) in https://github.com/apollographql/router/pull/8149 diff --git a/apollo-router/src/plugins/telemetry/mod.rs b/apollo-router/src/plugins/telemetry/mod.rs index 46e7fa77bd..664c926eaa 100644 --- a/apollo-router/src/plugins/telemetry/mod.rs +++ b/apollo-router/src/plugins/telemetry/mod.rs @@ -2055,7 +2055,7 @@ impl CustomTraceIdPropagator { let trace_id = match opentelemetry::trace::TraceId::from_hex(&trace_id) { Ok(trace_id) => trace_id, Err(err) => { - ::tracing::error!("cannot generate custom trace_id: {err}"); + ::tracing::error!(trace_id = %trace_id, error = %err, "cannot generate custom trace_id"); return None; } }; @@ -3287,6 +3287,29 @@ mod tests { assert_eq!(span.unwrap().trace_id().to_string(), expected_trace_id); } + #[test] + fn test_custom_trace_id_propagator_invalid_hex_characters() { + use crate::test_harness::tracing_test; + let _guard = tracing_test::dispatcher_guard(); + + let header = String::from("x-trace-id"); + let invalid_trace_id = String::from("invalidhexchars"); + + let propagator = CustomTraceIdPropagator::new(header.clone(), TraceIdFormat::Uuid); + let mut headers: HashMap = HashMap::new(); + headers.insert(header, invalid_trace_id.clone()); + + let span = propagator.extract_span_context(&headers); + + assert!(span.is_none()); + + assert!(tracing_test::logs_contain( + "cannot generate custom trace_id" + )); + + assert!(tracing_test::logs_contain(&invalid_trace_id)); + } + #[test] fn test_header_propagation_format() { struct Injected(HashMap); diff --git a/docs/source/routing/observability/telemetry/index.mdx b/docs/source/routing/observability/telemetry/index.mdx index c73f30079a..eb87916cab 100644 --- a/docs/source/routing/observability/telemetry/index.mdx +++ b/docs/source/routing/observability/telemetry/index.mdx @@ -45,6 +45,10 @@ The router emits telemetry in the industry-standard OpenTelemetry Protocol (OTLP - Jaeger - Zipkin +The router follows the [W3C Trace Context specification](https://www.w3.org/TR/trace-context/) for `trace_id` generation and propagation. OpenTelemetry uses 128-bit (32-character hexadecimal) trace IDs as defined in the W3C standard. When working with systems that do not follow this standard, the router provides format conversion options to ensure compatibility. + +When the router receives an incompatible or malformed `trace_id` in incoming requests (such as invalid hexadecimal characters, incorrect length, or non-standard formats), it logs an error message containing the invalid trace ID. + ### Attributes and selectors Attributes and selectors are key-value pairs that add contextual information from the router request lifecycle to telemetry data. You can use attributes and selectors to annotate events, metrics, and spans so they can help you filter and group data in your APMs.