Skip to content

Commit 540468b

Browse files
wilkinsonaphilwebb
authored andcommitted
Fix parsing of day duration meter values
Switch `MeterValue` parsing logic so that we try `Duration` before `double`. Prior to this commit, the value `1d` would result in `1.0` rather than "1 day". Fixes gh-28302
1 parent fc2c460 commit 540468b

File tree

3 files changed

+21
-13
lines changed

3 files changed

+21
-13
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MeterValue.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,11 @@ private Long getTimerValue() {
8686
* @return a {@link MeterValue} instance
8787
*/
8888
public static MeterValue valueOf(String value) {
89-
Double number = safeParseDouble(value);
90-
if (number != null) {
91-
return new MeterValue(number);
89+
Duration duration = safeParseDuration(value);
90+
if (duration != null) {
91+
return new MeterValue(duration);
9292
}
93-
return new MeterValue(DurationStyle.detectAndParse(value));
93+
return new MeterValue(Double.valueOf(value));
9494
}
9595

9696
/**
@@ -114,11 +114,11 @@ public static MeterValue valueOf(double value) {
114114
return new MeterValue(value);
115115
}
116116

117-
private static Double safeParseDouble(String value) {
117+
private static Duration safeParseDuration(String value) {
118118
try {
119-
return Double.valueOf(value);
119+
return DurationStyle.detectAndParse(value);
120120
}
121-
catch (NumberFormatException ex) {
121+
catch (IllegalArgumentException ex) {
122122
return null;
123123
}
124124
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/MetricsProperties.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -235,21 +235,21 @@ public static class Distribution {
235235
/**
236236
* Specific service-level objective boundaries for meter IDs starting with the
237237
* specified name. The longest match wins. Counters will be published for each
238-
* specified boundary. Values can be specified as a long or as a Duration value
238+
* specified boundary. Values can be specified as a double or as a Duration value
239239
* (for timer meters, defaulting to ms if no unit specified).
240240
*/
241241
private final Map<String, ServiceLevelObjectiveBoundary[]> slo = new LinkedHashMap<>();
242242

243243
/**
244244
* Minimum value that meter IDs starting with the specified name are expected to
245-
* observe. The longest match wins. Values can be specified as a long or as a
245+
* observe. The longest match wins. Values can be specified as a double or as a
246246
* Duration value (for timer meters, defaulting to ms if no unit specified).
247247
*/
248248
private final Map<String, String> minimumExpectedValue = new LinkedHashMap<>();
249249

250250
/**
251251
* Maximum value that meter IDs starting with the specified name are expected to
252-
* observe. The longest match wins. Values can be specified as a long or as a
252+
* observe. The longest match wins. Values can be specified as a double or as a
253253
* Duration value (for timer meters, defaulting to ms if no unit specified).
254254
*/
255255
private final Map<String, String> maximumExpectedValue = new LinkedHashMap<>();

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/ServiceLevelObjectiveBoundaryTests.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.metrics;
1818

19+
import java.time.Duration;
20+
1921
import io.micrometer.core.instrument.Meter.Type;
2022
import org.junit.jupiter.api.Test;
2123

@@ -42,11 +44,17 @@ void getValueForTimerWhenFromNumberStringShouldMsToNanosValue() {
4244
}
4345

4446
@Test
45-
void getValueForTimerWhenFromDurationStringShouldReturnDurationNanos() {
47+
void getValueForTimerWhenFromMillisecondDurationStringShouldReturnDurationNanos() {
4648
ServiceLevelObjectiveBoundary slo = ServiceLevelObjectiveBoundary.valueOf("123ms");
4749
assertThat(slo.getValue(Type.TIMER)).isEqualTo(123000000);
4850
}
4951

52+
@Test
53+
void getValueForTimerWhenFromDaysDurationStringShouldReturnDurationNanos() {
54+
ServiceLevelObjectiveBoundary slo = ServiceLevelObjectiveBoundary.valueOf("1d");
55+
assertThat(slo.getValue(Type.TIMER)).isEqualTo(Duration.ofDays(1).toNanos());
56+
}
57+
5058
@Test
5159
void getValueForDistributionSummaryWhenFromDoubleShouldReturnDoubleValue() {
5260
ServiceLevelObjectiveBoundary slo = ServiceLevelObjectiveBoundary.valueOf(123.42);

0 commit comments

Comments
 (0)