Skip to content

Commit 32e3de1

Browse files
authored
Merge branch 'main' into leiyks/sidecar-default-service-name
2 parents 91436f4 + 952c2ef commit 32e3de1

31 files changed

Lines changed: 2868 additions & 134 deletions

Cargo.lock

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

LICENSE-3rdparty.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ target-triple,https://github.com/dtolnay/target-triple,MIT OR Apache-2.0,David T
429429
tempfile,https://github.com/Stebalien/tempfile,MIT OR Apache-2.0,"Steven Allen <steven@stebalien.com>, The Rust Project Developers, Ashley Mannix <ashleymannix@live.com.au>, Jason White <me@jasonwhite.io>"
430430
termcolor,https://github.com/BurntSushi/termcolor,Unlicense OR MIT,Andrew Gallant <jamslam@gmail.com>
431431
test-case-macros,https://github.com/frondeus/test-case,MIT,"Marcin Sas-Szymanski <marcin.sas-szymanski@anixe.pl>, Wojciech Polak <frondeus@gmail.com>, Łukasz Biel <lukasz.p.biel@gmail.com>"
432+
thin-vec,https://github.com/mozilla/thin-vec,MIT OR Apache-2.0,Aria Beingessner <a.beingessner@gmail.com>
432433
thiserror,https://github.com/dtolnay/thiserror,MIT OR Apache-2.0,David Tolnay <dtolnay@gmail.com>
433434
thiserror-impl,https://github.com/dtolnay/thiserror,MIT OR Apache-2.0,David Tolnay <dtolnay@gmail.com>
434435
thread_local,https://github.com/Amanieu/thread_local-rs,MIT OR Apache-2.0,Amanieu d'Antras <amanieu@gmail.com>

libdd-common/src/regex_engine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
//! regexes requiring Unicode character class support.
1414
1515
#[cfg(all(feature = "regex-lite", not(feature = "require-regex-full")))]
16-
pub use regex_lite::{escape, Captures, Regex, RegexBuilder, Replacer};
16+
pub use regex_lite::{escape, Captures, Error, Regex, RegexBuilder, Replacer};
1717

1818
#[cfg(not(all(feature = "regex-lite", not(feature = "require-regex-full"))))]
19-
pub use regex::{escape, Captures, Regex, RegexBuilder, Replacer};
19+
pub use regex::{escape, Captures, Error, Regex, RegexBuilder, Replacer};

