From 1fd880d0e98f10d406d05a66f8ffb570294ef913 Mon Sep 17 00:00:00 2001 From: Alexey Orlenko Date: Wed, 20 Nov 2024 21:35:22 +0100 Subject: [PATCH] Introduce SerializableNonZeroU64 --- libs/telemetry/src/capturing/ng/collector.rs | 19 +++++++++++++++++-- libs/telemetry/src/capturing/ng/layer.rs | 6 +++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/libs/telemetry/src/capturing/ng/collector.rs b/libs/telemetry/src/capturing/ng/collector.rs index 853c95bfd1f..e4c7fdb34a7 100644 --- a/libs/telemetry/src/capturing/ng/collector.rs +++ b/libs/telemetry/src/capturing/ng/collector.rs @@ -6,12 +6,27 @@ use tracing::Level; use crate::models::{LogLevel, SpanKind, TraceSpan}; +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +struct SerializableNonZeroU64(NonZeroU64); + +impl Serialize for SerializableNonZeroU64 { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + // Serialize as string to preserve full u64 precision in JavaScript. Otherwise values + // larger than 2^53 - 1 will be parsed as floats on the client side, making it possible for + // IDs to collide. + self.0.to_string().serialize(serializer) + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)] -pub struct SpanId(NonZeroU64); +pub struct SpanId(SerializableNonZeroU64); impl From<&tracing::span::Id> for SpanId { fn from(id: &tracing::span::Id) -> Self { - Self(id.into_non_zero_u64()) + Self(SerializableNonZeroU64(id.into_non_zero_u64())) } } diff --git a/libs/telemetry/src/capturing/ng/layer.rs b/libs/telemetry/src/capturing/ng/layer.rs index 3d92873fd6e..a4013f2a840 100644 --- a/libs/telemetry/src/capturing/ng/layer.rs +++ b/libs/telemetry/src/capturing/ng/layer.rs @@ -285,15 +285,15 @@ mod tests { /// IDs (as libtest runs every test in its own thread). fn redact_id() -> Redaction { thread_local! { - static SPAN_ID_TO_SEQUENTIAL_ID: RefCell> = <_>::default(); + static SPAN_ID_TO_SEQUENTIAL_ID: RefCell> = <_>::default(); static NEXT_ID: RefCell = const { RefCell::new(1) }; } fn redact_recursive(value: Content) -> Content { match value { Content::NewtypeStruct("SpanId", ref nested) => match **nested { - Content::U64(original_id) => SPAN_ID_TO_SEQUENTIAL_ID.with_borrow_mut(|map| { - let id = map.entry(original_id).or_insert_with(|| { + Content::String(ref original_id) => SPAN_ID_TO_SEQUENTIAL_ID.with_borrow_mut(|map| { + let id = map.entry(original_id.clone()).or_insert_with(|| { NEXT_ID.with_borrow_mut(|next_id| { let id = *next_id; *next_id += 1;