Skip to content

Commit

Permalink
Set user agent header in OTLP registry
Browse files Browse the repository at this point in the history
Co-authored-by: Joao Grassi <5938087+joaopgrassi@users.noreply.github.com>
Co-authored-by: Jonatan Ivanov <jonatan.ivanov@gmail.com>
  • Loading branch information
jonatan-ivanov and joaopgrassi committed Oct 11, 2024
1 parent adfdd3e commit d7daaef
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 3 deletions.
1 change: 1 addition & 0 deletions implementations/micrometer-registry-otlp/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ dependencies {
testImplementation 'io.rest-assured:rest-assured'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.awaitility:awaitility'
testImplementation libs.mockitoCore5
}

dockerTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ public class OtlpMeterRegistry extends PushMeterRegistry {

private long deltaAggregationTimeUnixNano = 0L;

private final String userAgentHeader;

// Time when the last scheduled rollOver has started. Applicable only for delta
// flavour.
private volatile long lastMeterRolloverStartTime = -1;
Expand All @@ -104,9 +106,10 @@ public OtlpMeterRegistry(OtlpConfig config, Clock clock) {
this(config, clock, new HttpUrlConnectionSender());
}

// VisibleForTesting
// not public until we decide what we want to expose in public API
// HttpSender may not be a good idea if we will support a non-HTTP transport
private OtlpMeterRegistry(OtlpConfig config, Clock clock, HttpSender httpSender) {
OtlpMeterRegistry(OtlpConfig config, Clock clock, HttpSender httpSender) {
super(config, clock);
this.config = config;
this.baseTimeUnit = config.baseTimeUnit();
Expand All @@ -115,6 +118,7 @@ private OtlpMeterRegistry(OtlpConfig config, Clock clock, HttpSender httpSender)
this.otlpAggregationTemporality = AggregationTemporality
.toOtlpAggregationTemporality(config.aggregationTemporality());
setDeltaAggregationTimeUnixNano();
this.userAgentHeader = getUserAgentHeader();
config().namingConvention(NamingConvention.dot);
start(DEFAULT_THREAD_FACTORY);
}
Expand Down Expand Up @@ -163,6 +167,7 @@ protected void publish() {
.build())
.build();
HttpSender.Request.Builder httpRequest = this.httpSender.post(this.config.url())
.withHeader("User-Agent", this.userAgentHeader)
.withContent("application/x-protobuf", request.toByteArray());
this.config.headers().forEach(httpRequest::withHeader);
HttpSender.Response response = httpRequest.send();
Expand Down Expand Up @@ -572,4 +577,11 @@ static double[] getSloWithPositiveInf(DistributionStatisticConfig distributionSt
return sloWithPositiveInf;
}

private String getUserAgentHeader() {
if (this.getClass().getPackage().getImplementationVersion() == null) {
return "Micrometer-OTLP-Exporter-Java";
}
return "Micrometer-OTLP-Exporter-Java/" + this.getClass().getPackage().getImplementationVersion();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
*/
package io.micrometer.registry.otlp;

import io.micrometer.core.Issue;
import io.micrometer.core.instrument.*;
import io.micrometer.core.instrument.config.NamingConvention;
import io.micrometer.core.instrument.distribution.DistributionStatisticConfig;
import io.micrometer.core.ipc.http.HttpSender;
import io.opentelemetry.proto.metrics.v1.HistogramDataPoint;
import io.opentelemetry.proto.metrics.v1.Metric;
import io.opentelemetry.proto.metrics.v1.NumberDataPoint;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;
Expand All @@ -31,6 +34,8 @@
import java.util.concurrent.TimeUnit;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.assertArg;
import static org.mockito.Mockito.*;
import static uk.org.webcompere.systemstubs.SystemStubs.withEnvironmentVariables;

/**
Expand All @@ -47,12 +52,21 @@ abstract class OtlpMeterRegistryTest {

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

protected MockClock clock = new MockClock();
protected MockClock clock;

protected OtlpMeterRegistry registry = new OtlpMeterRegistry(otlpConfig(), clock);
protected OtlpMeterRegistry registry;

private HttpSender mockHttpSender;

abstract OtlpConfig otlpConfig();

@BeforeEach
void setUp() {
this.clock = new MockClock();
this.mockHttpSender = mock(HttpSender.class);
this.registry = new OtlpMeterRegistry(otlpConfig(), this.clock, this.mockHttpSender);
}

// If the service.name was not specified, SDKs MUST fallback to 'unknown_service'
@Test
void unknownServiceByDefault() {
Expand Down Expand Up @@ -106,6 +120,23 @@ void timeGauge() {
+ " time_unix_nano: 1000000\n" + " as_double: 0.024\n" + " }\n" + "}\n");
}

@Issue("#5577")
@Test
void httpHeaders() throws Throwable {
HttpSender.Request.Builder builder = HttpSender.Request.build(otlpConfig().url(), this.mockHttpSender);
when(mockHttpSender.post(otlpConfig().url())).thenReturn(builder);

when(mockHttpSender.send(isA(HttpSender.Request.class))).thenReturn(new HttpSender.Response(200, ""));

writeToMetric(TimeGauge.builder("gauge.time", this, TimeUnit.MICROSECONDS, o -> 24).register(registry));
registry.publish();

verify(this.mockHttpSender).send(assertArg(request -> {
assertThat(request.getRequestHeaders().get("User-Agent")).startsWith("Micrometer-OTLP-Exporter-Java");
assertThat(request.getRequestHeaders()).containsEntry("Content-Type", "application/x-protobuf");
}));
}

@Test
void distributionWithPercentileShouldWriteSummary() {
Timer timer = Timer.builder("timer")
Expand Down

0 comments on commit d7daaef

Please sign in to comment.