Skip to content

Commit 45e0741

Browse files
authored
Namespace datadog blackhole target metrics & default off (#1926)
* feat(datadog): namespace recorded series under target/ prefix Datadog blackhole now prefixes recorded metric names with target/, matching the prometheus and expvar target metrics collectors. The record policy continues to match on the unprefixed series name. Also changes the default record policy to Disabled, so no target metrics are recorded unless explicitly configured. Both are breaking changes for consumers relying on unprefixed metric names or default-all recording behavior. * update rand + silence unused * bump CI
1 parent c61c51c commit 45e0741

4 files changed

Lines changed: 40 additions & 18 deletions

File tree

.cargo/audit.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
[advisories]
22
ignore = [
33
"RUSTSEC-2020-0159",
4-
"RUSTSEC-2026-0001", # rkyv 0.7.46 UB in Arc/Rc - transitive via rust_decimal <- byte-unit
4+
"RUSTSEC-2026-0001", # rkyv 0.7.46 UB in Arc/Rc - optional dep of rust_decimal <- byte-unit, never compiled
5+
"RUSTSEC-2026-0235", # rkyv 0.7.46 OOB read - optional dep of rust_decimal <- byte-unit, never compiled
56
"RUSTSEC-2024-0436", # paste unmaintained - transitive via parquet
67
]
78

CHANGELOG.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## Unreleased
8+
9+
## Changed
10+
- **Breaking Change**: Datadog blackhole now records received series under the
11+
`target/` prefix, matching the prometheus and expvar target metrics
12+
collectors. The `record` policy still matches on the unprefixed series name.
13+
- **Breaking Change**: Datadog blackhole does not record any target metrics by
14+
default.
15+
16+
## Added
817
- Datadog blackhole now accepts a `record` policy (`all` / `disabled` /
918
`series_to_keep: [...]`) controlling which received series are recorded as
1019
capture metrics.
@@ -24,7 +33,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2433
metric, or omits the field entirely if the pool is empty.
2534
- `dogstatsd` generator now supports DogStatsD protocol v1.3 `|T` timestamps
2635
for count and gauge metrics via `timestamp.range` and `timestamp.probability`.
27-
- Fixed: `dogstatsd` tag generation would silently fail with a misleading
36+
37+
## Fixed
38+
- `dogstatsd` tag generation would silently fail with a misleading
2839
`StringGenerate` error for any `tag_length` whose range collapses after
2940
reserving one byte for the `:` separator -- every constant or single-value
3041
range (e.g. `Constant(3)`, `Constant(4)`, `Inclusive { min: 100, max: 100 }`)

Cargo.lock

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

lading/src/blackhole/datadog.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ use tracing::{debug, error, info, trace, warn};
4949
use super::General;
5050
use crate::proto::datadog::intake::metrics::MetricPayload;
5151

52+
/// Namespace for incoming metrics; matches other target-originated metrics.
53+
const TARGET_PREFIX: &str = "target/";
54+
5255
#[derive(thiserror::Error, Debug)]
5356
/// Errors produced by [`Datadog`].
5457
pub enum Error {
@@ -112,7 +115,7 @@ pub enum RecordPolicy {
112115

113116
impl Default for RecordPolicy {
114117
fn default() -> Self {
115-
Self::All
118+
Self::Disabled
116119
}
117120
}
118121

@@ -367,9 +370,16 @@ async fn handle_v2_protobuf(
367370
);
368371

369372
if !matches!(record, RecordPolicy::Disabled) {
373+
let mut scratch = String::new();
374+
370375
for series in payload.series.iter().filter(|series| {
371376
!series.points.is_empty() && record.records_series(&series.metric)
372377
}) {
378+
scratch.clear();
379+
scratch.reserve(TARGET_PREFIX.len() + series.metric.len());
380+
scratch.push_str(TARGET_PREFIX);
381+
scratch.push_str(&series.metric);
382+
373383
// Parse Datadog tags (format: "key:value" or "key") into label pairs.
374384
// Key-only tags are represented with an empty value.
375385
let tag_pairs: Vec<(&str, &str)> = series
@@ -395,7 +405,7 @@ async fn handle_v2_protobuf(
395405
// COUNT
396406
#[expect(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
397407
let value = point.value.round() as u64;
398-
counter_incr(&series.metric, &tag_pairs, value, timestamp).await
408+
counter_incr(&scratch, &tag_pairs, value, timestamp).await
399409
}
400410
2 => {
401411
// RATE
@@ -409,11 +419,11 @@ async fn handle_v2_protobuf(
409419
}
410420
#[expect(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
411421
let val = (point.value * interval as f64).round() as u64;
412-
counter_incr(&series.metric, &tag_pairs, val, timestamp).await
422+
counter_incr(&scratch, &tag_pairs, val, timestamp).await
413423
}
414424
3 => {
415425
// GAUGE
416-
gauge_set(&series.metric, &tag_pairs, point.value, timestamp).await
426+
gauge_set(&scratch, &tag_pairs, point.value, timestamp).await
417427
}
418428
i => {
419429
warn!("Unknown metric type, skipping: {i}");

0 commit comments

Comments
 (0)