Skip to content

Commit

Permalink
add support for OTEL_EXPORTER_OTLP_PROTOCOL for spring boot starter
Browse files Browse the repository at this point in the history
  • Loading branch information
zeitlinger committed Nov 27, 2023
1 parent 4bb39c7 commit 9c3e374
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public final class OtlpExporterProperties {
private boolean enabled = true;
@Nullable private String endpoint;

@Nullable private String protocol;

private final Map<String, String> headers = new HashMap<>();

@Nullable private Duration timeout;
Expand All @@ -51,6 +53,15 @@ public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}

@Nullable
public String getProtocol() {
return protocol;
}

public void setProtocol(@Nullable String protocol) {
this.protocol = protocol;
}

public Map<String, String> getHeaders() {
return headers;
}
Expand Down Expand Up @@ -81,6 +92,8 @@ public static class SignalProperties {
private boolean enabled = true;
@Nullable private String endpoint;

@Nullable private String protocol;

private final Map<String, String> headers = new HashMap<>();

@Nullable private Duration timeout;
Expand All @@ -102,6 +115,15 @@ public void setEndpoint(@Nullable String endpoint) {
this.endpoint = endpoint;
}

@Nullable
public String getProtocol() {
return protocol;
}

public void setProtocol(@Nullable String protocol) {
this.protocol = protocol;
}

public Map<String, String> getHeaders() {
return headers;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,101 @@

package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp;

import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil;
import java.time.Duration;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

class OtlpExporterUtil {
private OtlpExporterUtil() {}

static void applySignalProperties(
static <GrpcBuilder, HttpBuilder, Exporter> Exporter applySignalProperties(
String dataType,
OtlpExporterProperties properties,
OtlpExporterProperties.SignalProperties signalProperties,
Consumer<String> setEndpoint,
BiConsumer<String, String> addHeader,
Consumer<Duration> setTimeout) {
String endpoint = properties.getLogs().getEndpoint();
Supplier<GrpcBuilder> newGrpcBuilder,
Supplier<HttpBuilder> newHttpBuilder,
BiConsumer<GrpcBuilder, String> setGrpcEndpoint,
BiConsumer<HttpBuilder, String> setHttpEndpoint,
BiConsumer<GrpcBuilder, Map.Entry<String, String>> addGrpcHeader,
BiConsumer<HttpBuilder, Map.Entry<String, String>> addHttpHeader,
BiConsumer<GrpcBuilder, Duration> setGrpcTimeout,
BiConsumer<HttpBuilder, Duration> setHttpTimeout,
Function<GrpcBuilder, Exporter> buildGrpcExporter,
Function<HttpBuilder, Exporter> buildHttpExporter) {

String protocol = signalProperties.getProtocol();
if (protocol == null) {
protocol = properties.getProtocol();
}

GrpcBuilder grpcBuilder = newGrpcBuilder.get();
HttpBuilder httpBuilder = newHttpBuilder.get();

boolean isHttpProtobuf = Objects.equals(protocol, OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF);

String endpoint = signalProperties.getEndpoint();
if (endpoint == null) {
endpoint = properties.getEndpoint();
}
if (endpoint != null) {
setEndpoint.accept(endpoint);
if (isHttpProtobuf) {
if (!endpoint.endsWith("/")) {
endpoint += "/";
}
endpoint += signalPath(dataType);
}

if (isHttpProtobuf) {
setHttpEndpoint.accept(httpBuilder, endpoint);
} else {
setGrpcEndpoint.accept(grpcBuilder, endpoint);
}
}

Map<String, String> headers = signalProperties.getHeaders();
if (headers.isEmpty()) {
headers = properties.getHeaders();
}
headers.forEach(addHeader);
for (Map.Entry<String, String> entry : headers.entrySet()) {
if (isHttpProtobuf) {
addHttpHeader.accept(httpBuilder, entry);
} else {
addGrpcHeader.accept(grpcBuilder, entry);
}
}

Duration timeout = signalProperties.getTimeout();
if (timeout == null) {
timeout = properties.getTimeout();
}
if (timeout != null) {
setTimeout.accept(timeout);
if (isHttpProtobuf) {
setHttpTimeout.accept(httpBuilder, timeout);
} else {
setGrpcTimeout.accept(grpcBuilder, timeout);
}
}

return isHttpProtobuf
? buildHttpExporter.apply(httpBuilder)
: buildGrpcExporter.apply(grpcBuilder);
}

private static String signalPath(String dataType) {
switch (dataType) {
case OtlpConfigUtil.DATA_TYPE_METRICS:
return "v1/metrics";
case OtlpConfigUtil.DATA_TYPE_TRACES:
return "v1/traces";
case OtlpConfigUtil.DATA_TYPE_LOGS:
return "v1/logs";
default:
throw new IllegalArgumentException(
"Cannot determine signal path for unrecognized data type: " + dataType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@

package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp;

import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder;
import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil;
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter;
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder;
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
Expand All @@ -26,17 +30,25 @@ public class OtlpLoggerExporterAutoConfiguration {

@Bean
@ConditionalOnMissingBean
public OtlpGrpcLogRecordExporter otelOtlpGrpcLogRecordExporter(
OtlpExporterProperties properties) {
OtlpGrpcLogRecordExporterBuilder builder = OtlpGrpcLogRecordExporter.builder();
public LogRecordExporter otelOtlpGrpcLogRecordExporter(OtlpExporterProperties properties) {

OtlpExporterUtil.applySignalProperties(
return OtlpExporterUtil.applySignalProperties(
OtlpConfigUtil.DATA_TYPE_LOGS,
properties,
properties.getLogs(),
builder::setEndpoint,
builder::addHeader,
builder::setTimeout);

return builder.build();
OtlpGrpcLogRecordExporter::builder,
OtlpHttpLogRecordExporter::builder,
OtlpGrpcLogRecordExporterBuilder::setEndpoint,
OtlpHttpLogRecordExporterBuilder::setEndpoint,
(builder, entry) -> {
builder.addHeader(entry.getKey(), entry.getValue());
},
(builder, entry) -> {
builder.addHeader(entry.getKey(), entry.getValue());
},
OtlpGrpcLogRecordExporterBuilder::setTimeout,
OtlpHttpLogRecordExporterBuilder::setTimeout,
OtlpGrpcLogRecordExporterBuilder::build,
OtlpHttpLogRecordExporterBuilder::build);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@

package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp;

import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder;
import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder;
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
Expand All @@ -28,16 +32,24 @@ public class OtlpMetricExporterAutoConfiguration {

@Bean
@ConditionalOnMissingBean
public OtlpGrpcMetricExporter otelOtlpGrpcMetricExporter(OtlpExporterProperties properties) {
OtlpGrpcMetricExporterBuilder builder = OtlpGrpcMetricExporter.builder();

OtlpExporterUtil.applySignalProperties(
public MetricExporter otelOtlpGrpcMetricExporter(OtlpExporterProperties properties) {
return OtlpExporterUtil.applySignalProperties(
OtlpConfigUtil.DATA_TYPE_METRICS,
properties,
properties.getMetrics(),
builder::setEndpoint,
builder::addHeader,
builder::setTimeout);

return builder.build();
properties.getLogs(),
OtlpGrpcMetricExporter::builder,
OtlpHttpMetricExporter::builder,
OtlpGrpcMetricExporterBuilder::setEndpoint,
OtlpHttpMetricExporterBuilder::setEndpoint,
(builder, entry) -> {
builder.addHeader(entry.getKey(), entry.getValue());
},
(builder, entry) -> {
builder.addHeader(entry.getKey(), entry.getValue());
},
OtlpGrpcMetricExporterBuilder::setTimeout,
OtlpHttpMetricExporterBuilder::setTimeout,
OtlpGrpcMetricExporterBuilder::build,
OtlpHttpMetricExporterBuilder::build);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@

package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp;

import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder;
import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder;
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
Expand All @@ -33,16 +37,24 @@ public class OtlpSpanExporterAutoConfiguration {

@Bean
@ConditionalOnMissingBean
public OtlpGrpcSpanExporter otelOtlpGrpcSpanExporter(OtlpExporterProperties properties) {
OtlpGrpcSpanExporterBuilder builder = OtlpGrpcSpanExporter.builder();

OtlpExporterUtil.applySignalProperties(
public SpanExporter otelOtlpGrpcSpanExporter(OtlpExporterProperties properties) {
return OtlpExporterUtil.applySignalProperties(
OtlpConfigUtil.DATA_TYPE_TRACES,
properties,
properties.getTraces(),
builder::setEndpoint,
builder::addHeader,
builder::setTimeout);

return builder.build();
properties.getLogs(),
OtlpGrpcSpanExporter::builder,
OtlpHttpSpanExporter::builder,
OtlpGrpcSpanExporterBuilder::setEndpoint,
OtlpHttpSpanExporterBuilder::setEndpoint,
(builder, entry) -> {
builder.addHeader(entry.getKey(), entry.getValue());
},
(builder, entry) -> {
builder.addHeader(entry.getKey(), entry.getValue());
},
OtlpGrpcSpanExporterBuilder::setTimeout,
OtlpHttpSpanExporterBuilder::setTimeout,
OtlpGrpcSpanExporterBuilder::build,
OtlpHttpSpanExporterBuilder::build);
}
}

0 comments on commit 9c3e374

Please sign in to comment.