Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions libdd-data-pipeline/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
3 changes: 2 additions & 1 deletion libdd-data-pipeline/src/otlp/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 1 addition & 5 deletions libdd-data-pipeline/src/trace_exporter/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -611,9 +611,7 @@ impl<R: SharedRuntime> TraceExporterBuilder<R> {
// 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 };
}
Expand Down Expand Up @@ -717,9 +715,7 @@ impl<R: SharedRuntime> TraceExporterBuilder<R> {

// 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)
{
Expand All @@ -732,7 +728,7 @@ impl<R: SharedRuntime> TraceExporterBuilder<R> {
.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,
Expand Down
11 changes: 0 additions & 11 deletions libdd-data-pipeline/src/trace_exporter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,6 @@ pub struct TraceExporter<
common_stats_tags: Vec<Tag>,
client_computed_top_level: bool,
client_side_stats: StatsComputationConfig,
#[cfg_attr(target_arch = "wasm32", allow(dead_code))]
previous_info_state: ArcSwapOption<String>,
info_response_observer: ResponseObserver,
#[cfg(feature = "telemetry")]
Expand All @@ -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"
Expand Down Expand Up @@ -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<AgentInfo>) -> bool {
Some(agent_info.state_hash.as_str())
Expand All @@ -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;
Expand Down Expand Up @@ -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<AgentInfo>) {
let supports_v1 = agent_info
.info
Expand Down
22 changes: 3 additions & 19 deletions libdd-data-pipeline/src/trace_exporter/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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.
Expand All @@ -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,
Expand All @@ -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,
Expand All @@ -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<StatsComputationStatus>,
#[cfg(feature = "stats-obfuscation")]
Expand All @@ -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
Expand All @@ -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<AgentInfo>) -> Vec<String> {
agent_info
Expand All @@ -113,7 +103,6 @@ fn get_span_kinds_for_stats(agent_info: &Arc<AgentInfo>) -> Vec<String> {
.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
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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<StatsComputationStatus>) {
// load_full() avoids holding an ArcSwap Guard (!Send) across .await.
Expand All @@ -207,7 +194,6 @@ pub(crate) async fn stop_stats_computation(client_side_stats: &ArcSwap<StatsComp
}
}

#[cfg(not(target_arch = "wasm32"))]
/// Handle stats computation when agent changes from disabled to enabled
pub(crate) fn handle_stats_disabled_by_agent<
C: HttpClientCapability + SleepCapability + MaybeSend + Sync + 'static,
Expand Down Expand Up @@ -240,7 +226,6 @@ pub(crate) fn handle_stats_disabled_by_agent<
}

#[cfg(feature = "stats-obfuscation")]
#[cfg(not(target_arch = "wasm32"))]
fn update_obfuscation_config(
agent_info: &Arc<AgentInfo>,
client_side_stats: &StatsComputationConfig,
Expand Down Expand Up @@ -270,7 +255,6 @@ fn update_obfuscation_config(
}
}

#[cfg(not(target_arch = "wasm32"))]
pub(crate) async fn handle_stats_enabled(
agent_info: &Arc<AgentInfo>,
stats_concentrator: &Arc<Mutex<SpanConcentrator>>,
Expand Down
2 changes: 2 additions & 0 deletions libdd-trace-stats/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
1 change: 0 additions & 1 deletion libdd-trace-stats/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
6 changes: 4 additions & 2 deletions libdd-trace-stats/src/span_concentrator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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))
}

Expand Down
Loading