Skip to content

Commit 883b656

Browse files
authored
fix micrometer invalid double values (#1419)
* fix micrometer invalid double values
1 parent 2d2057f commit 883b656

File tree

3 files changed

+30
-4
lines changed

3 files changed

+30
-4
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ endif::[]
3636
* Eliminate `unsupported class version error` messages related to loading the Java 11 HttpClient plugin in pre-Java-11 JVMs {pull}1397[1397]
3737
* Fix rejected metric events by APM Server with response code 400 due to data validation error - sanitizing Micrometer
3838
metricset tag keys - {pull}1413[1413]
39+
* Fix invalid micrometer metrics with non-numeric values {pull}1419[1419]
3940
* Fix `NoClassDefFoundError` with JDBC instrumentation plugin {pull}1409[1409]
4041
4142
[[release-notes-1.x]]

apm-agent-plugins/apm-micrometer-plugin/src/main/java/co/elastic/apm/agent/micrometer/MicrometerMeterRegistrySerializer.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import co.elastic.apm.agent.report.serialize.DslJsonSerializer;
2828
import com.dslplatform.json.DslJson;
2929
import com.dslplatform.json.JsonWriter;
30-
import com.dslplatform.json.Nullable;
3130
import com.dslplatform.json.NumberConverter;
3231
import io.micrometer.core.instrument.Counter;
3332
import io.micrometer.core.instrument.DistributionSummary;
@@ -116,10 +115,15 @@ static void serializeMetricSet(List<Tag> tags, List<Meter> meters, long epochMic
116115
serializeDistributionSummary(jw, timer.getId(), timer.count(), timer.totalAmount());
117116
hasValue = true;
118117
} else if (meter instanceof Gauge) {
119-
if (hasValue) jw.writeByte(JsonWriter.COMMA);
120118
Gauge gauge = (Gauge) meter;
121-
serializeValue(gauge.getId(), gauge.value(), jw);
122-
hasValue = true;
119+
120+
// gauge values can be Double.NaN or +/-Infinite
121+
if (isValidValue(gauge.value())) {
122+
if (hasValue) jw.writeByte(JsonWriter.COMMA);
123+
serializeValue(gauge.getId(), gauge.value(), jw);
124+
hasValue = true;
125+
}
126+
123127
} else if (meter instanceof Counter) {
124128
if (hasValue) jw.writeByte(JsonWriter.COMMA);
125129
Counter counter = (Counter) meter;
@@ -198,4 +202,8 @@ private static void serializeValueStart(String key, String suffix, JsonWriter jw
198202
jw.writeByte(JsonWriter.QUOTE);
199203
jw.writeByte(JsonWriter.SEMI);
200204
}
205+
206+
private static boolean isValidValue(double value) {
207+
return !Double.isNaN(value) && !Double.isInfinite(value);
208+
}
201209
}

apm-agent-plugins/apm-micrometer-plugin/src/test/java/co/elastic/apm/agent/micrometer/MicrometerMetricsReporterTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,23 @@ void testDistributionSummary() {
229229
assertThat(metricSet.get("metricset").get("samples").get("timer.sum").get("value").longValue()).isEqualTo(3);
230230
}
231231

232+
@Test
233+
void tryToSerializeInvalidGaugeValues() {
234+
for (Double invalidValue : Arrays.asList(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN)) {
235+
List<Tag> tags = List.of(Tag.of("foo", "bar"));
236+
meterRegistry.gauge("gauge1", tags, 42, v -> invalidValue);
237+
meterRegistry.gauge("gauge2", tags, 42, v -> 42D);
238+
JsonNode metricSet = getSingleMetricSet();
239+
assertThat(metricSet.get("metricset").get("samples").get("gauge1"))
240+
.describedAs("value of %s is not expected to be written to json", invalidValue)
241+
.isNull();
242+
243+
// serialization should handle ignoring the 1st value
244+
assertThat(metricSet.get("metricset").get("samples").get("gauge2").get("value").doubleValue())
245+
.isEqualTo(42D);
246+
}
247+
}
248+
232249
private JsonNode getSingleMetricSet() {
233250
List<JsonNode> metricSets = getMetricSets();
234251
assertThat(metricSets).hasSize(1);

0 commit comments

Comments
 (0)