Skip to content

Commit ae0aa11

Browse files
authored
fix: skip encoding empty sketches (vectordotdev#18530)
Signed-off-by: Luke Steensen <[email protected]>
1 parent 7295f22 commit ae0aa11

File tree

1 file changed

+54
-21
lines changed

1 file changed

+54
-21
lines changed

src/sinks/datadog/metrics/encoder.rs

+54-21
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,11 @@ fn sketch_to_proto_message(
390390
ddsketch: &AgentDDSketch,
391391
default_namespace: &Option<Arc<str>>,
392392
log_schema: &'static LogSchema,
393-
) -> ddmetric_proto::sketch_payload::Sketch {
393+
) -> Option<ddmetric_proto::sketch_payload::Sketch> {
394+
if ddsketch.is_empty() {
395+
return None;
396+
}
397+
394398
let name = get_namespaced_name(metric, default_namespace);
395399
let ts = encode_timestamp(metric.timestamp());
396400
let mut tags = metric.tags().cloned().unwrap_or_default();
@@ -418,7 +422,7 @@ fn sketch_to_proto_message(
418422
let k = bins.into_iter().map(Into::into).collect();
419423
let n = counts.into_iter().map(Into::into).collect();
420424

421-
ddmetric_proto::sketch_payload::Sketch {
425+
Some(ddmetric_proto::sketch_payload::Sketch {
422426
metric: name,
423427
tags,
424428
host,
@@ -433,7 +437,7 @@ fn sketch_to_proto_message(
433437
k,
434438
n,
435439
}],
436-
}
440+
})
437441
}
438442

439443
fn encode_sketch_incremental<B>(
@@ -459,16 +463,21 @@ where
459463
// for `SketchPayload` with a single sketch looks just like as if we literally wrote out a
460464
// single value for the given field.
461465

462-
let sketch_proto = sketch_to_proto_message(metric, ddsketch, default_namespace, log_schema);
463-
464-
// Manually write the field tag for `sketches` and then encode the sketch payload directly as a
465-
// length-delimited message.
466-
prost::encoding::encode_key(
467-
get_sketch_payload_sketches_field_number(),
468-
prost::encoding::WireType::LengthDelimited,
469-
buf,
470-
);
471-
sketch_proto.encode_length_delimited(buf)
466+
if let Some(sketch_proto) =
467+
sketch_to_proto_message(metric, ddsketch, default_namespace, log_schema)
468+
{
469+
// Manually write the field tag for `sketches` and then encode the sketch payload directly as a
470+
// length-delimited message.
471+
prost::encoding::encode_key(
472+
get_sketch_payload_sketches_field_number(),
473+
prost::encoding::WireType::LengthDelimited,
474+
buf,
475+
);
476+
sketch_proto.encode_length_delimited(buf)
477+
} else {
478+
// If the sketch was empty, that's fine too
479+
Ok(())
480+
}
472481
}
473482

474483
fn get_namespaced_name(metric: &Metric, default_namespace: &Option<Arc<str>>) -> String {
@@ -790,15 +799,11 @@ mod tests {
790799
};
791800
match sketch {
792801
MetricSketch::AgentDDSketch(ddsketch) => {
793-
// Don't encode any empty sketches.
794-
if ddsketch.is_empty() {
795-
continue;
802+
if let Some(sketch) =
803+
sketch_to_proto_message(metric, ddsketch, default_namespace, log_schema)
804+
{
805+
sketches.push(sketch);
796806
}
797-
798-
let sketch =
799-
sketch_to_proto_message(metric, ddsketch, default_namespace, log_schema);
800-
801-
sketches.push(sketch);
802807
}
803808
}
804809
}
@@ -927,6 +932,34 @@ mod tests {
927932
assert_eq!(expected, processed.pop().unwrap());
928933
}
929934

935+
#[test]
936+
fn encode_empty_sketch() {
937+
// This is a simple test where we ensure that a single metric, with the default limits, can
938+
// be encoded without hitting any errors.
939+
let mut encoder = DatadogMetricsEncoder::new(DatadogMetricsEndpoint::Sketches, None)
940+
.expect("default payload size limits should be valid");
941+
let sketch = Metric::new(
942+
"empty",
943+
MetricKind::Incremental,
944+
AgentDDSketch::with_agent_defaults().into(),
945+
)
946+
.with_timestamp(Some(ts()));
947+
let expected = sketch.clone();
948+
949+
// Encode the sketch.
950+
let result = encoder.try_encode(sketch);
951+
assert!(result.is_ok());
952+
assert_eq!(result.unwrap(), None);
953+
954+
// Finish the payload, make sure we got what we came for.
955+
let result = encoder.finish();
956+
assert!(result.is_ok());
957+
958+
let (_payload, mut processed) = result.unwrap();
959+
assert_eq!(processed.len(), 1);
960+
assert_eq!(expected, processed.pop().unwrap());
961+
}
962+
930963
#[test]
931964
fn encode_multiple_sketch_metrics_normal_vs_incremental() {
932965
// This tests our incremental sketch encoding against the more straightforward approach of

0 commit comments

Comments
 (0)