Skip to content

Commit 6db2199

Browse files
authored
fix(dogstatsd): properly pack multiple metrics into each payload up to the configured limit (#586)
1 parent 68c40ee commit 6db2199

File tree

8 files changed

+601
-378
lines changed

8 files changed

+601
-378
lines changed

Cargo.lock

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

metrics-exporter-dogstatsd/proptest-regressions/forwarder/writer.txt

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Seeds for failure cases proptest has generated in the past. It is
2+
# automatically read and these particular cases re-run before any
3+
# novel cases are generated.
4+
#
5+
# It is recommended to check this file in to source control so that
6+
# everyone who runs the test benefits from these saved cases.
7+
cc ecafaadc4a51995b06f20080248f4e17c818026dc20e29e2a2dd233393af6773 # shrinks to payload_limit = 27, inputs = [Histogram(Key { name: KeyName("aAAaAa0a"), labels: [Label("aaaaa", "")], hashed: true, hash: 4563833112871895604 }, [-0.0]), Histogram(Key { name: KeyName("0AA0AaaA"), labels: [], hashed: true, hash: 13699395814728153738 }, [-0.0])]
8+
cc 8d5fca863d5e68150df55ff75e9718f6491d27dfd598e53b29fd0583a5e05a66 # shrinks to payload_limit = 0, inputs = [Counter(Key { name: KeyName("aaAAAAaa"), labels: [], hashed: true, hash: 15261619708481900111 }, 0, None)]

metrics-exporter-dogstatsd/src/builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,6 @@ impl DogStatsDBuilder {
347347
histogram_sampling: self.histogram_sampling,
348348
histogram_reservoir_size: self.histogram_reservoir_size,
349349
histograms_as_distributions: self.histograms_as_distributions,
350-
global_labels: self.global_labels,
351350
global_prefix: self.global_prefix,
352351
};
353352

@@ -367,6 +366,7 @@ impl DogStatsDBuilder {
367366
max_payload_len,
368367
flush_interval,
369368
write_timeout: self.write_timeout,
369+
global_labels: self.global_labels,
370370
};
371371

372372
if self.synchronous {

metrics-exporter-dogstatsd/src/forwarder/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use std::{
66
time::Duration,
77
};
88

9+
use metrics::Label;
10+
911
pub mod sync;
1012

1113
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -105,9 +107,20 @@ fn unknown_scheme_error_str(scheme: &str) -> String {
105107
#[derive(Clone)]
106108
pub(crate) struct ForwarderConfiguration {
107109
pub remote_addr: RemoteAddr,
110+
111+
/// Maximum size, in bytes, for an individual payload.
112+
///
113+
/// Payloads may contain multiple metrics.
108114
pub max_payload_len: usize,
115+
116+
/// Duration to wait between flushing metrics.
109117
pub flush_interval: Duration,
118+
119+
/// Timeout for writing to the socket.
110120
pub write_timeout: Duration,
121+
122+
/// Global labels to attach to all metrics.
123+
pub global_labels: Vec<Label>,
111124
}
112125

113126
impl ForwarderConfiguration {

metrics-exporter-dogstatsd/src/forwarder/sync.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ impl Forwarder {
146146
pub fn run(mut self) {
147147
let mut flush_state = FlushState::default();
148148
let mut writer =
149-
PayloadWriter::new(self.config.max_payload_len, self.config.is_length_prefixed());
149+
PayloadWriter::new(self.config.max_payload_len, self.config.is_length_prefixed())
150+
.with_global_labels(&self.config.global_labels);
150151
let mut telemetry_update = TelemetryUpdate::default();
151152

152153
let mut next_flush = Instant::now() + self.config.flush_interval;

metrics-exporter-dogstatsd/src/state.rs

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{collections::HashSet, time::SystemTime};
22

3-
use metrics::{Key, Label};
3+
use metrics::Key;
44
use metrics_util::registry::Registry;
55
use tracing::error;
66

@@ -28,9 +28,6 @@ pub struct StateConfiguration {
2828
/// Whether or not to emit histograms as distributions.
2929
pub histograms_as_distributions: bool,
3030

31-
/// Global labels to add to all metrics
32-
pub global_labels: Vec<Label>,
33-
3431
/// Global prefix/namespace to use for all metrics
3532
pub global_prefix: Option<String>,
3633
}
@@ -108,13 +105,8 @@ impl State {
108105
self.config.global_prefix.as_deref()
109106
};
110107

111-
let result = writer.write_counter(
112-
&key,
113-
value,
114-
self.get_aggregation_timestamp(),
115-
prefix,
116-
&self.config.global_labels,
117-
);
108+
let result =
109+
writer.write_counter(&key, value, self.get_aggregation_timestamp(), prefix);
118110
if result.any_failures() {
119111
let points_dropped = result.points_dropped();
120112
error!(
@@ -140,13 +132,7 @@ impl State {
140132
} else {
141133
self.config.global_prefix.as_deref()
142134
};
143-
let result = writer.write_gauge(
144-
&key,
145-
value,
146-
self.get_aggregation_timestamp(),
147-
prefix,
148-
&self.config.global_labels,
149-
);
135+
let result = writer.write_gauge(&key, value, self.get_aggregation_timestamp(), prefix);
150136
if result.any_failures() {
151137
let points_dropped = result.points_dropped();
152138
error!(metric_name = key.name(), points_dropped, "Failed to build gauge payload.");
@@ -175,21 +161,9 @@ impl State {
175161
histogram.flush(|maybe_sample_rate, values| {
176162
let points_len = values.len();
177163
let result = if self.config.histograms_as_distributions {
178-
writer.write_distribution(
179-
&key,
180-
values,
181-
maybe_sample_rate,
182-
prefix,
183-
&self.config.global_labels,
184-
)
164+
writer.write_distribution(&key, values, maybe_sample_rate, prefix)
185165
} else {
186-
writer.write_histogram(
187-
&key,
188-
values,
189-
maybe_sample_rate,
190-
prefix,
191-
&self.config.global_labels,
192-
)
166+
writer.write_histogram(&key, values, maybe_sample_rate, prefix)
193167
};
194168

195169
// Scale the points flushed/dropped values by the sample rate to determine the true number of points flushed/dropped.

0 commit comments

Comments
 (0)