diff --git a/custom/src/main/java/com/splunk/opentelemetry/SplunkDeclarativeConfigurationCustomizerProvider.java b/custom/src/main/java/com/splunk/opentelemetry/SplunkDeclarativeConfigurationCustomizerProvider.java deleted file mode 100644 index a596f488a..000000000 --- a/custom/src/main/java/com/splunk/opentelemetry/SplunkDeclarativeConfigurationCustomizerProvider.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.splunk.opentelemetry; - -import static io.opentelemetry.sdk.autoconfigure.AdditionalPropertiesUtil.addAdditionalPropertyIfAbsent; -import static io.opentelemetry.sdk.autoconfigure.AdditionalPropertiesUtil.getAdditionalProperty; -import static io.opentelemetry.sdk.autoconfigure.AdditionalPropertiesUtil.setAdditionalProperty; - -import com.google.auto.service.AutoService; -import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizer; -import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnSamplerModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLanguageSpecificInstrumentationModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.InstrumentationModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProviderModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProviderModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.NameStringValuePairModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpGrpcExporterModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpGrpcMetricExporterModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpExporterModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpMetricExporterModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleLogRecordProcessorModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessorModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.logging.Logger; -import java.util.stream.Stream; - -@AutoService(DeclarativeConfigurationCustomizerProvider.class) -public class SplunkDeclarativeConfigurationCustomizerProvider - implements DeclarativeConfigurationCustomizerProvider { - private static final Logger logger = - Logger.getLogger(SplunkDeclarativeConfigurationCustomizerProvider.class.getName()); - - public static final String SPLUNK_ACCESS_TOKEN = "splunk.access.token"; - public static final String SPLUNK_REALM_PROPERTY = "splunk.realm"; - - @Override - public void customize(DeclarativeConfigurationCustomizer autoConfiguration) { - autoConfiguration.addModelCustomizer( - model -> { - if (model.getInstrumentationDevelopment() == null) { - model.withInstrumentationDevelopment(new InstrumentationModel()); - } - ExperimentalLanguageSpecificInstrumentationModel javaModel = - model.getInstrumentationDevelopment().getJava(); - if (javaModel == null) { - javaModel = new ExperimentalLanguageSpecificInstrumentationModel(); - model.getInstrumentationDevelopment().withJava(javaModel); - } - Map properties = javaModel.getAdditionalProperties(); - - customizeConfigProperties(properties); - customizeExporters(model, properties); - customizeSampler(model); - customizeLoggers(model, properties); - - logger.fine(() -> "Customized model: " + model); - - // TODO: implement this in the declarative config validator - // EndpointProtocolValidator.validate(customized, config, logger::warning); - return model; - }); - } - - private static void customizeConfigProperties(Map properties) { - addAdditionalPropertyIfAbsent(properties, "splunk.metrics.force_full_commandline", false); - addAdditionalPropertyIfAbsent(properties, "otel.instrumentation.spring-batch.enabled", true); - addAdditionalPropertyIfAbsent( - properties, "otel.instrumentation.spring-batch.item.enabled", true); - } - - private static void customizeSampler(OpenTelemetryConfigurationModel model) { - // otel.traces.sampler = always_on - if (model.getTracerProvider() != null) { - SamplerModel samplerModel = model.getTracerProvider().getSampler(); - if (samplerModel == null) { - samplerModel = new SamplerModel(); - model.getTracerProvider().withSampler(samplerModel); - } - if ((samplerModel.getAlwaysOff() == null) - && (samplerModel.getAlwaysOn() == null) - && (samplerModel.getJaegerRemote() == null) - && (samplerModel.getParentBased() == null) - && (samplerModel.getTraceIdRatioBased() == null) - && (samplerModel.getAdditionalProperties().isEmpty())) { - samplerModel.withAlwaysOn(new AlwaysOnSamplerModel()); - } - } - } - - private static void customizeLoggers( - OpenTelemetryConfigurationModel model, Map properties) { - // disable logging instrumentations if the logging exporter is not used - boolean loggerExporterDefined = false; - if (model.getLoggerProvider() != null) { - List processors = model.getLoggerProvider().getProcessors(); - if (processors != null) { - loggerExporterDefined = - processors.stream().anyMatch(p -> p.getBatch() != null || p.getSimple() != null); - } - } - if (!loggerExporterDefined) { - setAdditionalProperty(properties, "otel.instrumentation.java-util-logging.enabled", false); - setAdditionalProperty(properties, "otel.instrumentation.jboss-logmanager.enabled", false); - setAdditionalProperty(properties, "otel.instrumentation.log4j-appender.enabled", false); - setAdditionalProperty(properties, "otel.instrumentation.logback-appender.enabled", false); - } - } - - private static void customizeExporters( - OpenTelemetryConfigurationModel model, Map properties) { - String accessToken = - Optional.ofNullable(getAdditionalProperty(properties, SPLUNK_ACCESS_TOKEN)) - .map(Object::toString) - .orElse(null); - String baseEndpointUrl = - Optional.ofNullable(getAdditionalProperty(properties, SPLUNK_REALM_PROPERTY)) - .map((realm) -> "https://ingest." + realm + ".signalfx.com") - .orElse(null); - - if (model.getTracerProvider() != null) { - customizeSpanExporters(model.getTracerProvider(), baseEndpointUrl, accessToken); - } - - if (model.getMeterProvider() != null) { - customizeMetricExporters(model.getMeterProvider(), baseEndpointUrl, accessToken); - } - - if (model.getLoggerProvider() != null) { - customizeLogRecordExporters(model.getLoggerProvider(), accessToken); - } - } - - private static void customizeSpanExporters( - TracerProviderModel model, String baseEndpointUrl, String accessToken) { - String endpointUrl = - Optional.ofNullable(baseEndpointUrl).map((url) -> url + "/v1/traces").orElse(null); - - iterateBatchSpanExporters(model) - .map(SpanExporterModel::getOtlpHttp) - .filter(Objects::nonNull) - .forEach( - exporterModel -> { - maybeAddTokenHeader(exporterModel, accessToken); - maybeSetEndpoint(exporterModel, endpointUrl); - }); - iterateBatchSpanExporters(model) - .map(SpanExporterModel::getOtlpGrpc) - .filter(Objects::nonNull) - .forEach( - exporterModel -> { - maybeAddTokenHeader(exporterModel, accessToken); - maybeSetEndpoint(exporterModel, baseEndpointUrl); - }); - - iterateSimpleSpanExporters(model) - .map(SpanExporterModel::getOtlpHttp) - .filter(Objects::nonNull) - .forEach( - exporterModel -> { - maybeAddTokenHeader(exporterModel, accessToken); - maybeSetEndpoint(exporterModel, endpointUrl); - }); - iterateSimpleSpanExporters(model) - .map(SpanExporterModel::getOtlpGrpc) - .filter(Objects::nonNull) - .forEach( - exporterModel -> { - maybeAddTokenHeader(exporterModel, accessToken); - maybeSetEndpoint(exporterModel, baseEndpointUrl); - }); - } - - private static void customizeMetricExporters( - MeterProviderModel model, String baseEndpointUrl, String accessToken) { - String endpointUrl = - Optional.ofNullable(baseEndpointUrl).map((url) -> url + "/v2/datapoint/otlp").orElse(null); - - iteratePeriodicMetricExporters(model) - .map(PushMetricExporterModel::getOtlpHttp) - .filter(Objects::nonNull) - .forEach( - exporterModel -> { - maybeAddTokenHeader(exporterModel, accessToken); - maybeSetEndpoint(exporterModel, endpointUrl); - }); - iteratePeriodicMetricExporters(model) - .map(PushMetricExporterModel::getOtlpGrpc) - .filter(Objects::nonNull) - .forEach( - exporterModel -> { - maybeAddTokenHeader(exporterModel, accessToken); - // metrics ingest doesn't currently accept grpc - }); - } - - private static void customizeLogRecordExporters(LoggerProviderModel model, String accessToken) { - String httpEndpoint = "http://localhost:4318/v1/logs"; - String grpcEndpoint = "http://localhost:4317"; - - iterateBatchLogRecordExporters(model) - .map(LogRecordExporterModel::getOtlpHttp) - .filter(Objects::nonNull) - .forEach( - exporterModel -> { - maybeAddTokenHeader(exporterModel, accessToken); - maybeSetEndpoint(exporterModel, httpEndpoint); - }); - iterateBatchLogRecordExporters(model) - .map(LogRecordExporterModel::getOtlpGrpc) - .filter(Objects::nonNull) - .forEach( - exporterModel -> { - maybeAddTokenHeader(exporterModel, accessToken); - maybeSetEndpoint(exporterModel, grpcEndpoint); - }); - - iterateSimpleLogRecordExporters(model) - .map(LogRecordExporterModel::getOtlpHttp) - .filter(Objects::nonNull) - .forEach( - exporterModel -> { - maybeAddTokenHeader(exporterModel, accessToken); - maybeSetEndpoint(exporterModel, httpEndpoint); - }); - iterateSimpleLogRecordExporters(model) - .map(LogRecordExporterModel::getOtlpGrpc) - .filter(Objects::nonNull) - .forEach( - exporterModel -> { - maybeAddTokenHeader(exporterModel, accessToken); - maybeSetEndpoint(exporterModel, grpcEndpoint); - }); - } - - private static void maybeSetEndpoint(OtlpHttpMetricExporterModel exporterModel, String endpoint) { - if ((endpoint != null) && (exporterModel.getEndpoint() == null)) { - exporterModel.withEndpoint(endpoint); - exporterModel.withEncoding(OtlpHttpExporterModel.OtlpHttpEncoding.PROTOBUF); - } - } - - private static void maybeSetEndpoint(OtlpGrpcExporterModel exporterModel, String endpoint) { - if ((endpoint != null) && (exporterModel.getEndpoint() == null)) { - exporterModel.withEndpoint(endpoint); - } - } - - private static void maybeSetEndpoint(OtlpHttpExporterModel exporterModel, String endpoint) { - if ((endpoint != null) && (exporterModel.getEndpoint() == null)) { - exporterModel.withEndpoint(endpoint); - } - } - - private static Stream iterateBatchSpanExporters(TracerProviderModel model) { - return model.getProcessors().stream() - .map(SpanProcessorModel::getBatch) - .filter(Objects::nonNull) - .map(BatchSpanProcessorModel::getExporter) - .filter(Objects::nonNull); - } - - private static Stream iterateSimpleSpanExporters(TracerProviderModel model) { - return model.getProcessors().stream() - .map(SpanProcessorModel::getSimple) - .filter(Objects::nonNull) - .map(SimpleSpanProcessorModel::getExporter) - .filter(Objects::nonNull); - } - - private static Stream iteratePeriodicMetricExporters( - MeterProviderModel model) { - return model.getReaders().stream() - .map(MetricReaderModel::getPeriodic) - .filter(Objects::nonNull) - .map(PeriodicMetricReaderModel::getExporter) - .filter(Objects::nonNull); - } - - private static Stream iterateBatchLogRecordExporters( - LoggerProviderModel model) { - return model.getProcessors().stream() - .map(LogRecordProcessorModel::getBatch) - .filter(Objects::nonNull) - .map(BatchLogRecordProcessorModel::getExporter) - .filter(Objects::nonNull); - } - - private static Stream iterateSimpleLogRecordExporters( - LoggerProviderModel model) { - return model.getProcessors().stream() - .map(LogRecordProcessorModel::getSimple) - .filter(Objects::nonNull) - .map(SimpleLogRecordProcessorModel::getExporter) - .filter(Objects::nonNull); - } - - private static void maybeAddTokenHeader(OtlpHttpExporterModel model, String accessToken) { - if (accessToken != null) { - List headers = model.getHeaders(); - if (headers == null) { - headers = new ArrayList<>(); - model.withHeaders(headers); - } - maybeAddTokenHeader(headers, accessToken); - } - } - - private static void maybeAddTokenHeader(OtlpGrpcMetricExporterModel model, String accessToken) { - if (accessToken != null) { - List headers = model.getHeaders(); - if (headers == null) { - headers = new ArrayList<>(); - model.withHeaders(headers); - } - maybeAddTokenHeader(headers, accessToken); - } - } - - private static void maybeAddTokenHeader(OtlpHttpMetricExporterModel model, String accessToken) { - if (accessToken != null) { - List headers = model.getHeaders(); - if (headers == null) { - headers = new ArrayList<>(); - model.withHeaders(headers); - } - maybeAddTokenHeader(headers, accessToken); - } - } - - private static void maybeAddTokenHeader(OtlpGrpcExporterModel model, String accessToken) { - if (accessToken != null) { - List headers = model.getHeaders(); - if (headers == null) { - headers = new ArrayList<>(); - model.withHeaders(headers); - } - maybeAddTokenHeader(headers, accessToken); - } - } - - private static void maybeAddTokenHeader( - List headers, String accessToken) { - NameStringValuePairModel accessTokenHeader = - new NameStringValuePairModel().withName("X-SF-TOKEN").withValue(accessToken); - if (headers.stream() - .noneMatch(header -> Objects.equals(header.getName(), accessTokenHeader.getName()))) { - headers.add(accessTokenHeader); - } - } -} diff --git a/custom/src/main/java/com/splunk/opentelemetry/webengine/WebengineSpanProcessorComponentProvider.java b/custom/src/main/java/com/splunk/opentelemetry/webengine/WebengineSpanProcessorComponentProvider.java index c381a841b..9175079ed 100644 --- a/custom/src/main/java/com/splunk/opentelemetry/webengine/WebengineSpanProcessorComponentProvider.java +++ b/custom/src/main/java/com/splunk/opentelemetry/webengine/WebengineSpanProcessorComponentProvider.java @@ -24,17 +24,16 @@ @SuppressWarnings("rawtypes") @AutoService(ComponentProvider.class) public class WebengineSpanProcessorComponentProvider implements ComponentProvider { - static String PROVIDER_NAME = "web_engine"; + static final String NAME = "web_engine"; @Override public Class getType() { return SpanProcessor.class; } - // TODO: Add to Splunk specific yaml config file format documentation @Override public String getName() { - return PROVIDER_NAME; + return NAME; } @Override diff --git a/custom/src/main/java/com/splunk/opentelemetry/webengine/WebengineSpanProcessorCustomizerProvider.java b/custom/src/main/java/com/splunk/opentelemetry/webengine/WebengineSpanProcessorCustomizerProvider.java index cf0c860c7..1d4061854 100644 --- a/custom/src/main/java/com/splunk/opentelemetry/webengine/WebengineSpanProcessorCustomizerProvider.java +++ b/custom/src/main/java/com/splunk/opentelemetry/webengine/WebengineSpanProcessorCustomizerProvider.java @@ -41,7 +41,7 @@ public void customize(DeclarativeConfigurationCustomizer autoConfiguration) { 0, new SpanProcessorModel() .withAdditionalProperty( - WebengineSpanProcessorComponentProvider.PROVIDER_NAME, null)); + WebengineSpanProcessorComponentProvider.NAME, null)); } return model; }); diff --git a/custom/src/test/java/com/splunk/opentelemetry/SplunkDeclarativeConfigurationCustomizerProviderTest.java b/custom/src/test/java/com/splunk/opentelemetry/SplunkDeclarativeConfigurationCustomizerProviderTest.java deleted file mode 100644 index 76fa571b7..000000000 --- a/custom/src/test/java/com/splunk/opentelemetry/SplunkDeclarativeConfigurationCustomizerProviderTest.java +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright Splunk Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.splunk.opentelemetry; - -import static com.splunk.opentelemetry.testing.declarativeconfig.DeclarativeConfigTestUtil.parseAndCustomizeModel; -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; -import io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.NameStringValuePairModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel; -import java.nio.file.Path; -import java.util.List; -import java.util.Objects; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -class SplunkDeclarativeConfigurationCustomizerProviderTest { - - @Test - void shouldCustomizeConfigPropertiesIfUndefined() { - // given - var yaml = - """ - file_format: "1.0-rc.1" - instrumentation/development: - java: - """; - - // when - DeclarativeConfigProperties configProperties = getCustomizedJavaInstrumentationConfig(yaml); - - // then - assertThat( - configProperties - .getStructured("splunk") - .getStructured("metrics") - .getBoolean("force_full_commandline")) - .isEqualTo(false); - assertThat(configProperties.getStructured("spring-batch").getBoolean("enabled")) - .isEqualTo(true); - assertThat( - configProperties - .getStructured("spring-batch") - .getStructured("item") - .getBoolean("enabled")) - .isEqualTo(true); - } - - @Test - void shouldKeepOriginalConfigProperties() { - // given - var yaml = - """ - file_format: "1.0-rc.1" - instrumentation/development: - java: - spring-batch: - enabled: false - item: - enabled: false - splunk: - metrics: - force_full_commandline: true - """; - - // when - DeclarativeConfigProperties configProperties = getCustomizedJavaInstrumentationConfig(yaml); - - // then - assertThat( - configProperties - .getStructured("splunk") - .getStructured("metrics") - .getBoolean("force_full_commandline")) - .isEqualTo(true); - assertThat(configProperties.getStructured("spring-batch").getBoolean("enabled")) - .isEqualTo(false); - assertThat( - configProperties - .getStructured("spring-batch") - .getStructured("item") - .getBoolean("enabled")) - .isEqualTo(false); - } - - @Test - void shouldCustomizeSamplerIfUndefined(@TempDir Path tempDir) { - // given - String yaml = - """ - file_format: "1.0-rc.1" - tracer_provider: - processors: - - batch: - exporter: - console: - sampler: - instrumentation/development: - java: - """; - - // when - OpenTelemetryConfigurationModel model = getCustomizedModel(yaml); - - // then - assertThat(model.getTracerProvider().getSampler().getAlwaysOn()).isNotNull(); - } - - @Test - void shouldKeepOriginalSamplerConfigurationIfDefined(@TempDir Path tempDir) { - // given - var yaml = - """ - file_format: "1.0-rc.1" - tracer_provider: - processors: - - batch: - exporter: - console: - sampler: - always_off: - instrumentation/development: - java: - """; - - // when - OpenTelemetryConfigurationModel model = getCustomizedModel(yaml); - - // then - assertThat(model.getTracerProvider().getSampler().getAlwaysOff()).isNotNull(); - } - - @Test - void shouldCustomizeSpanExporters() { - // given - var yaml = - """ - file_format: "1.0-rc.1" - tracer_provider: - processors: - - batch: - exporter: - otlp_http: - - batch: - exporter: - otlp_http: - endpoint: "http://untouched:1" - - batch: - exporter: - otlp_grpc: - - batch: - exporter: - otlp_grpc: - endpoint: "http://untouched:2" - - simple: - exporter: - otlp_http: - - simple: - exporter: - otlp_http: - endpoint: "http://untouched:3" - - simple: - exporter: - otlp_grpc: - - simple: - exporter: - otlp_grpc: - endpoint: "http://untouched:4" - instrumentation/development: - java: - splunk: - realm: unreal-test-realm - access: - token: ABC123456 - """; - - // when - OpenTelemetryConfigurationModel model = getCustomizedModel(yaml); - - // then - NameStringValuePairModel tokenHeader = - new NameStringValuePairModel().withName("X-SF-TOKEN").withValue("ABC123456"); - String httpEndpoint = "https://ingest.unreal-test-realm.signalfx.com/v1/traces"; - String grpcEndpoint = "https://ingest.unreal-test-realm.signalfx.com"; - - assertThat(getSpanProcessorModel(model, 0).getBatch().getExporter().getOtlpHttp()) - .matches((m) -> m.getEndpoint().equals(httpEndpoint)) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getSpanProcessorModel(model, 1).getBatch().getExporter().getOtlpHttp()) - .matches((m) -> m.getEndpoint().equals("http://untouched:1")) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getSpanProcessorModel(model, 2).getBatch().getExporter().getOtlpGrpc()) - .matches((m) -> m.getEndpoint().equals(grpcEndpoint)) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getSpanProcessorModel(model, 3).getBatch().getExporter().getOtlpGrpc()) - .matches((m) -> m.getEndpoint().equals("http://untouched:2")) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getSpanProcessorModel(model, 4).getSimple().getExporter().getOtlpHttp()) - .matches((m) -> m.getEndpoint().equals(httpEndpoint)) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getSpanProcessorModel(model, 5).getSimple().getExporter().getOtlpHttp()) - .matches((m) -> m.getEndpoint().equals("http://untouched:3")) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getSpanProcessorModel(model, 6).getSimple().getExporter().getOtlpGrpc()) - .matches((m) -> m.getEndpoint().equals(grpcEndpoint)) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getSpanProcessorModel(model, 7).getSimple().getExporter().getOtlpGrpc()) - .matches((m) -> m.getEndpoint().equals("http://untouched:4")) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - } - - @Test - void shouldCustomizeMetricExporters() { - // given - var yaml = - """ - file_format: "1.0-rc.1" - meter_provider: - readers: - - periodic: - exporter: - otlp_http: - - periodic: - exporter: - otlp_http: - endpoint: "http://untouched:1" - - periodic: - exporter: - otlp_grpc: - - periodic: - exporter: - otlp_grpc: - endpoint: "http://untouched:2" - instrumentation/development: - java: - splunk: - realm: unreal-test-realm - access: - token: ABC123456 - """; - - // when - OpenTelemetryConfigurationModel model = getCustomizedModel(yaml); - - // then - NameStringValuePairModel tokenHeader = - new NameStringValuePairModel().withName("X-SF-TOKEN").withValue("ABC123456"); - String httpEndpoint = "https://ingest.unreal-test-realm.signalfx.com/v2/datapoint/otlp"; - - assertThat(getMetricReaderModel(model, 0).getPeriodic().getExporter().getOtlpHttp()) - .matches((m) -> m.getEndpoint().equals(httpEndpoint)) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getMetricReaderModel(model, 1).getPeriodic().getExporter().getOtlpHttp()) - .matches((m) -> m.getEndpoint().equals("http://untouched:1")) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getMetricReaderModel(model, 2).getPeriodic().getExporter().getOtlpGrpc()) - .matches((m) -> m.getEndpoint() == null) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getMetricReaderModel(model, 3).getPeriodic().getExporter().getOtlpGrpc()) - .matches((m) -> m.getEndpoint().equals("http://untouched:2")) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - } - - @Test - void shouldCustomizeLogRecordExporters() { - // given - var yaml = - """ - file_format: "1.0-rc.1" - logger_provider: - processors: - - batch: - exporter: - otlp_http: - - batch: - exporter: - otlp_http: - endpoint: "http://untouched:1" - - batch: - exporter: - otlp_grpc: - - batch: - exporter: - otlp_grpc: - endpoint: "http://untouched:2" - - simple: - exporter: - otlp_http: - - simple: - exporter: - otlp_http: - endpoint: "http://untouched:3" - - simple: - exporter: - otlp_grpc: - - simple: - exporter: - otlp_grpc: - endpoint: "http://untouched:4" - instrumentation/development: - java: - splunk: - realm: unreal-test-realm - access: - token: ABC123456 - """; - - // when - OpenTelemetryConfigurationModel model = getCustomizedModel(yaml); - - // then - NameStringValuePairModel tokenHeader = - new NameStringValuePairModel().withName("X-SF-TOKEN").withValue("ABC123456"); - String httpEndpoint = "http://localhost:4318/v1/logs"; - String grpcEndpoint = "http://localhost:4317"; - - assertThat(getLogRecordProcessorModel(model, 0).getBatch().getExporter().getOtlpHttp()) - .matches((m) -> m.getEndpoint().equals(httpEndpoint)) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getLogRecordProcessorModel(model, 1).getBatch().getExporter().getOtlpHttp()) - .matches((m) -> m.getEndpoint().equals("http://untouched:1")) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getLogRecordProcessorModel(model, 2).getBatch().getExporter().getOtlpGrpc()) - .matches((m) -> m.getEndpoint().equals(grpcEndpoint)) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getLogRecordProcessorModel(model, 3).getBatch().getExporter().getOtlpGrpc()) - .matches((m) -> m.getEndpoint().equals("http://untouched:2")) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getLogRecordProcessorModel(model, 4).getSimple().getExporter().getOtlpHttp()) - .matches((m) -> m.getEndpoint().equals(httpEndpoint)) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getLogRecordProcessorModel(model, 5).getSimple().getExporter().getOtlpHttp()) - .matches((m) -> m.getEndpoint().equals("http://untouched:3")) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getLogRecordProcessorModel(model, 6).getSimple().getExporter().getOtlpGrpc()) - .matches((m) -> m.getEndpoint().equals(grpcEndpoint)) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - - assertThat(getLogRecordProcessorModel(model, 7).getSimple().getExporter().getOtlpGrpc()) - .matches((m) -> m.getEndpoint().equals("http://untouched:4")) - .matches((m) -> m.getHeaders().contains(tokenHeader)); - } - - private SpanProcessorModel getSpanProcessorModel( - OpenTelemetryConfigurationModel model, int index) { - assertThat(model.getTracerProvider()).isNotNull(); - return model.getTracerProvider().getProcessors().get(index); - } - - private MetricReaderModel getMetricReaderModel(OpenTelemetryConfigurationModel model, int index) { - assertThat(model.getMeterProvider()).isNotNull(); - return model.getMeterProvider().getReaders().get(index); - } - - private LogRecordProcessorModel getLogRecordProcessorModel( - OpenTelemetryConfigurationModel model, int index) { - assertThat(model.getLoggerProvider()).isNotNull(); - return model.getLoggerProvider().getProcessors().get(index); - } - - @Test - void shouldNotUpdateAccessTokenProvidedInExporterHeaders() { - // given - var yaml = - """ - file_format: "1.0-rc.1" - tracer_provider: - processors: - - batch: - exporter: - otlp_http: - headers: - - name: X-SF-TOKEN - value: XYZ - instrumentation/development: - java: - splunk: - access: - token: ABC123456 - """; - - // when - OpenTelemetryConfigurationModel model = getCustomizedModel(yaml); - - // then - List headers = - model.getTracerProvider().getProcessors().stream() - .filter(m -> m.getBatch() != null) - .limit(1) - .toList() - .get(0) - .getBatch() - .getExporter() - .getOtlpHttp() - .getHeaders(); - assertThat(headers.size()).isEqualTo(1); - assertThat(headers.get(0).getName()).isEqualTo("X-SF-TOKEN"); - assertThat(headers.get(0).getValue()).isEqualTo("XYZ"); - } - - private static OpenTelemetryConfigurationModel getCustomizedModel(String yaml) { - SplunkDeclarativeConfigurationCustomizerProvider customizer = - new SplunkDeclarativeConfigurationCustomizerProvider(); - return parseAndCustomizeModel(yaml, customizer); - } - - private static DeclarativeConfigProperties getCustomizedJavaInstrumentationConfig(String yaml) { - var model = getCustomizedModel(yaml); - var configProvider = SdkConfigProvider.create(model); - return Objects.requireNonNull(configProvider.getInstrumentationConfig()).getStructured("java"); - } -} diff --git a/custom/src/test/java/com/splunk/opentelemetry/webengine/WebengineSpanProcessorCustomizerProviderTest.java b/custom/src/test/java/com/splunk/opentelemetry/webengine/WebengineSpanProcessorCustomizerProviderTest.java index 9359cfd8f..6e97072e7 100644 --- a/custom/src/test/java/com/splunk/opentelemetry/webengine/WebengineSpanProcessorCustomizerProviderTest.java +++ b/custom/src/test/java/com/splunk/opentelemetry/webengine/WebengineSpanProcessorCustomizerProviderTest.java @@ -46,7 +46,7 @@ void shouldAddWebengineSpanProcessor() { processors .get(0) .getAdditionalProperties() - .containsKey(WebengineSpanProcessorComponentProvider.PROVIDER_NAME)) + .containsKey(WebengineSpanProcessorComponentProvider.NAME)) .isTrue(); assertThat(processors.get(1).getSimple()).isNotNull(); }