Skip to content

Commit 75b670a

Browse files
author
Mateusz Rzeszutek
committed
Disable by default gauge-based histograms in the Micrometer bridge
1 parent c660a80 commit 75b670a

File tree

17 files changed

+621
-346
lines changed

17 files changed

+621
-346
lines changed
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Settings for the Micrometer bridge instrumentation
22

3-
| System property | Type | Default | Description |
4-
|---|---|---|---|
5-
| `otel.instrumentation.micrometer.base-time-unit` | String | `ms` | Set the base time unit for the OpenTelemetry `MeterRegistry` implementation. <details><summary>Valid values</summary>`ns`, `nanoseconds`, `us`, `microseconds`, `ms`, `microseconds`, `s`, `seconds`, `min`, `minutes`, `h`, `hours`, `d`, `days`</details> |
6-
| `otel.instrumentation.micrometer.prometheus-mode.enabled` | boolean | false | Enable the "Prometheus mode" this will simulate the behavior of Micrometer's PrometheusMeterRegistry. The instruments will be renamed to match Micrometer instrument naming, and the base time unit will be set to seconds. |
3+
| System property | Type | Default | Description |
4+
|------------------------------------------------------------|---------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
5+
| `otel.instrumentation.micrometer.base-time-unit` | String | `ms` | Set the base time unit for the OpenTelemetry `MeterRegistry` implementation. <details><summary>Valid values</summary>`ns`, `nanoseconds`, `us`, `microseconds`, `ms`, `microseconds`, `s`, `seconds`, `min`, `minutes`, `h`, `hours`, `d`, `days`</details> |
6+
| `otel.instrumentation.micrometer.prometheus-mode.enabled` | boolean | false | Enable the "Prometheus mode" this will simulate the behavior of Micrometer's PrometheusMeterRegistry. The instruments will be renamed to match Micrometer instrument naming, and the base time unit will be set to seconds. |
7+
| `otel.instrumentation.micrometer.histogram-gauges.enabled` | boolean | false | Enables the generation of gauge-based Micrometer histograms for `DistributionSummary` and `Timer` instruments. |

instrumentation/micrometer/micrometer-1.5/javaagent/build.gradle.kts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,25 @@ tasks {
3636
jvmArgs("-Dotel.instrumentation.micrometer.base-time-unit=seconds")
3737
}
3838

39+
val testHistogramGauges by registering(Test::class) {
40+
filter {
41+
includeTestsMatching("*HistogramGaugesTest")
42+
}
43+
include("**/*HistogramGaugesTest.*")
44+
jvmArgs("-Dotel.instrumentation.micrometer.histogram-gauges.enabled=true")
45+
}
46+
3947
test {
4048
filter {
4149
excludeTestsMatching("*TimerSecondsTest")
4250
excludeTestsMatching("*PrometheusModeTest")
51+
excludeTestsMatching("*HistogramGaugesTest")
4352
}
4453
}
4554

4655
check {
4756
dependsOn(testBaseTimeUnit)
4857
dependsOn(testPrometheusMode)
58+
dependsOn(testHistogramGauges)
4959
}
5060
}