libdd-data-pipeline/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ libdd-common = { version = "4.2.0", path = "../libdd-common", default-features =
3636
libdd-shared-runtime = { version = "1.0.0", path = "../libdd-shared-runtime", default-features = false }
3737
libdd-telemetry = { version = "5.0.1", path = "../libdd-telemetry", default-features = false, optional = true}
3838
libdd-trace-protobuf = { version = "3.0.2", path = "../libdd-trace-protobuf" }
39+
libdd-trace-normalization = { version = "2.0.0", path = "../libdd-trace-normalization" }
3940
libdd-trace-stats = { version = "5.0.0", path = "../libdd-trace-stats", default-features = false }
4041
libdd-trace-utils = { version = "8.0.0", path = "../libdd-trace-utils", default-features = false }
4142
libdd-trace-obfuscation = { version = "4.0.0", path = "../libdd-trace-obfuscation", default-features = false, optional = true }

libdd-data-pipeline/src/agent_info/schema.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,25 @@ pub struct AgentInfoStruct {
4040
/// Container tags hash from HTTP response header
4141
pub container_tags_hash: Option<String>,
4242
/// Exact-match tag filters applied before stats computation (root span only).
43-
pub filter_tags: Option<FilterTagsConfig>,
43+
#[serde(default)]
44+
pub filter_tags: FilterTagsConfig,
4445
/// Regex-match tag filters applied before stats computation (root span only).
45-
pub filter_tags_regex: Option<FilterTagsConfig>,
46+
#[serde(default)]
47+
pub filter_tags_regex: FilterTagsConfig,
4648
/// Regex patterns for root-span resource names; matching traces are excluded from stats.
47-
pub ignore_resources: Option<Vec<String>>,
49+
#[serde(default)]
50+
pub ignore_resources: Vec<String>,
4851
}
4952

5053
/// Require/reject lists for tag-based trace filters exposed by the agent /info endpoint.
5154
#[derive(Clone, Serialize, Deserialize, Default, Debug, PartialEq)]
5255
pub struct FilterTagsConfig {
5356
/// All listed filters must match at least one root-span tag for the trace to be accepted.
54-
pub require: Option<Vec<String>>,
57+
#[serde(default)]
58+
pub require: Vec<String>,
5559
/// If any listed filter matches a root-span tag the trace is rejected.
56-
pub reject: Option<Vec<String>>,
60+
#[serde(default)]
61+
pub reject: Vec<String>,
5762
}
5863

5964
#[allow(missing_docs)]

libdd-data-pipeline/src/telemetry/metrics.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ pub enum MetricKind {
2727
ChunksSent,
2828
/// trace_chunks_dropped metric (reason: p0_drop)
2929
ChunksDroppedP0,
30+
/// trace_chunks_dropped metric (reason: trace_filters)
31+
ChunksDroppedByTraceFilter,
3032
/// trace_chunks_dropped metric (reason: serialization_error)
3133
ChunksDroppedSerializationError,
3234
/// trace_chunks_dropped metric (reason: send_failure)
@@ -102,6 +104,15 @@ const METRICS: &[Metric] = &[
102104
namespace: MetricNamespace::Tracers,
103105
tags: &[tag!["src_library", "libdatadog"], tag!["reason", "p0_drop"]],
104106
},
107+
Metric {
108+
name: CHUNKS_DROPPED_STR,
109+
metric_type: MetricType::Count,
110+
namespace: MetricNamespace::Tracers,
111+
tags: &[
112+
tag!["src_library", "libdatadog"],
113+
tag!["reason", "trace_filters"],
114+
],
115+
},
105116
Metric {
106117
name: CHUNKS_DROPPED_STR,
107118
metric_type: MetricType::Count,

libdd-data-pipeline/src/telemetry/mod.rs

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use libdd_telemetry::worker::{
1313
};
1414
use libdd_trace_utils::{
1515
send_with_retry::{SendWithRetryError, SendWithRetryResult},
16+
span::trace_utils::DroppedStats,
1617
trace_utils::SendDataResult,
1718
};
1819
use std::{collections::HashMap, time::Duration};
@@ -165,6 +166,7 @@ pub struct SendPayloadTelemetry {
165166
bytes_sent: u64,
166167
chunks_sent: u64,
167168
chunks_dropped_p0: u64,
169+
chunks_dropped_by_trace_filter: u64,
168170
chunks_dropped_serialization_error: u64,
169171
chunks_dropped_send_failure: u64,
170172
responses_count_per_code: HashMap<u16, u64>,
@@ -193,15 +195,16 @@ impl SendPayloadTelemetry {
193195
/// * `value` - The result of sending traces with retry
194196
/// * `bytes_sent` - The number of bytes in the payload
195197
/// * `chunks` - The number of trace chunks in the payload
196-
/// * `chunks_dropped_p0` - The number of P0 trace chunks dropped due to sampling
198+
/// * `dropped_stats` - Trace dropped stats from `stats::process_traces_for_stats`
197199
pub fn from_retry_result(
198200
value: &SendWithRetryResult,
199201
bytes_sent: u64,
200202
chunks: u64,
201-
chunks_dropped_p0: u64,
203+
dropped_stats: DroppedStats,
202204
) -> Self {
203205
let mut telemetry = Self {
204-
chunks_dropped_p0,
206+
chunks_dropped_p0: dropped_stats.dropped_p0_traces as u64,
207+
chunks_dropped_by_trace_filter: dropped_stats.dropped_by_trace_filter as u64,
205208
..Default::default()
206209
};
207210
match value {
@@ -288,6 +291,13 @@ impl TelemetryClient {
288291
self.worker
289292
.add_point(data.chunks_dropped_p0 as f64, key, vec![])?;
290293
}
294+
if data.chunks_dropped_by_trace_filter > 0 {
295+
let key = self
296+
.metrics
297+
.get(metrics::MetricKind::ChunksDroppedByTraceFilter);
298+
self.worker
299+
.add_point(data.chunks_dropped_by_trace_filter as f64, key, vec![])?;
300+
}
291301
if data.chunks_dropped_serialization_error > 0 {
292302
let key = self
293303
.metrics
@@ -704,7 +714,16 @@ mod tests {
704714
.unwrap(),
705715
3,
706716
));
707-
let telemetry = SendPayloadTelemetry::from_retry_result(&result, 4, 5, 0);
717+
let telemetry = SendPayloadTelemetry::from_retry_result(
718+
&result,
719+
4,
720+
5,
721+
DroppedStats {
722+
dropped_p0_traces: 0,
723+
dropped_p0_spans: 0,
724+
dropped_by_trace_filter: 0,
725+
},
726+
);
708727
assert_eq!(
709728
telemetry,
710729
SendPayloadTelemetry {
@@ -726,7 +745,16 @@ mod tests {
726745
.unwrap(),
727746
3,
728747
));
729-
let telemetry = SendPayloadTelemetry::from_retry_result(&result, 4, 5, 10);
748+
let telemetry = SendPayloadTelemetry::from_retry_result(
749+
&result,
750+
4,
751+
5,
752+
DroppedStats {
753+
dropped_p0_traces: 10,
754+
dropped_p0_spans: 0,
755+
dropped_by_trace_filter: 0,
756+
},
757+
);
730758
assert_eq!(
731759
telemetry,
732760
SendPayloadTelemetry {
@@ -747,7 +775,16 @@ mod tests {
747775
.body(Bytes::new())
748776
.unwrap();
749777
let result = Err(SendWithRetryError::Http(error_response, 5));
750-
let telemetry = SendPayloadTelemetry::from_retry_result(&result, 1, 2, 0);
778+
let telemetry = SendPayloadTelemetry::from_retry_result(
779+
&result,
780+
1,
781+
2,
782+
DroppedStats {
783+
dropped_p0_traces: 0,
784+
dropped_p0_spans: 0,
785+
dropped_by_trace_filter: 0,
786+
},
787+
);
751788
assert_eq!(
752789
telemetry,
753790
SendPayloadTelemetry {
@@ -766,7 +803,16 @@ mod tests {
766803
HttpError::Network(anyhow::anyhow!("connection refused")),
767804
5,
768805
));
769-
let telemetry = SendPayloadTelemetry::from_retry_result(&result, 1, 2, 0);
806+
let telemetry = SendPayloadTelemetry::from_retry_result(
807+
&result,
808+
1,
809+
2,
810+
DroppedStats {
811+
dropped_p0_traces: 0,
812+
dropped_p0_spans: 0,
813+
dropped_by_trace_filter: 0,
814+
},
815+
);
770816
assert_eq!(
771817
telemetry,
772818
SendPayloadTelemetry {
@@ -781,7 +827,16 @@ mod tests {
781827
#[test]
782828
fn telemetry_from_timeout_error_test() {
783829
let result = Err(SendWithRetryError::Timeout(5));
784-
let telemetry = SendPayloadTelemetry::from_retry_result(&result, 1, 2, 0);
830+
let telemetry = SendPayloadTelemetry::from_retry_result(
831+
&result,
832+
1,
833+
2,
834+
DroppedStats {
835+
dropped_p0_traces: 0,
836+
dropped_p0_spans: 0,
837+
dropped_by_trace_filter: 0,
838+
},
839+
);
785840
assert_eq!(
786841
telemetry,
787842
SendPayloadTelemetry {
@@ -797,7 +852,16 @@ mod tests {
797852
#[test]
798853
fn telemetry_from_build_error_test() {
799854
let result = Err(SendWithRetryError::Build(5));
800-
let telemetry = SendPayloadTelemetry::from_retry_result(&result, 1, 2, 0);
855+
let telemetry = SendPayloadTelemetry::from_retry_result(
856+
&result,
857+
1,
858+
2,
859+
DroppedStats {
860+
dropped_p0_traces: 0,
861+
dropped_p0_spans: 0,
862+
dropped_by_trace_filter: 0,
863+
},
864+
);
801865
assert_eq!(
802866
telemetry,
803867
SendPayloadTelemetry {

libdd-data-pipeline/src/trace_exporter/builder.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use libdd_capabilities::{HttpClientCapability, MaybeSend, SleepCapability};
2222
use libdd_common::{parse_uri, tag, Endpoint};
2323
use libdd_dogstatsd_client::new;
2424
use libdd_shared_runtime::SharedRuntime;
25+
use libdd_trace_utils::trace_filter::TraceFilterer;
2526
use std::sync::Arc;
2627
use std::time::Duration;
2728

@@ -514,6 +515,7 @@ impl TraceExporterBuilder {
514515
.agent_rates_payload_version_enabled
515516
.then(AgentResponsePayloadVersion::new),
516517
otlp_config,
518+
trace_filterer: ArcSwap::from_pointee(TraceFilterer::with_empty_conf()),
517519
})
518520
}
519521

libdd-data-pipeline/src/trace_exporter/mod.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod trace_serializer;
99

1010
// Re-export the builder
1111
pub use builder::TraceExporterBuilder;
12+
use libdd_trace_utils::{span::trace_utils::DroppedStats, trace_filter::TraceFilterer};
1213

1314
use self::agent_response::AgentResponse;
1415
use self::metrics::MetricsEmitter;
@@ -30,7 +31,7 @@ use crate::{
3031
health_metrics,
3132
health_metrics::{HealthMetric, SendResult, TransportErrorType},
3233
};
33-
use arc_swap::ArcSwapOption;
34+
use arc_swap::{ArcSwap, ArcSwapOption};
3435
use bytes::Bytes;
3536
use http::header::HeaderMap;
3637
use http::uri::PathAndQuery;
@@ -213,6 +214,7 @@ pub struct TraceExporter<C: HttpClientCapability + SleepCapability + MaybeSend +
213214
agent_payload_response_version: Option<AgentResponsePayloadVersion>,
214215
/// When set, traces are exported via OTLP HTTP/JSON instead of the Datadog agent.
215216
otlp_config: Option<OtlpTraceConfig>,
217+
trace_filterer: ArcSwap<TraceFilterer>,
216218
}
217219

218220
impl<C: HttpClientCapability + SleepCapability + MaybeSend + Sync + 'static> TraceExporter<C> {
@@ -348,9 +350,9 @@ impl<C: HttpClientCapability + SleepCapability + MaybeSend + Sync + 'static> Tra
348350
.map(|s| s.as_str())
349351
}
350352

351-
#[cfg(not(target_arch = "wasm32"))]
352353
/// Reconcile in-process stats state with the latest agent info.
353354
/// Async so the `Enabled` arm can await a stats-worker shutdown without `block_on`.
355+
#[cfg(not(target_arch = "wasm32"))]
354356
async fn check_agent_info(&self) {
355357
let Some(agent_info) = agent_info::get_agent_info() else {
356358
return;
@@ -363,6 +365,14 @@ impl<C: HttpClientCapability + SleepCapability + MaybeSend + Sync + 'static> Tra
363365
self.refresh_v1_active(&agent_info);
364366
}
365367

368+
self.trace_filterer.store(Arc::new(TraceFilterer::new(
369+
&agent_info.info.filter_tags.require,
370+
&agent_info.info.filter_tags.reject,
371+
&agent_info.info.filter_tags_regex.require,
372+
&agent_info.info.filter_tags_regex.reject,
373+
&agent_info.info.ignore_resources,
374+
)));
375+
366376
// load_full() avoids holding an ArcSwap Guard (!Send) across .await.
367377
let status = self.client_side_stats.status.load_full();
368378
match &*status {
@@ -567,7 +577,8 @@ impl<C: HttpClientCapability + SleepCapability + MaybeSend + Sync + 'static> Tra
567577
mp_payload: Vec<u8>,
568578
headers: HeaderMap,
569579
chunks: usize,
570-
#[cfg_attr(not(feature = "telemetry"), allow(unused_variables))] chunks_dropped_p0: usize,
580+
#[cfg_attr(not(feature = "telemetry"), allow(unused_variables))]
581+
dropped_stats: DroppedStats,
571582
) -> Result<AgentResponse, TraceExporterError> {
572583
let strategy = RetryStrategy::default();
573584
let payload_len = mp_payload.len();
@@ -588,7 +599,7 @@ impl<C: HttpClientCapability + SleepCapability + MaybeSend + Sync + 'static> Tra
588599
&result,
589600
payload_len as u64,
590601
chunks as u64,
591-
chunks_dropped_p0 as u64,
602+
dropped_stats,
592603
)) {
593604
error!(?e, "Error sending telemetry");
594605
}
@@ -605,11 +616,12 @@ impl<C: HttpClientCapability + SleepCapability + MaybeSend + Sync + 'static> Tra
605616

606617
// Process stats computation and drop non-sampled (p0) chunks.
607618
// This must run before the OTLP path so that unsampled spans are not exported.
608-
let dropped_p0_stats = stats::process_traces_for_stats(
619+
let dropped_stats = stats::process_traces_for_stats(
609620
&mut traces,
610621
&mut header_tags,
611622
&self.client_side_stats.status,
612623
self.client_computed_top_level,
624+
&self.trace_filterer.load(),
613625
);
614626

615627
for chunk in &mut traces {
@@ -662,7 +674,7 @@ impl<C: HttpClientCapability + SleepCapability + MaybeSend + Sync + 'static> Tra
662674
prepared.data,
663675
prepared.headers,
664676
prepared.chunk_count,
665-
dropped_p0_stats.dropped_p0_traces,
677+
dropped_stats,
666678
)
667679
.await;
668680

0 commit comments

Comments
 (0)