Skip to content

Commit df32a06

Browse files
committed
Further enhancement to OtlpMetricsSender
Introduces an immutable Request object and builder.
1 parent 8db4d6e commit df32a06

File tree

5 files changed

+124
-63
lines changed

5 files changed

+124
-63
lines changed

docs/src/test/java/io/micrometer/docs/metrics/OtlpMeterRegistryCustomizationTest.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
import io.micrometer.registry.otlp.OtlpMetricsSender;
2424
import org.junit.jupiter.api.Test;
2525

26-
import java.util.Map;
27-
2826
class OtlpMeterRegistryCustomizationTest {
2927

3028
@Test
@@ -49,7 +47,7 @@ void customizeOtlpSender() {
4947
private static class OtlpGrpcMetricsSender implements OtlpMetricsSender {
5048

5149
@Override
52-
public void send(String address, byte[] metricsData, Map<String, String> headers) {
50+
public void send(Request request) {
5351
}
5452

5553
}

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

Lines changed: 0 additions & 35 deletions
This file was deleted.

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

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

18-
import io.micrometer.common.util.internal.logging.InternalLogger;
19-
import io.micrometer.common.util.internal.logging.InternalLoggerFactory;
2018
import io.micrometer.core.ipc.http.HttpSender;
2119

22-
import java.util.Map;
23-
2420
/**
2521
* An implementation of {@link OtlpMetricsSender} that uses an {@link HttpSender}.
2622
*
2723
* @since 1.15.0
2824
*/
2925
public class OtlpHttpMetricsSender implements OtlpMetricsSender {
3026

31-
private static final InternalLogger logger = InternalLoggerFactory.getInstance(OtlpHttpMetricsSender.class);
32-
3327
private final HttpSender httpSender;
3428

3529
private final String userAgentHeader;
@@ -41,19 +35,23 @@ public OtlpHttpMetricsSender(HttpSender httpSender) {
4135

4236
/**
4337
* Send a batch of OTLP Protobuf format metrics to an OTLP HTTP receiver.
44-
* @param address address of the OTLP HTTP receiver to which metrics will be sent
45-
* @param metricsData OTLP protobuf encoded batch of metrics
46-
* @param headers metadata to send as headers with the metrics data
47-
* @throws Throwable when there is an exception in sending the metrics; the caller
38+
* @param request metrics request to publish
39+
* @throws Exception when there is an exception in sending the metrics; the caller
4840
* should handle this in some way such as logging the exception
4941
*/
5042
@Override
51-
public void send(String address, byte[] metricsData, Map<String, String> headers) throws Throwable {
52-
HttpSender.Request.Builder httpRequest = this.httpSender.post(address)
43+
public void send(Request request) throws Exception {
44+
HttpSender.Request.Builder httpRequest = this.httpSender.post(request.getAddress())
5345
.withHeader("User-Agent", userAgentHeader)
54-
.withContent("application/x-protobuf", metricsData);
55-
headers.forEach(httpRequest::withHeader);
56-
HttpSender.Response response = httpRequest.send();
46+
.withContent("application/x-protobuf", request.getMetricsData());
47+
request.getHeaders().forEach(httpRequest::withHeader);
48+
HttpSender.Response response;
49+
try {
50+
response = httpRequest.send();
51+
}
52+
catch (Throwable e) {
53+
throw new Exception(e);
54+
}
5755
if (!response.isSuccessful()) {
5856
throw new OtlpHttpMetricsSendUnsuccessfulException(String
5957
.format("Server responded with HTTP status code %d and body %s", response.code(), response.body()));
@@ -71,7 +69,7 @@ private String getUserAgentHeader() {
7169

7270
private static class OtlpHttpMetricsSendUnsuccessfulException extends RuntimeException {
7371

74-
public OtlpHttpMetricsSendUnsuccessfulException(String message) {
72+
private OtlpHttpMetricsSendUnsuccessfulException(String message) {
7573
super(message);
7674
}
7775

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ protected void publish() {
181181
.build())
182182
.build();
183183

184-
metricsSender.send(config.url(), request.toByteArray(), config.headers());
184+
metricsSender.newRequest(request.toByteArray()).address(config.url()).headers(config.headers()).send();
185185
}
186-
catch (Throwable e) {
186+
catch (Exception e) {
187187
logger.warn(String.format("Failed to publish metrics to OTLP receiver (context: %s)",
188188
getConfigurationContext()), e);
189189
}

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

Lines changed: 107 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,125 @@
1515
*/
1616
package io.micrometer.registry.otlp;
1717

18+
import io.micrometer.common.lang.Nullable;
19+
20+
import java.nio.charset.StandardCharsets;
21+
import java.util.Collections;
1822
import java.util.Map;
23+
import java.util.Objects;
1924

2025
/**
2126
* This is responsible for sending OTLP format metrics to a compatible location. Specific
2227
* implementations can use different transports or clients for sending the metrics.
2328
*
2429
* @since 1.15.0
2530
*/
26-
public interface OtlpMetricsSender extends MetricsSender {
31+
public interface OtlpMetricsSender {
2732

2833
/**
2934
* Send a batch of OTLP Protobuf format metrics to an OTLP receiver.
30-
* @param address address of the OTLP receiver to which metrics will be sent
31-
* @param metricsData OTLP protobuf encoded batch of metrics
32-
* @param headers metadata to send as headers with the metrics data
33-
* @throws Throwable when there is an exception in sending the metrics; the caller
35+
* @param request metrics request to publish
36+
* @throws Exception when there is an exception in sending the metrics; the caller
3437
* should handle this in some way such as logging the exception
3538
*/
36-
@Override
37-
void send(String address, byte[] metricsData, Map<String, String> headers) throws Throwable;
39+
void send(Request request) throws Exception;
40+
41+
/**
42+
* Start building a request to use with this sender.
43+
* @param metricsData metrics data that will be sent
44+
* @return builder
45+
* @see Request.Builder#send
46+
*/
47+
default Request.Builder newRequest(byte[] metricsData) {
48+
return new Request.Builder(metricsData, this);
49+
}
50+
51+
/**
52+
* Immutable representation of a payload of metrics to use with a
53+
* {@link OtlpMetricsSender}.
54+
*
55+
* @since 1.15.0
56+
*/
57+
class Request {
58+
59+
@Nullable
60+
private final String address;
61+
62+
private final Map<String, String> headers;
63+
64+
private final byte[] metricsData;
65+
66+
/**
67+
* Represents a payload of metrics to be sent.
68+
* @param address where to send the metrics
69+
* @param metricsData encoded batch of metrics
70+
* @param headers metadata to send as headers with the metrics data
71+
*/
72+
private Request(@Nullable String address, Map<String, String> headers, byte[] metricsData) {
73+
this.address = address;
74+
this.headers = headers;
75+
this.metricsData = metricsData;
76+
}
77+
78+
@Nullable
79+
public String getAddress() {
80+
return address;
81+
}
82+
83+
public byte[] getMetricsData() {
84+
return metricsData;
85+
}
86+
87+
public Map<String, String> getHeaders() {
88+
return headers;
89+
}
90+
91+
@Override
92+
public String toString() {
93+
return "OtlpMetricsSender.Request for address: " + address + ", headers: " + headers + ", metricsData: "
94+
+ new String(metricsData, StandardCharsets.UTF_8);
95+
}
96+
97+
public static class Builder {
98+
99+
private final byte[] metricsData;
100+
101+
private final OtlpMetricsSender sender;
102+
103+
@Nullable
104+
private String address;
105+
106+
private Map<String, String> headers = Collections.emptyMap();
107+
108+
private Builder(byte[] metricsData, OtlpMetricsSender sender) {
109+
this.metricsData = Objects.requireNonNull(metricsData);
110+
this.sender = sender;
111+
}
112+
113+
public Builder address(String address) {
114+
this.address = address;
115+
return this;
116+
}
117+
118+
public Builder headers(Map<String, String> headers) {
119+
this.headers = headers;
120+
return this;
121+
}
122+
123+
public Request build() {
124+
return new Request(address, headers, metricsData);
125+
}
126+
127+
/**
128+
* Build this request and send it to the associated sender.
129+
* @throws Exception when sending the request fails, an exception is thrown
130+
*/
131+
public void send() throws Exception {
132+
sender.send(build());
133+
}
134+
135+
}
136+
137+
}
38138

39139
}

0 commit comments

Comments
 (0)