diff --git a/Cargo.lock b/Cargo.lock index 80b95ce8db..7c69112752 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3029,6 +3029,7 @@ dependencies = [ "tokio-util", "tracing", "uuid", + "web-time", ] [[package]] @@ -3464,6 +3465,7 @@ dependencies = [ "tokio", "tokio-util", "tracing", + "web-time", ] [[package]] diff --git a/libdd-data-pipeline/Cargo.toml b/libdd-data-pipeline/Cargo.toml index 46bc35a720..b25381a3d5 100644 --- a/libdd-data-pipeline/Cargo.toml +++ b/libdd-data-pipeline/Cargo.toml @@ -46,6 +46,7 @@ libdd-tinybytes = { version = "1.1.1", path = "../libdd-tinybytes", features = [ "bytes_string", "serialization", ] } +web-time = "1" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] tokio = { version = "1.23", features = ["time", "test-util"], default-features = false } diff --git a/libdd-data-pipeline/src/otlp/metrics.rs b/libdd-data-pipeline/src/otlp/metrics.rs index 46104b12f1..2a81293579 100644 --- a/libdd-data-pipeline/src/otlp/metrics.rs +++ b/libdd-data-pipeline/src/otlp/metrics.rs @@ -16,8 +16,9 @@ use libdd_trace_utils::otlp_encoder::mapper::status_code; use libdd_trace_utils::otlp_encoder::OtlpResourceInfo; use serde_json::{json, Value}; use std::sync::{Arc, Mutex}; -use std::time::{Duration, SystemTime}; +use std::time::Duration; use tracing::error; +use web_time::SystemTime; const METRIC_NAME: &str = "traces.span.sdk.metrics.duration"; const NANOS_PER_SECOND: f64 = 1_000_000_000.0; diff --git a/libdd-data-pipeline/src/trace_exporter/builder.rs b/libdd-data-pipeline/src/trace_exporter/builder.rs index 5b0ae5a29c..78493e9edd 100644 --- a/libdd-data-pipeline/src/trace_exporter/builder.rs +++ b/libdd-data-pipeline/src/trace_exporter/builder.rs @@ -611,9 +611,7 @@ impl TraceExporterBuilder { // The handle is stored in TraceExporterWorkers on both native and wasm so // that shutdown_async can stop the worker symmetrically on both targets. - #[allow(unused_mut)] let mut stats = StatsComputationStatus::Disabled; - #[cfg(not(target_arch = "wasm32"))] if let Some(bucket_size) = self.stats_bucket_size { stats = StatsComputationStatus::DisabledByAgent { bucket_size }; } @@ -717,9 +715,7 @@ impl TraceExporterBuilder { // OTLP metrics + stats bucket size: start the concentrator unconditionally (bypass the // agent gate) so `check_agent_info` cannot later disable stats. - #[allow(unused_mut)] let mut otlp_stats_enabled = false; - #[cfg(not(target_arch = "wasm32"))] if let (Some(metrics_config), Some(bucket_size)) = (otlp_metrics_config.clone(), self.stats_bucket_size) { @@ -732,7 +728,7 @@ impl TraceExporterBuilder { .collect(); let concentrator = Arc::new(Mutex::new(SpanConcentrator::new( bucket_size, - std::time::SystemTime::now(), + web_time::SystemTime::now(), span_kinds, self.peer_tags.clone(), None, diff --git a/libdd-data-pipeline/src/trace_exporter/mod.rs b/libdd-data-pipeline/src/trace_exporter/mod.rs index 01fc311980..6291c47d3f 100644 --- a/libdd-data-pipeline/src/trace_exporter/mod.rs +++ b/libdd-data-pipeline/src/trace_exporter/mod.rs @@ -257,7 +257,6 @@ pub struct TraceExporter< common_stats_tags: Vec, client_computed_top_level: bool, client_side_stats: StatsComputationConfig, - #[cfg_attr(target_arch = "wasm32", allow(dead_code))] previous_info_state: ArcSwapOption, info_response_observer: ResponseObserver, #[cfg(feature = "telemetry")] @@ -275,7 +274,6 @@ pub struct TraceExporter< /// When true, span stats are computed and exported as OTLP metrics. The concentrator is /// started at build time, so agent-driven stats (de)activation in `check_agent_info` is /// skipped. - #[cfg_attr(target_arch = "wasm32", allow(dead_code))] otlp_stats_enabled: bool, /// When `Some(max_line_size)`, traces are written as newline-delimited JSON /// through the [`LogWriterCapability`] (the Datadog Forwarder "log exporter" @@ -433,7 +431,6 @@ impl< Ok(res) } - #[cfg(not(target_arch = "wasm32"))] /// Check if agent info state has changed fn has_agent_info_state_changed(&self, agent_info: &Arc) -> bool { Some(agent_info.state_hash.as_str()) @@ -446,7 +443,6 @@ impl< /// Reconcile in-process stats state with the latest agent info. /// Async so the `Enabled` arm can await a stats-worker shutdown without `block_on`. - #[cfg(not(target_arch = "wasm32"))] async fn check_agent_info(&self) { let Some(agent_info) = agent_info::get_agent_info() else { return; @@ -504,18 +500,11 @@ impl< .store(Some(agent_info.state_hash.clone().into())) } - #[cfg(target_arch = "wasm32")] - async fn check_agent_info(&self) { - // No background workers on wasm — agent info is never fetched, stats are - // never computed. This is intentionally a no-op. - } - /// Reconcile `v1_active` with the agent's currently-advertised endpoints. Called only when /// V1 is configured and the agent info state has changed, so transitions are logged at most /// once per change. Note: `v1_active` can also transition `true → false` outside this path, /// via the fail-closed hook in `send_trace_chunks_inner` when the agent returns 404 on /// `/v1.0/traces` (the agent does not bump its state hash on 404). - #[cfg(not(target_arch = "wasm32"))] fn refresh_v1_active(&self, agent_info: &Arc) { let supports_v1 = agent_info .info diff --git a/libdd-data-pipeline/src/trace_exporter/stats.rs b/libdd-data-pipeline/src/trace_exporter/stats.rs index a242605343..4384b3a5d6 100644 --- a/libdd-data-pipeline/src/trace_exporter/stats.rs +++ b/libdd-data-pipeline/src/trace_exporter/stats.rs @@ -7,14 +7,11 @@ //! including starting/stopping stats workers, managing the span concentrator, //! and processing traces for stats collection. -#[cfg(not(target_arch = "wasm32"))] use super::add_path; use super::TracerMetadata; -#[cfg(not(target_arch = "wasm32"))] use crate::agent_info::schema::AgentInfo; use arc_swap::ArcSwap; use libdd_capabilities::{HttpClientCapability, MaybeSend, SleepCapability}; -#[cfg(not(target_arch = "wasm32"))] use libdd_common::Endpoint; use libdd_common::MutexExt; use libdd_shared_runtime::{SharedRuntime, WorkerHandle}; @@ -23,18 +20,16 @@ use libdd_trace_stats::span_concentrator::SpanConcentrator; use libdd_trace_stats::span_concentrator::{ SharedStatsComputationObfuscationConfig, StatsComputationObfuscationConfig, }; -#[cfg(not(target_arch = "wasm32"))] use libdd_trace_stats::stats_exporter::{StatsExporter, StatsMetadata}; use libdd_trace_utils::trace_filter::TraceFilterer; use std::sync::{Arc, Mutex}; use std::time::Duration; -#[cfg(not(target_arch = "wasm32"))] use tracing::{debug, error}; +// std::time::SystemTime::now() panics on wasm32. +use web_time::SystemTime; -#[cfg(not(target_arch = "wasm32"))] pub(crate) const DEFAULT_STATS_ELIGIBLE_SPAN_KINDS: [&str; 4] = ["client", "server", "producer", "consumer"]; -#[cfg(not(target_arch = "wasm32"))] pub(crate) const STATS_ENDPOINT: &str = "/v0.6/stats"; /// The maximum obfuscation version this tracer supports. @@ -43,7 +38,6 @@ pub(crate) const SUPPORTED_OBFUSCATION_VERSION: u32 = 1; #[cfg(feature = "stats-obfuscation")] pub(crate) const SUPPORTED_OBFUSCATION_VERSION_STR: &str = "1"; -#[cfg(not(target_arch = "wasm32"))] /// Context struct that groups immutable parameters used by stats functions pub(crate) struct StatsContext<'a, R: SharedRuntime> { pub metadata: &'a TracerMetadata, @@ -52,7 +46,6 @@ pub(crate) struct StatsContext<'a, R: SharedRuntime> { } #[derive(Debug)] -#[cfg_attr(target_arch = "wasm32", allow(dead_code))] pub(crate) enum StatsComputationStatus { /// Client-side stats has been disabled by the tracer Disabled, @@ -68,7 +61,6 @@ pub(crate) enum StatsComputationStatus { } #[derive(Debug)] -#[cfg_attr(target_arch = "wasm32", allow(dead_code))] pub(crate) struct StatsComputationConfig { pub(crate) status: ArcSwap, #[cfg(feature = "stats-obfuscation")] @@ -84,7 +76,6 @@ pub(crate) struct StatsComputationConfig { /// This requires: /// - `client_drop_p0s` to be enabled on the agent, /// - the `/v0.6/stats` endpoint to be advertised by the agent. -#[cfg(not(target_arch = "wasm32"))] fn is_stats_computation_supported(agent_info: &AgentInfo) -> bool { agent_info.info.client_drop_p0s.is_some_and(|v| v) && agent_info @@ -103,7 +94,6 @@ fn is_obfuscation_active(agent_info: &AgentInfo) -> bool { .is_some_and(|v| v >= 1 && v <= SUPPORTED_OBFUSCATION_VERSION) } -#[cfg(not(target_arch = "wasm32"))] /// Get span kinds for stats computation with default fallback fn get_span_kinds_for_stats(agent_info: &Arc) -> Vec { agent_info @@ -113,7 +103,6 @@ fn get_span_kinds_for_stats(agent_info: &Arc) -> Vec { .unwrap_or_else(|| DEFAULT_STATS_ELIGIBLE_SPAN_KINDS.map(String::from).to_vec()) } -#[cfg(not(target_arch = "wasm32"))] /// Start the stats exporter and enable stats computation /// /// Should only be used if the agent enabled stats computation @@ -132,7 +121,7 @@ pub(crate) fn start_stats_computation< { let stats_concentrator = Arc::new(Mutex::new(SpanConcentrator::new( bucket_size, - std::time::SystemTime::now(), + SystemTime::now(), span_kinds, peer_tags, None, @@ -144,7 +133,6 @@ pub(crate) fn start_stats_computation< Ok(()) } -#[cfg(not(target_arch = "wasm32"))] /// Create stats exporter and worker, start the worker, and update the state fn create_and_start_stats_worker< C: HttpClientCapability + SleepCapability + MaybeSend + Sync + 'static, @@ -186,7 +174,6 @@ fn create_and_start_stats_worker< Ok(()) } -#[cfg(not(target_arch = "wasm32"))] /// Transition from `Enabled` to `DisabledByAgent`, awaiting the stats worker shutdown. pub(crate) async fn stop_stats_computation(client_side_stats: &ArcSwap) { // load_full() avoids holding an ArcSwap Guard (!Send) across .await. @@ -207,7 +194,6 @@ pub(crate) async fn stop_stats_computation(client_side_stats: &ArcSwap, client_side_stats: &StatsComputationConfig, @@ -270,7 +255,6 @@ fn update_obfuscation_config( } } -#[cfg(not(target_arch = "wasm32"))] pub(crate) async fn handle_stats_enabled( agent_info: &Arc, stats_concentrator: &Arc>, diff --git a/libdd-trace-stats/Cargo.toml b/libdd-trace-stats/Cargo.toml index 09f913e6e8..83531c2501 100644 --- a/libdd-trace-stats/Cargo.toml +++ b/libdd-trace-stats/Cargo.toml @@ -29,6 +29,8 @@ tokio = { version = "1.23", features = ["macros", "time"], default-features = fa tokio-util = "0.7.11" tracing = { version = "0.1", default-features = false } async-trait = "0.1.85" +# Cross-platform `SystemTime`; `std::time::SystemTime::now()` panics on wasm32. +web-time = "1" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] libdd-capabilities-impl = { version = "2.0.0", path = "../libdd-capabilities-impl", default-features = false } diff --git a/libdd-trace-stats/src/lib.rs b/libdd-trace-stats/src/lib.rs index 8e5793c8bb..855e8ce088 100644 --- a/libdd-trace-stats/src/lib.rs +++ b/libdd-trace-stats/src/lib.rs @@ -10,5 +10,4 @@ //! This crate provides utilities to compute stats from traces. pub mod span_concentrator; -#[cfg(not(target_arch = "wasm32"))] pub mod stats_exporter; diff --git a/libdd-trace-stats/src/span_concentrator/mod.rs b/libdd-trace-stats/src/span_concentrator/mod.rs index f1beb5eab9..37036e5d5a 100644 --- a/libdd-trace-stats/src/span_concentrator/mod.rs +++ b/libdd-trace-stats/src/span_concentrator/mod.rs @@ -2,8 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 //! This module implements the SpanConcentrator used to aggregate spans into stats use std::collections::HashMap; -use std::time::{self, Duration, SystemTime}; +use std::time::Duration; use tracing::debug; +// std::time::SystemTime panics on wasm32. +use web_time::{SystemTime, UNIX_EPOCH}; use libdd_trace_protobuf::pb; @@ -35,7 +37,7 @@ impl FlushableConcentrator for SpanConcentrator { /// Return a Duration between t and the unix epoch /// If t is before the unix epoch return 0 fn system_time_to_unix_duration(t: SystemTime) -> Duration { - t.duration_since(time::UNIX_EPOCH) + t.duration_since(UNIX_EPOCH) .unwrap_or(Duration::from_nanos(0)) }