Skip to content
Open
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
3 changes: 3 additions & 0 deletions changelog.d/25621_datadog_metrics_sort.fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fixed a bug in the `datadog_metrics` sink where the metric type name was compared against itself (instead of the peer metric) when sorting metrics before encoding. The sort key is `(type_name, metric_name, timestamp)`, but the type comparison was a no-op, making `metric_name` the effective primary key. The fix restores the intended ordering.

authors: gwenaskell
20 changes: 19 additions & 1 deletion src/sinks/datadog/metrics/sink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ fn sort_and_collapse_counters_by_series_and_timestamp(mut metrics: Vec<Metric>)
a.timestamp().map(|dt| dt.timestamp()).unwrap_or(now_ts),
)
.cmp(&(
a.value().as_name(),
b.value().as_name(),
b.series(),
b.timestamp().map(|dt| dt.timestamp()).unwrap_or(now_ts),
))
Expand Down Expand Up @@ -393,6 +393,24 @@ mod tests {
assert_eq!(expected, actual);
}

#[test]
fn sort_metric_type_is_primary_sort_key() {
// The sort key is (type_name, series, timestamp). "counter" < "gauge" alphabetically,
// so a counter must always precede a gauge regardless of series name.
let input = vec![
create_gauge("aaa", 1.0),
create_counter("zzz", 1.0),
create_counter("aaa", 1.0),
];
let expected = vec![
create_counter("aaa", 1.0),
create_counter("zzz", 1.0),
create_gauge("aaa", 1.0),
];
let actual = sort_and_collapse_counters_by_series_and_timestamp(input);
assert_eq!(expected, actual);
}

#[test]
fn collapse_identical_metrics_multiple_timestamps() {
let ts_1 = Utc::now() - Duration::from_secs(5);
Expand Down
Loading