Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public void customize(DeclarativeConfigurationCustomizer customizer) {
customizeResources(model);
customizeUserAgent(model);
customizeExperimentalRuntimeTelemetryMetrics(model);
customizeMetricsTemporality(model);
return model;
});
}
Expand Down Expand Up @@ -293,4 +294,40 @@ static List<NameStringValuePairModel> addUserAgent(
result.add(new NameStringValuePairModel().withName(HEADER_NAME).withValue(value));
return result;
}

private void customizeMetricsTemporality(OpenTelemetryConfigurationModel model) {
// configure otlp metric exporters temporality preference if not explicitly set.
// for users, setting it explicitly to 'cumulative' restores default SDK behavior.
//
// meter_provider:
// readers:
// - periodic:
// exporter:
// # or 'otlp_grpc' for grpc
// otlp_http:
// endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318}/v1/metrics
// temporality_preference: delta

Optional.ofNullable(model.getMeterProvider())
.map(MeterProviderModel::getReaders)
.orElse(Collections.emptyList())
.forEach(
reader -> {
Optional.ofNullable(reader.getPeriodic())
.map(PeriodicMetricReaderModel::getExporter)
.ifPresent(
metricExporterModel -> {
OtlpGrpcMetricExporterModel otlpGrpc = metricExporterModel.getOtlpGrpc();
if (otlpGrpc != null && otlpGrpc.getTemporalityPreference() == null) {
otlpGrpc.withTemporalityPreference(
OtlpHttpMetricExporterModel.ExporterTemporalityPreference.DELTA);
}
OtlpHttpMetricExporterModel otlpHttp = metricExporterModel.getOtlpHttp();
if (otlpHttp != null && otlpHttp.getTemporalityPreference() == null) {
otlpHttp.withTemporalityPreference(
OtlpHttpMetricExporterModel.ExporterTemporalityPreference.DELTA);
}
});
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,21 @@
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;

class ElasticDeclarativeConfigurationCustomizerTest {
Expand Down Expand Up @@ -275,6 +280,69 @@ private static Map<String, String> userAgentHeader(String value) {
return header;
}

@ParameterizedTest
@MethodSource("metricExporterTemporalityValues")
void metricExporterTemporality(String protocol, @Nullable String userSetTemporality) {

OpenTelemetryConfigurationModel model = new OpenTelemetryConfigurationModel();
PushMetricExporterModel metricExporterModel = new PushMetricExporterModel();

switch (protocol) {
case "grpc":
OtlpHttpMetricExporterModel.ExporterTemporalityPreference grpcUserPreference = null;
if (userSetTemporality != null) {
grpcUserPreference =
OtlpHttpMetricExporterModel.ExporterTemporalityPreference.fromValue(
userSetTemporality);
}
metricExporterModel.withOtlpGrpc(
new OtlpGrpcMetricExporterModel().withTemporalityPreference(grpcUserPreference));
break;
case "http":
OtlpHttpMetricExporterModel.ExporterTemporalityPreference httpUserPreference = null;
if (userSetTemporality != null) {
httpUserPreference =
OtlpHttpMetricExporterModel.ExporterTemporalityPreference.fromValue(
userSetTemporality);
}
metricExporterModel.withOtlpHttp(
new OtlpHttpMetricExporterModel().withTemporalityPreference(httpUserPreference));
break;
default:
throw new IllegalArgumentException("Unsupported protocol: " + protocol);
}

model.withMeterProvider(
new MeterProviderModel()
.withReaders(
Collections.singletonList(
new MetricReaderModel()
.withPeriodic(
new PeriodicMetricReaderModel().withExporter(metricExporterModel)))));

applyConfigCustomize(model, new ElasticDeclarativeConfigurationCustomizer());

assertThat(model.getMeterProvider()).isNotNull();
assertThat(model.getMeterProvider().getReaders()).hasSize(1);
assertThatJson(json(model.getMeterProvider().getReaders().get(0)))
.inPath("periodic.exporter.otlp_" + protocol + ".temporality_preference")
.isEqualTo(userSetTemporality != null ? userSetTemporality : "delta");
}

public static Stream<Arguments> metricExporterTemporalityValues() {
ArrayList<Arguments> args = new ArrayList<>();
for (String protocol : Arrays.asList("grpc", "http")) {
for (OtlpHttpMetricExporterModel.ExporterTemporalityPreference temporality :
OtlpHttpMetricExporterModel.ExporterTemporalityPreference.values()) {
String userValue = temporality.name().toLowerCase();
args.add(Arguments.of(protocol, userValue));
}
// test for default value when user does not set any value
args.add(Arguments.of(protocol, null));
}
return args.stream();
}

private OpenTelemetryConfigurationModel applyConfigCustomize(
OpenTelemetryConfigurationModel originalModel,
DeclarativeConfigurationCustomizerProvider customizerProvider) {
Expand Down
Loading