Skip to content

Commit eff8a61

Browse files
Merge branch '1.13.x'
2 parents b078704 + 77d72d2 commit eff8a61

File tree

3 files changed

+52
-6
lines changed

3 files changed

+52
-6
lines changed

implementations/micrometer-registry-otlp/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ dependencies {
1010
testImplementation 'io.rest-assured:rest-assured'
1111
testImplementation 'org.testcontainers:junit-jupiter'
1212
testImplementation 'org.awaitility:awaitility'
13+
testImplementation libs.mockitoCore5
1314
}
1415

1516
dockerTest {

implementations/micrometer-registry-otlp/src/main/java/io/micrometer/registry/otlp/OtlpMeterRegistry.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ public class OtlpMeterRegistry extends PushMeterRegistry {
9191

9292
private final TimeUnit baseTimeUnit;
9393

94+
private final String userAgentHeader;
95+
9496
// Time when the last scheduled rollOver has started. Applicable only for delta
9597
// flavour.
9698
private volatile long lastMeterRolloverStartTime = -1;
@@ -117,15 +119,17 @@ public OtlpMeterRegistry(OtlpConfig config, Clock clock, ThreadFactory threadFac
117119
this(config, clock, threadFactory, new HttpUrlConnectionSender());
118120
}
119121

122+
// VisibleForTesting
120123
// not public until we decide what we want to expose in public API
121124
// HttpSender may not be a good idea if we will support a non-HTTP transport
122-
private OtlpMeterRegistry(OtlpConfig config, Clock clock, ThreadFactory threadFactory, HttpSender httpSender) {
125+
OtlpMeterRegistry(OtlpConfig config, Clock clock, ThreadFactory threadFactory, HttpSender httpSender) {
123126
super(config, clock);
124127
this.config = config;
125128
this.baseTimeUnit = config.baseTimeUnit();
126129
this.httpSender = httpSender;
127130
this.resource = Resource.newBuilder().addAllAttributes(getResourceAttributes()).build();
128131
this.aggregationTemporality = config.aggregationTemporality();
132+
this.userAgentHeader = getUserAgentHeader();
129133
config().namingConvention(NamingConvention.dot);
130134
start(threadFactory);
131135
}
@@ -175,6 +179,7 @@ protected void publish() {
175179
.build())
176180
.build();
177181
HttpSender.Request.Builder httpRequest = this.httpSender.post(this.config.url())
182+
.withHeader("User-Agent", this.userAgentHeader)
178183
.withContent("application/x-protobuf", request.toByteArray());
179184
this.config.headers().forEach(httpRequest::withHeader);
180185
HttpSender.Response response = httpRequest.send();
@@ -487,4 +492,11 @@ static double[] getSloWithPositiveInf(DistributionStatisticConfig distributionSt
487492
return sloWithPositiveInf;
488493
}
489494

495+
private String getUserAgentHeader() {
496+
if (this.getClass().getPackage().getImplementationVersion() == null) {
497+
return "Micrometer-OTLP-Exporter-Java";
498+
}
499+
return "Micrometer-OTLP-Exporter-Java/" + this.getClass().getPackage().getImplementationVersion();
500+
}
501+
490502
}

implementations/micrometer-registry-otlp/src/test/java/io/micrometer/registry/otlp/OtlpMeterRegistryTest.java

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@
1515
*/
1616
package io.micrometer.registry.otlp;
1717

18-
import io.micrometer.core.instrument.*;
18+
import io.micrometer.core.Issue;
1919
import io.micrometer.core.instrument.Timer;
20+
import io.micrometer.core.instrument.*;
2021
import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;
21-
import io.micrometer.core.instrument.Timer;
22+
import io.micrometer.core.instrument.util.NamedThreadFactory;
23+
import io.micrometer.core.ipc.http.HttpSender;
2224
import io.opentelemetry.proto.metrics.v1.ExponentialHistogramDataPoint;
2325
import io.opentelemetry.proto.metrics.v1.HistogramDataPoint;
2426
import io.opentelemetry.proto.metrics.v1.Metric;
2527
import io.opentelemetry.proto.metrics.v1.NumberDataPoint;
28+
import org.junit.jupiter.api.BeforeEach;
2629
import org.junit.jupiter.api.Test;
2730

2831
import java.io.IOException;
@@ -31,6 +34,8 @@
3134
import java.util.concurrent.TimeUnit;
3235

3336
import static org.assertj.core.api.Assertions.assertThat;
37+
import static org.mockito.ArgumentMatchers.assertArg;
38+
import static org.mockito.Mockito.*;
3439
import static uk.org.webcompere.systemstubs.SystemStubs.withEnvironmentVariables;
3540

3641
/**
@@ -47,16 +52,27 @@ abstract class OtlpMeterRegistryTest {
4752

4853
protected static final Tag meterTag = Tag.of("key", "value");
4954

50-
protected MockClock clock = new MockClock();
55+
protected MockClock clock;
5156

52-
OtlpMeterRegistry registry = new OtlpMeterRegistry(otlpConfig(), clock);
57+
private HttpSender mockHttpSender;
5358

54-
OtlpMeterRegistry registryWithExponentialHistogram = new OtlpMeterRegistry(exponentialHistogramOtlpConfig(), clock);
59+
OtlpMeterRegistry registry;
60+
61+
OtlpMeterRegistry registryWithExponentialHistogram;
5562

5663
abstract OtlpConfig otlpConfig();
5764

5865
abstract OtlpConfig exponentialHistogramOtlpConfig();
5966

67+
@BeforeEach
68+
void setUp() {
69+
this.clock = new MockClock();
70+
this.mockHttpSender = mock(HttpSender.class);
71+
this.registry = new OtlpMeterRegistry(otlpConfig(), this.clock,
72+
new NamedThreadFactory("otlp-metrics-publisher"), this.mockHttpSender);
73+
this.registryWithExponentialHistogram = new OtlpMeterRegistry(exponentialHistogramOtlpConfig(), clock);
74+
}
75+
6076
// If the service.name was not specified, SDKs MUST fallback to 'unknown_service'
6177
@Test
6278
void unknownServiceByDefault() {
@@ -129,6 +145,23 @@ void timeGauge() {
129145
+ " time_unix_nano: 1000000\n" + " as_double: 0.024\n" + " }\n" + "}\n");
130146
}
131147

148+
@Issue("#5577")
149+
@Test
150+
void httpHeaders() throws Throwable {
151+
HttpSender.Request.Builder builder = HttpSender.Request.build(otlpConfig().url(), this.mockHttpSender);
152+
when(mockHttpSender.post(otlpConfig().url())).thenReturn(builder);
153+
154+
when(mockHttpSender.send(isA(HttpSender.Request.class))).thenReturn(new HttpSender.Response(200, ""));
155+
156+
writeToMetric(TimeGauge.builder("gauge.time", this, TimeUnit.MICROSECONDS, o -> 24).register(registry));
157+
registry.publish();
158+
159+
verify(this.mockHttpSender).send(assertArg(request -> {
160+
assertThat(request.getRequestHeaders().get("User-Agent")).startsWith("Micrometer-OTLP-Exporter-Java");
161+
assertThat(request.getRequestHeaders()).containsEntry("Content-Type", "application/x-protobuf");
162+
}));
163+
}
164+
132165
@Test
133166
void distributionWithPercentileShouldWriteSummary() {
134167
Timer.Builder timer = Timer.builder("timer")

0 commit comments

Comments
 (0)