instrumentation/micrometer/micrometer-1.5/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/micrometer/v1_5/MicrometerSingletons.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ public final class MicrometerSingletons {
2323
.setBaseTimeUnit(
2424
TimeUnitParser.parseConfigValue(
2525
config.getString("otel.instrumentation.micrometer.base-time-unit")))
26+
.setMicrometerHistogramGaugesEnabled(
27+
config.getBoolean(
28+
"otel.instrumentation.micrometer.histogram-gauges.enabled", false))
2629
.build();
2730
}
2831

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.micrometer.v1_5;
7+
8+
import io.micrometer.core.instrument.Metrics;
9+
import io.opentelemetry.instrumentation.micrometer.v1_5.AbstractDistributionSummaryHistogramGaugesTest;
10+
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
11+
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
12+
import org.junit.jupiter.api.AfterEach;
13+
import org.junit.jupiter.api.extension.RegisterExtension;
14+
15+
class DistributionSummaryHistogramGaugesTest
16+
extends AbstractDistributionSummaryHistogramGaugesTest {
17+
18+
@RegisterExtension
19+
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
20+
21+
@AfterEach
22+
public void cleanup() {
23+
Metrics.globalRegistry.forEachMeter(Metrics.globalRegistry::remove);
24+
}
25+
26+
@Override
27+
protected InstrumentationExtension testing() {
28+
return testing;
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.micrometer.v1_5;
7+
8+
import io.micrometer.core.instrument.Metrics;
9+
import io.opentelemetry.instrumentation.micrometer.v1_5.AbstractTimerHistogramGaugesTest;
10+
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
11+
import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension;
12+
import org.junit.jupiter.api.AfterEach;
13+
import org.junit.jupiter.api.extension.RegisterExtension;
14+
15+
class TimerHistogramGaugesTest extends AbstractTimerHistogramGaugesTest {
16+
17+
@RegisterExtension
18+
static final InstrumentationExtension testing = AgentInstrumentationExtension.create();
19+
20+
@AfterEach
21+
public void cleanup() {
22+
Metrics.globalRegistry.forEachMeter(Metrics.globalRegistry::remove);
23+
}
24+
25+
@Override
26+
protected InstrumentationExtension testing() {
27+
return testing;
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.micrometer.v1_5;
7+
8+
import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;
9+
10+
@SuppressWarnings("CanIgnoreReturnValueSuggester")
11+
enum DistributionStatisticConfigModifier {
12+
DISABLE_HISTOGRAM_GAUGES {
13+
@Override
14+
DistributionStatisticConfig modify(DistributionStatisticConfig config) {
15+
return DistributionStatisticConfig.builder()
16+
// disable all percentile and slo related options
17+
.percentilesHistogram(null)
18+
.percentiles((double[]) null)
19+
.serviceLevelObjectives((double[]) null)
20+
.percentilePrecision(null)
21+
// and keep the rest
22+
.minimumExpectedValue(config.getMinimumExpectedValueAsDouble())
23+
.maximumExpectedValue(config.getMaximumExpectedValueAsDouble())
24+
.expiry(config.getExpiry())
25+
.bufferLength(config.getBufferLength())
26+
.build();
27+
}
28+
},
29+
IDENTITY {
30+
@Override
31+
DistributionStatisticConfig modify(DistributionStatisticConfig config) {
32+
return config;
33+
}
34+
};
35+
36+
abstract DistributionStatisticConfig modify(DistributionStatisticConfig config);
37+
}

instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryDistributionSummary.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ final class OpenTelemetryDistributionSummary extends AbstractDistributionSummary
4343
NamingConvention namingConvention,
4444
Clock clock,
4545
DistributionStatisticConfig distributionStatisticConfig,
46+
DistributionStatisticConfigModifier modifier,
4647
double scale,
4748
Meter otelMeter) {
48-
super(id, clock, distributionStatisticConfig, scale, false);
49+
super(id, clock, modifier.modify(distributionStatisticConfig), scale, false);
4950

5051
if (isUsingMicrometerHistograms()) {
5152
measurements = new MicrometerHistogramMeasurements();

instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryMeterRegistry.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,18 @@ public static OpenTelemetryMeterRegistryBuilder builder(OpenTelemetry openTeleme
5050
}
5151

5252
private final TimeUnit baseTimeUnit;
53+
private final DistributionStatisticConfigModifier distributionStatisticConfigModifier;
5354
private final io.opentelemetry.api.metrics.Meter otelMeter;
5455

5556
OpenTelemetryMeterRegistry(
5657
Clock clock,
5758
TimeUnit baseTimeUnit,
5859
NamingConvention namingConvention,
60+
DistributionStatisticConfigModifier distributionStatisticConfigModifier,
5961
io.opentelemetry.api.metrics.Meter otelMeter) {
6062
super(clock);
6163
this.baseTimeUnit = baseTimeUnit;
64+
this.distributionStatisticConfigModifier = distributionStatisticConfigModifier;
6265
this.otelMeter = otelMeter;
6366

6467
this.config()
@@ -104,6 +107,7 @@ protected Timer newTimer(
104107
config().namingConvention(),
105108
clock,
106109
distributionStatisticConfig,
110+
distributionStatisticConfigModifier,
107111
pauseDetector,
108112
getBaseTimeUnit(),
109113
otelMeter);
@@ -118,7 +122,13 @@ protected DistributionSummary newDistributionSummary(
118122
Meter.Id id, DistributionStatisticConfig distributionStatisticConfig, double scale) {
119123
OpenTelemetryDistributionSummary distributionSummary =
120124
new OpenTelemetryDistributionSummary(
121-
id, config().namingConvention(), clock, distributionStatisticConfig, scale, otelMeter);
125+
id,
126+
config().namingConvention(),
127+
clock,
128+
distributionStatisticConfig,
129+
distributionStatisticConfigModifier,
130+
scale,
131+
otelMeter);
122132
if (distributionSummary.isUsingMicrometerHistograms()) {
123133
HistogramGauges.registerWithCommonFormat(distributionSummary, this);
124134
}

instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryMeterRegistryBuilder.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77

88
import com.google.errorprone.annotations.CanIgnoreReturnValue;
99
import io.micrometer.core.instrument.Clock;
10+
import io.micrometer.core.instrument.DistributionSummary;
11+
import io.micrometer.core.instrument.LongTaskTimer;
1012
import io.micrometer.core.instrument.MeterRegistry;
13+
import io.micrometer.core.instrument.Timer;
1114
import io.micrometer.core.instrument.config.NamingConvention;
1215
import io.opentelemetry.api.OpenTelemetry;
1316
import java.util.concurrent.TimeUnit;
@@ -22,6 +25,7 @@ public final class OpenTelemetryMeterRegistryBuilder {
2225
private Clock clock = Clock.SYSTEM;
2326
private TimeUnit baseTimeUnit = TimeUnit.MILLISECONDS;
2427
private boolean prometheusMode = false;
28+
private boolean histogramGaugesEnabled = false;
2529

2630
OpenTelemetryMeterRegistryBuilder(OpenTelemetry openTelemetry) {
2731
this.openTelemetry = openTelemetry;
@@ -54,6 +58,27 @@ public OpenTelemetryMeterRegistryBuilder setPrometheusMode(boolean prometheusMod
5458
return this;
5559
}
5660

61+
/**
62+
* Enables the generation of gauge-based Micrometer histograms. While the Micrometer bridge is
63+
* able to map Micrometer's {@link DistributionSummary} and {@link Timer} service level objectives
64+
* to OpenTelemetry histogram buckets, it might not cover all cases that are normally supported by
65+
* Micrometer (e.g. the bridge is not able to translate percentiles). With this setting enabled,
66+
* the Micrometer bridge will additionally emit Micrometer service level objectives and
67+
* percentiles as separate gauges.
68+
*
69+
* <p>Note that this setting does not concern the {@link LongTaskTimer}, as it is not bridged to
70+
* an OpenTelemetry histogram.
71+
*
72+
* <p>This is disabled by default, set this to {@code true} to enable gauge-based Micrometer
73+
* histograms.
74+
*/
75+
@CanIgnoreReturnValue
76+
public OpenTelemetryMeterRegistryBuilder setMicrometerHistogramGaugesEnabled(
77+
boolean histogramGaugesEnabled) {
78+
this.histogramGaugesEnabled = histogramGaugesEnabled;
79+
return this;
80+
}
81+
5782
/**
5883
* Returns a new {@link OpenTelemetryMeterRegistry} with the settings of this {@link
5984
* OpenTelemetryMeterRegistryBuilder}.
@@ -63,11 +88,16 @@ public MeterRegistry build() {
6388
TimeUnit baseTimeUnit = prometheusMode ? TimeUnit.SECONDS : this.baseTimeUnit;
6489
NamingConvention namingConvention =
6590
prometheusMode ? PrometheusModeNamingConvention.INSTANCE : NamingConvention.identity;
91+
DistributionStatisticConfigModifier modifier =
92+
histogramGaugesEnabled
93+
? DistributionStatisticConfigModifier.IDENTITY
94+
: DistributionStatisticConfigModifier.DISABLE_HISTOGRAM_GAUGES;
6695

6796
return new OpenTelemetryMeterRegistry(
6897
clock,
6998
baseTimeUnit,
7099
namingConvention,
100+
modifier,
71101
openTelemetry.getMeterProvider().get(INSTRUMENTATION_NAME));
72102
}
73103
}

instrumentation/micrometer/micrometer-1.5/library/src/main/java/io/opentelemetry/instrumentation/micrometer/v1_5/OpenTelemetryTimer.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,17 @@ final class OpenTelemetryTimer extends AbstractTimer implements RemovableMeter {
4545
NamingConvention namingConvention,
4646
Clock clock,
4747
DistributionStatisticConfig distributionStatisticConfig,
48+
DistributionStatisticConfigModifier modifier,
4849
PauseDetector pauseDetector,
4950
TimeUnit baseTimeUnit,
5051
Meter otelMeter) {
51-
super(id, clock, distributionStatisticConfig, pauseDetector, TimeUnit.MILLISECONDS, false);
52+
super(
53+
id,
54+
clock,
55+
modifier.modify(distributionStatisticConfig),
56+
pauseDetector,
57+
baseTimeUnit,
58+
false);
5259

5360
if (isUsingMicrometerHistograms()) {
5461
measurements = new MicrometerHistogramMeasurements();

0 commit comments

Comments
 (0)