Skip to content

Commit

Permalink
Implement otlp exporter providers (#5003)
Browse files Browse the repository at this point in the history
* Implement otlp exporter providers

* Remove redundant else

* Restore unsupported protocol test
  • Loading branch information
jack-berg authored Dec 18, 2022
1 parent ece93b7 commit 5b497b1
Show file tree
Hide file tree
Showing 30 changed files with 607 additions and 556 deletions.
1 change: 1 addition & 0 deletions exporters/otlp/all/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ dependencies {
api(project(":sdk:metrics"))

implementation(project(":exporters:otlp:common"))
implementation(project(":sdk-extensions:autoconfigure-spi"))

compileOnly("io.grpc:grpc-stub")

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.exporter.otlp.internal;

import static io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil.DATA_TYPE_METRICS;
import static io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil.PROTOCOL_GRPC;
import static io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF;

import io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil;
import io.opentelemetry.exporter.internal.retry.RetryUtil;
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider;
import io.opentelemetry.sdk.metrics.export.MetricExporter;

/**
* {@link MetricExporter} SPI implementation for {@link OtlpGrpcMetricExporter} and {@link
* OtlpHttpMetricExporter}.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public class OtlpMetricExporterProvider implements ConfigurableMetricExporterProvider {
@Override
public MetricExporter createExporter(ConfigProperties config) {
String protocol = OtlpConfigUtil.getOtlpProtocol(DATA_TYPE_METRICS, config);

if (protocol.equals(PROTOCOL_HTTP_PROTOBUF)) {
OtlpHttpMetricExporterBuilder builder = OtlpHttpMetricExporter.builder();

OtlpConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_METRICS,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
retryPolicy -> RetryUtil.setRetryPolicyOnDelegate(builder, retryPolicy));
OtlpConfigUtil.configureOtlpAggregationTemporality(
config, builder::setAggregationTemporalitySelector);
OtlpConfigUtil.configureOtlpHistogramDefaultAggregation(
config, builder::setDefaultAggregationSelector);

return builder.build();
} else if (protocol.equals(PROTOCOL_GRPC)) {
OtlpGrpcMetricExporterBuilder builder = OtlpGrpcMetricExporter.builder();

OtlpConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_METRICS,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
retryPolicy -> RetryUtil.setRetryPolicyOnDelegate(builder, retryPolicy));
OtlpConfigUtil.configureOtlpAggregationTemporality(
config, builder::setAggregationTemporalitySelector);
OtlpConfigUtil.configureOtlpHistogramDefaultAggregation(
config, builder::setDefaultAggregationSelector);

return builder.build();
}
throw new ConfigurationException("Unsupported OTLP metrics protocol: " + protocol);
}

@Override
public String getName() {
return "otlp";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.exporter.otlp.internal;

import static io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil.DATA_TYPE_TRACES;
import static io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil.PROTOCOL_GRPC;
import static io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF;

import io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil;
import io.opentelemetry.exporter.internal.retry.RetryUtil;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider;
import io.opentelemetry.sdk.trace.export.SpanExporter;

/**
* {@link SpanExporter} SPI implementation for {@link OtlpGrpcSpanExporter} and {@link
* OtlpHttpSpanExporter}.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public class OtlpSpanExporterProvider implements ConfigurableSpanExporterProvider {
@Override
public SpanExporter createExporter(ConfigProperties config) {
String protocol = OtlpConfigUtil.getOtlpProtocol(DATA_TYPE_TRACES, config);
if (protocol.equals(PROTOCOL_HTTP_PROTOBUF)) {
OtlpHttpSpanExporterBuilder builder = OtlpHttpSpanExporter.builder();

OtlpConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_TRACES,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
retryPolicy -> RetryUtil.setRetryPolicyOnDelegate(builder, retryPolicy));

return builder.build();
} else if (protocol.equals(PROTOCOL_GRPC)) {
OtlpGrpcSpanExporterBuilder builder = OtlpGrpcSpanExporter.builder();

OtlpConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_TRACES,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
retryPolicy -> RetryUtil.setRetryPolicyOnDelegate(builder, retryPolicy));

return builder.build();
}
throw new ConfigurationException("Unsupported OTLP traces protocol: " + protocol);
}

@Override
public String getName() {
return "otlp";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.opentelemetry.exporter.otlp.internal.OtlpMetricExporterProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.opentelemetry.exporter.otlp.internal.OtlpSpanExporterProvider
2 changes: 2 additions & 0 deletions exporters/otlp/common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ dependencies {

api(project(":exporters:common"))

implementation(project(":sdk-extensions:autoconfigure-spi"))

compileOnly(project(":sdk:metrics"))
compileOnly(project(":sdk:trace"))
compileOnly(project(":sdk:logs"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.autoconfigure;
package io.opentelemetry.exporter.internal.otlp;

import io.opentelemetry.exporter.internal.retry.RetryPolicy;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
Expand All @@ -13,36 +13,41 @@
import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector;
import io.opentelemetry.sdk.metrics.export.DefaultAggregationSelector;
import io.opentelemetry.sdk.metrics.internal.view.ExponentialHistogramAggregation;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import javax.annotation.Nullable;

final class OtlpConfigUtil {
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class OtlpConfigUtil {

static final String DATA_TYPE_TRACES = "traces";
static final String DATA_TYPE_METRICS = "metrics";
static final String DATA_TYPE_LOGS = "logs";
public static final String DATA_TYPE_TRACES = "traces";
public static final String DATA_TYPE_METRICS = "metrics";
public static final String DATA_TYPE_LOGS = "logs";

static final String PROTOCOL_GRPC = "grpc";
static final String PROTOCOL_HTTP_PROTOBUF = "http/protobuf";
public static final String PROTOCOL_GRPC = "grpc";
public static final String PROTOCOL_HTTP_PROTOBUF = "http/protobuf";

static String getOtlpProtocol(String dataType, ConfigProperties config) {
/** Determine the configured OTLP protocol for the {@code dataType}. */
public static String getOtlpProtocol(String dataType, ConfigProperties config) {
String protocol = config.getString("otel.exporter.otlp." + dataType + ".protocol");
if (protocol != null) {
return protocol;
}
return config.getString("otel.exporter.otlp.protocol", PROTOCOL_GRPC);
}

static void configureOtlpExporterBuilder(
/** Invoke the setters with the OTLP configuration for the {@code dataType}. */
public static void configureOtlpExporterBuilder(
String dataType,
ConfigProperties config,
Consumer<String> setEndpoint,
Expand Down Expand Up @@ -133,7 +138,11 @@ static void configureOtlpExporterBuilder(
}
}

static void configureOtlpAggregationTemporality(
/**
* Invoke the {@code aggregationTemporalitySelectorConsumer} with the configured {@link
* AggregationTemporality}.
*/
public static void configureOtlpAggregationTemporality(
ConfigProperties config,
Consumer<AggregationTemporalitySelector> aggregationTemporalitySelectorConsumer) {
String temporalityStr = config.getString("otel.exporter.otlp.metrics.temporality.preference");
Expand All @@ -154,7 +163,11 @@ static void configureOtlpAggregationTemporality(
aggregationTemporalitySelectorConsumer.accept(temporalitySelector);
}

static void configureOtlpHistogramDefaultAggregation(
/**
* Invoke the {@code defaultAggregationSelectorConsumer} with the configured {@link
* DefaultAggregationSelector}.
*/
public static void configureOtlpHistogramDefaultAggregation(
ConfigProperties config,
Consumer<DefaultAggregationSelector> defaultAggregationSelectorConsumer) {
String defaultHistogramAggregation =
Expand Down Expand Up @@ -215,14 +228,17 @@ private static byte[] readFileBytes(@Nullable String filePath) {
if (filePath == null) {
return null;
}
Path path = Paths.get(filePath);
if (!Files.exists(path)) {
throw new ConfigurationException("Invalid OTLP certificate/key path: " + path);
File file = new File(filePath);
if (!file.exists()) {
throw new ConfigurationException("Invalid OTLP certificate/key path: " + filePath);
}
try {
return Files.readAllBytes(path);
RandomAccessFile raf = new RandomAccessFile(file, "r");
byte[] bytes = new byte[(int) raf.length()];
raf.readFully(bytes);
return bytes;
} catch (IOException e) {
throw new ConfigurationException("Error reading content of file (" + path + ")", e);
throw new ConfigurationException("Error reading content of file (" + filePath + ")", e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.autoconfigure;
package io.opentelemetry.exporter.internal.otlp;

import static io.opentelemetry.sdk.autoconfigure.OtlpConfigUtil.DATA_TYPE_LOGS;
import static io.opentelemetry.sdk.autoconfigure.OtlpConfigUtil.DATA_TYPE_METRICS;
import static io.opentelemetry.sdk.autoconfigure.OtlpConfigUtil.DATA_TYPE_TRACES;
import static io.opentelemetry.sdk.autoconfigure.OtlpConfigUtil.PROTOCOL_GRPC;
import static io.opentelemetry.sdk.autoconfigure.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF;
import static org.assertj.core.api.Assertions.assertThat;
import static io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil.DATA_TYPE_LOGS;
import static io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil.DATA_TYPE_METRICS;
import static io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil.DATA_TYPE_TRACES;
import static io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil.PROTOCOL_GRPC;
import static io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

Expand Down
1 change: 1 addition & 0 deletions exporters/otlp/logs/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ dependencies {
api(project(":sdk:logs"))

implementation(project(":exporters:otlp:common"))
implementation(project(":sdk-extensions:autoconfigure-spi"))

compileOnly("io.grpc:grpc-stub")

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.exporter.otlp.internal;

import static io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil.DATA_TYPE_LOGS;
import static io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil.PROTOCOL_GRPC;
import static io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF;

import io.opentelemetry.exporter.internal.otlp.OtlpConfigUtil;
import io.opentelemetry.exporter.internal.retry.RetryUtil;
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder;
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter;
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider;
import io.opentelemetry.sdk.logs.export.LogRecordExporter;

/**
* {@link LogRecordExporter} SPI implementation for {@link OtlpGrpcLogRecordExporter} and {@link
* OtlpHttpLogRecordExporter}.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public class OtlpLogRecordExporterProvider implements ConfigurableLogRecordExporterProvider {
@Override
public LogRecordExporter createExporter(ConfigProperties config) {
String protocol = OtlpConfigUtil.getOtlpProtocol(DATA_TYPE_LOGS, config);

if (protocol.equals(PROTOCOL_HTTP_PROTOBUF)) {
OtlpHttpLogRecordExporterBuilder builder = OtlpHttpLogRecordExporter.builder();

OtlpConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_LOGS,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
retryPolicy -> RetryUtil.setRetryPolicyOnDelegate(builder, retryPolicy));

return builder.build();
} else if (protocol.equals(PROTOCOL_GRPC)) {
OtlpGrpcLogRecordExporterBuilder builder = OtlpGrpcLogRecordExporter.builder();

OtlpConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_LOGS,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
retryPolicy -> RetryUtil.setRetryPolicyOnDelegate(builder, retryPolicy));

return builder.build();
}
throw new ConfigurationException("Unsupported OTLP logs protocol: " + protocol);
}

@Override
public String getName() {
return "otlp";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
io.opentelemetry.exporter.otlp.internal.OtlpLogRecordExporterProvider
Loading

0 comments on commit 5b497b1

Please sign in to comment.