Add metrics & micrometer support to spring-boot-autoconfigure (#6270)
* Add metrics & micrometer support to spring-boot-autoconfigure * Apply suggestions from code review Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com> * code review comments Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
This commit is contained in:
parent
646a724a38
commit
9058ad6f40
|
@ -14,7 +14,10 @@ muzzle {
|
|||
dependencies {
|
||||
library("io.micrometer:micrometer-core:1.5.0")
|
||||
|
||||
implementation("io.opentelemetry:opentelemetry-micrometer1-shim")
|
||||
implementation("io.opentelemetry:opentelemetry-micrometer1-shim") {
|
||||
// just get the instrumentation, without micrometer itself
|
||||
exclude("io.micrometer", "micrometer-core")
|
||||
}
|
||||
}
|
||||
|
||||
tasks {
|
||||
|
|
|
@ -6,21 +6,27 @@ plugins {
|
|||
group = "io.opentelemetry.instrumentation"
|
||||
|
||||
val versions: Map<String, String> by project
|
||||
val springBootVersion = versions["org.springframework.boot"]
|
||||
|
||||
dependencies {
|
||||
implementation(project(":instrumentation-api-annotation-support"))
|
||||
|
||||
implementation("org.springframework.boot:spring-boot-autoconfigure:${versions["org.springframework.boot"]}")
|
||||
annotationProcessor("org.springframework.boot:spring-boot-autoconfigure-processor:${versions["org.springframework.boot"]}")
|
||||
implementation("org.springframework.boot:spring-boot-autoconfigure:$springBootVersion")
|
||||
annotationProcessor("org.springframework.boot:spring-boot-autoconfigure-processor:$springBootVersion")
|
||||
implementation("javax.validation:validation-api:2.0.1.Final")
|
||||
|
||||
implementation(project(":instrumentation:spring:spring-web-3.1:library"))
|
||||
implementation(project(":instrumentation:spring:spring-webmvc-3.1:library"))
|
||||
implementation(project(":instrumentation:spring:spring-webflux-5.0:library"))
|
||||
implementation("io.opentelemetry:opentelemetry-micrometer1-shim") {
|
||||
// just get the instrumentation, without micrometer itself
|
||||
exclude("io.micrometer", "micrometer-core")
|
||||
}
|
||||
|
||||
compileOnly("org.springframework.boot:spring-boot-starter-aop:${versions["org.springframework.boot"]}")
|
||||
compileOnly("org.springframework.boot:spring-boot-starter-web:${versions["org.springframework.boot"]}")
|
||||
compileOnly("org.springframework.boot:spring-boot-starter-webflux:${versions["org.springframework.boot"]}")
|
||||
compileOnly("org.springframework.boot:spring-boot-starter-actuator:$springBootVersion")
|
||||
compileOnly("org.springframework.boot:spring-boot-starter-aop:$springBootVersion")
|
||||
compileOnly("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
|
||||
compileOnly("org.springframework.boot:spring-boot-starter-webflux:$springBootVersion")
|
||||
|
||||
compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi")
|
||||
compileOnly("io.opentelemetry:opentelemetry-extension-annotations")
|
||||
|
@ -32,10 +38,11 @@ dependencies {
|
|||
compileOnly("io.opentelemetry:opentelemetry-exporter-otlp")
|
||||
compileOnly("io.opentelemetry:opentelemetry-exporter-zipkin")
|
||||
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-aop:${versions["org.springframework.boot"]}")
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-webflux:${versions["org.springframework.boot"]}")
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-web:${versions["org.springframework.boot"]}")
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-test:${versions["org.springframework.boot"]}") {
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-actuator:$springBootVersion")
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-aop:$springBootVersion")
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-webflux:$springBootVersion")
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-test:$springBootVersion") {
|
||||
exclude("org.junit.vintage", "junit-vintage-engine")
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.spring.autoconfigure;
|
||||
|
||||
import java.time.Duration;
|
||||
import javax.annotation.Nullable;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties(prefix = "otel.metric.export")
|
||||
public class MetricExportProperties {
|
||||
|
||||
@Nullable private Duration interval;
|
||||
|
||||
@Nullable
|
||||
public Duration getInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
||||
public void setInterval(@Nullable Duration interval) {
|
||||
this.interval = interval;
|
||||
}
|
||||
}
|
|
@ -12,6 +12,11 @@ import io.opentelemetry.instrumentation.spring.autoconfigure.resources.SpringRes
|
|||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
|
||||
import io.opentelemetry.sdk.metrics.export.MetricExporter;
|
||||
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
|
||||
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReaderBuilder;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import io.opentelemetry.sdk.trace.SdkTracerProvider;
|
||||
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
|
||||
|
@ -36,7 +41,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
|
|||
* <p>Updates the sampler probability for the configured {@link TracerProvider}.
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(SamplerProperties.class)
|
||||
@EnableConfigurationProperties({MetricExportProperties.class, SamplerProperties.class})
|
||||
public class OpenTelemetryAutoConfiguration {
|
||||
|
||||
@Configuration
|
||||
|
@ -61,6 +66,32 @@ public class OpenTelemetryAutoConfiguration {
|
|||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public SdkMeterProvider sdkMeterProvider(
|
||||
MetricExportProperties properties,
|
||||
ObjectProvider<List<MetricExporter>> metricExportersProvider,
|
||||
Resource otelResource) {
|
||||
|
||||
SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder();
|
||||
|
||||
metricExportersProvider.getIfAvailable(Collections::emptyList).stream()
|
||||
.map(metricExporter -> createPeriodicMetricReader(properties, metricExporter))
|
||||
.forEach(meterProviderBuilder::registerMetricReader);
|
||||
|
||||
return meterProviderBuilder.setResource(otelResource).build();
|
||||
}
|
||||
|
||||
private static PeriodicMetricReader createPeriodicMetricReader(
|
||||
MetricExportProperties properties, MetricExporter metricExporter) {
|
||||
PeriodicMetricReaderBuilder metricReaderBuilder =
|
||||
PeriodicMetricReader.builder(metricExporter);
|
||||
if (properties.getInterval() != null) {
|
||||
metricReaderBuilder.setInterval(properties.getInterval());
|
||||
}
|
||||
return metricReaderBuilder.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Resource otelResource(
|
||||
|
@ -76,12 +107,15 @@ public class OpenTelemetryAutoConfiguration {
|
|||
|
||||
@Bean
|
||||
public OpenTelemetry openTelemetry(
|
||||
ObjectProvider<ContextPropagators> propagatorsProvider, SdkTracerProvider tracerProvider) {
|
||||
ObjectProvider<ContextPropagators> propagatorsProvider,
|
||||
SdkTracerProvider tracerProvider,
|
||||
SdkMeterProvider meterProvider) {
|
||||
|
||||
ContextPropagators propagators = propagatorsProvider.getIfAvailable(ContextPropagators::noop);
|
||||
|
||||
return OpenTelemetrySdk.builder()
|
||||
.setTracerProvider(tracerProvider)
|
||||
.setMeterProvider(meterProvider)
|
||||
.setPropagators(propagators)
|
||||
.build();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Configuration for {@link io.opentelemetry.exporter.logging.LoggingSpanExporter} and {@link
|
||||
* io.opentelemetry.exporter.logging.LoggingMetricExporter}.
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "otel.exporter.logging")
|
||||
public final class LoggingExporterProperties {
|
||||
|
||||
private boolean enabled = true;
|
||||
private final SignalProperties traces = new SignalProperties();
|
||||
private final SignalProperties metrics = new SignalProperties();
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public SignalProperties getTraces() {
|
||||
return traces;
|
||||
}
|
||||
|
||||
public SignalProperties getMetrics() {
|
||||
return metrics;
|
||||
}
|
||||
|
||||
public static class SignalProperties {
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging;
|
||||
|
||||
import io.opentelemetry.exporter.logging.LoggingMetricExporter;
|
||||
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
|
||||
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/** Configures {@link LoggingSpanExporter} bean for tracing. */
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(LoggingExporterProperties.class)
|
||||
@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class)
|
||||
@ConditionalOnProperty(
|
||||
prefix = "otel.exporter.logging",
|
||||
name = {"enabled", "metrics.enabled"},
|
||||
matchIfMissing = true)
|
||||
@ConditionalOnClass(LoggingMetricExporter.class)
|
||||
public class LoggingMetricExporterAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public LoggingMetricExporter otelLoggingMetricExporter() {
|
||||
return LoggingMetricExporter.create();
|
||||
}
|
||||
}
|
|
@ -17,9 +17,12 @@ import org.springframework.context.annotation.Configuration;
|
|||
|
||||
/** Configures {@link LoggingSpanExporter} bean for tracing. */
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(LoggingSpanExporterProperties.class)
|
||||
@EnableConfigurationProperties(LoggingExporterProperties.class)
|
||||
@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class)
|
||||
@ConditionalOnProperty(prefix = "otel.exporter.logging", name = "enabled", matchIfMissing = true)
|
||||
@ConditionalOnProperty(
|
||||
prefix = "otel.exporter.logging",
|
||||
name = {"enabled", "traces.enabled"},
|
||||
matchIfMissing = true)
|
||||
@ConditionalOnClass(LoggingSpanExporter.class)
|
||||
public class LoggingSpanExporterAutoConfiguration {
|
||||
|
||||
|
|
|
@ -10,7 +10,8 @@ import javax.annotation.Nullable;
|
|||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Configuration for {@link io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter}.
|
||||
* Configuration for {@link io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter} and {@link
|
||||
* io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter}.
|
||||
*
|
||||
* <p>Get Exporter Service Name
|
||||
*
|
||||
|
@ -19,11 +20,13 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
|||
* <p>Get max wait time for Collector to process Span Batches
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "otel.exporter.otlp")
|
||||
public final class OtlpGrpcSpanExporterProperties {
|
||||
public final class OtlpExporterProperties {
|
||||
|
||||
private boolean enabled = true;
|
||||
@Nullable private String endpoint;
|
||||
@Nullable private Duration timeout;
|
||||
private final SignalProperties traces = new SignalProperties();
|
||||
private final SignalProperties metrics = new SignalProperties();
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
|
@ -50,4 +53,45 @@ public final class OtlpGrpcSpanExporterProperties {
|
|||
public void setTimeout(Duration timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public SignalProperties getTraces() {
|
||||
return traces;
|
||||
}
|
||||
|
||||
public SignalProperties getMetrics() {
|
||||
return metrics;
|
||||
}
|
||||
|
||||
public static class SignalProperties {
|
||||
|
||||
private boolean enabled = true;
|
||||
@Nullable private String endpoint;
|
||||
@Nullable private Duration timeout;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getEndpoint() {
|
||||
return endpoint;
|
||||
}
|
||||
|
||||
public void setEndpoint(@Nullable String endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Duration getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public void setTimeout(@Nullable Duration timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp;
|
||||
|
||||
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
|
||||
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder;
|
||||
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
|
||||
import java.time.Duration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class)
|
||||
@EnableConfigurationProperties(OtlpExporterProperties.class)
|
||||
@ConditionalOnProperty(
|
||||
prefix = "otel.exporter.otlp",
|
||||
name = {"enabled", "metrics.enabled"},
|
||||
matchIfMissing = true)
|
||||
@ConditionalOnClass(OtlpGrpcMetricExporter.class)
|
||||
public class OtlpMetricExporterAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public OtlpGrpcMetricExporter otelOtlpGrpcMetricExporter(OtlpExporterProperties properties) {
|
||||
OtlpGrpcMetricExporterBuilder builder = OtlpGrpcMetricExporter.builder();
|
||||
|
||||
String endpoint = properties.getMetrics().getEndpoint();
|
||||
if (endpoint == null) {
|
||||
endpoint = properties.getEndpoint();
|
||||
}
|
||||
if (endpoint != null) {
|
||||
builder.setEndpoint(endpoint);
|
||||
}
|
||||
|
||||
Duration timeout = properties.getMetrics().getTimeout();
|
||||
if (timeout == null) {
|
||||
timeout = properties.getTimeout();
|
||||
}
|
||||
if (timeout != null) {
|
||||
builder.setTimeout(timeout);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp;
|
|||
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
|
||||
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder;
|
||||
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
|
||||
import java.time.Duration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
|
@ -23,22 +24,35 @@ import org.springframework.context.annotation.Configuration;
|
|||
*/
|
||||
@Configuration
|
||||
@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class)
|
||||
@EnableConfigurationProperties(OtlpGrpcSpanExporterProperties.class)
|
||||
@ConditionalOnProperty(prefix = "otel.exporter.otlp", name = "enabled", matchIfMissing = true)
|
||||
@EnableConfigurationProperties(OtlpExporterProperties.class)
|
||||
@ConditionalOnProperty(
|
||||
prefix = "otel.exporter.otlp",
|
||||
name = {"enabled", "traces.enabled"},
|
||||
matchIfMissing = true)
|
||||
@ConditionalOnClass(OtlpGrpcSpanExporter.class)
|
||||
public class OtlpGrpcSpanExporterAutoConfiguration {
|
||||
public class OtlpSpanExporterAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public OtlpGrpcSpanExporter otelOtlpGrpcSpanExporter(OtlpGrpcSpanExporterProperties properties) {
|
||||
|
||||
public OtlpGrpcSpanExporter otelOtlpGrpcSpanExporter(OtlpExporterProperties properties) {
|
||||
OtlpGrpcSpanExporterBuilder builder = OtlpGrpcSpanExporter.builder();
|
||||
if (properties.getEndpoint() != null) {
|
||||
builder.setEndpoint(properties.getEndpoint());
|
||||
|
||||
String endpoint = properties.getTraces().getEndpoint();
|
||||
if (endpoint == null) {
|
||||
endpoint = properties.getEndpoint();
|
||||
}
|
||||
if (properties.getTimeout() != null) {
|
||||
builder.setTimeout(properties.getTimeout());
|
||||
if (endpoint != null) {
|
||||
builder.setEndpoint(endpoint);
|
||||
}
|
||||
|
||||
Duration timeout = properties.getTraces().getTimeout();
|
||||
if (timeout == null) {
|
||||
timeout = properties.getTimeout();
|
||||
}
|
||||
if (timeout != null) {
|
||||
builder.setTimeout(timeout);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.spring.autoconfigure.metrics;
|
||||
|
||||
import io.micrometer.core.instrument.Clock;
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.micrometer1shim.OpenTelemetryMeterRegistry;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(MicrometerShimProperties.class)
|
||||
@ConditionalOnProperty(name = "otel.springboot.micrometer.enabled", matchIfMissing = true)
|
||||
@AutoConfigureAfter(MetricsAutoConfiguration.class)
|
||||
@AutoConfigureBefore(CompositeMeterRegistryAutoConfiguration.class)
|
||||
@ConditionalOnBean(Clock.class)
|
||||
@ConditionalOnClass(MeterRegistry.class)
|
||||
public class MicrometerShimAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public MeterRegistry micrometerShim(OpenTelemetry openTelemetry, Clock micrometerClock) {
|
||||
return OpenTelemetryMeterRegistry.builder(openTelemetry).setClock(micrometerClock).build();
|
||||
}
|
||||
}
|
|
@ -3,13 +3,13 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging;
|
||||
package io.opentelemetry.instrumentation.spring.autoconfigure.metrics;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/** Configuration for {@link io.opentelemetry.exporter.logging.LoggingSpanExporter}. */
|
||||
@ConfigurationProperties(prefix = "otel.exporter.logging")
|
||||
public final class LoggingSpanExporterProperties {
|
||||
@ConfigurationProperties(prefix = "otel.springboot.micrometer")
|
||||
public class MicrometerShimProperties {
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
public boolean isEnabled() {
|
|
@ -1,12 +1,14 @@
|
|||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.exporters.jaeger.JaegerSpanExporterAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpGrpcSpanExporterAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.exporters.zipkin.ZipkinSpanExporterAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging.LoggingSpanExporterAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.propagators.PropagationAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.aspects.TraceAspectAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.exporters.jaeger.JaegerSpanExporterAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging.LoggingSpanExporterAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpMetricExporterAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpSpanExporterAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.exporters.zipkin.ZipkinSpanExporterAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.httpclients.resttemplate.RestTemplateAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.httpclients.webclient.WebClientAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.webmvc.WebMvcFilterAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.aspects.TraceAspectAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.resources.OtelResourceAutoConfiguration
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.metrics.MicrometerShimAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.propagators.PropagationAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.resources.OtelResourceAutoConfiguration,\
|
||||
io.opentelemetry.instrumentation.spring.autoconfigure.webmvc.WebMvcFilterAutoConfiguration
|
||||
|
|
|
@ -11,6 +11,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
import io.opentelemetry.api.OpenTelemetry;
|
||||
import io.opentelemetry.api.common.AttributeKey;
|
||||
import io.opentelemetry.instrumentation.spring.autoconfigure.resources.OtelResourceAutoConfiguration;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
|
||||
import io.opentelemetry.sdk.resources.Resource;
|
||||
import io.opentelemetry.sdk.trace.SdkTracerProvider;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
|
@ -44,34 +45,44 @@ class OpenTelemetryAutoConfigurationTest {
|
|||
assertThat(context)
|
||||
.hasBean("customOpenTelemetry")
|
||||
.doesNotHaveBean("openTelemetry")
|
||||
.doesNotHaveBean("sdkTracerProvider"));
|
||||
.doesNotHaveBean("sdkTracerProvider")
|
||||
.doesNotHaveBean("sdkMeterProvider"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName(
|
||||
"when Application Context DOES NOT contain OpenTelemetry bean should initialize openTelemetry")
|
||||
void initializeTracerProviderAndOpenTelemetry() {
|
||||
void initializeProvidersAndOpenTelemetry() {
|
||||
this.contextRunner
|
||||
.withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class))
|
||||
.run(context -> assertThat(context).hasBean("openTelemetry").hasBean("sdkTracerProvider"));
|
||||
.run(
|
||||
context ->
|
||||
assertThat(context)
|
||||
.hasBean("openTelemetry")
|
||||
.hasBean("sdkTracerProvider")
|
||||
.hasBean("sdkMeterProvider"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName(
|
||||
"when Application Context DOES NOT contain OpenTelemetry bean but TracerProvider should initialize openTelemetry")
|
||||
void initializeOpenTelemetry() {
|
||||
void initializeOpenTelemetryWithCustomProviders() {
|
||||
this.contextRunner
|
||||
.withBean(
|
||||
"customTracerProvider",
|
||||
SdkTracerProvider.class,
|
||||
() -> SdkTracerProvider.builder().build())
|
||||
.withBean(
|
||||
"customMeterProvider", SdkMeterProvider.class, () -> SdkMeterProvider.builder().build())
|
||||
.withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class))
|
||||
.run(
|
||||
context ->
|
||||
assertThat(context)
|
||||
.hasBean("openTelemetry")
|
||||
.hasBean("customTracerProvider")
|
||||
.doesNotHaveBean("sdkTracerProvider"));
|
||||
.doesNotHaveBean("sdkTracerProvider")
|
||||
.hasBean("customMeterProvider")
|
||||
.doesNotHaveBean("sdkMeterProvider"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.opentelemetry.exporter.logging.LoggingMetricExporter;
|
||||
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
class LoggingMetricExporterAutoConfigurationTest {
|
||||
|
||||
private final ApplicationContextRunner runner =
|
||||
new ApplicationContextRunner()
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(
|
||||
OpenTelemetryAutoConfiguration.class,
|
||||
LoggingMetricExporterAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void loggingEnabled() {
|
||||
runner
|
||||
.withPropertyValues("otel.exporter.logging.enabled=true")
|
||||
.run(
|
||||
context ->
|
||||
assertThat(
|
||||
context.getBean("otelLoggingMetricExporter", LoggingMetricExporter.class))
|
||||
.isNotNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
void loggingMetricsEnabled() {
|
||||
runner
|
||||
.withPropertyValues("otel.exporter.logging.metrics.enabled=true")
|
||||
.run(
|
||||
context ->
|
||||
assertThat(
|
||||
context.getBean("otelLoggingMetricExporter", LoggingMetricExporter.class))
|
||||
.isNotNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
void loggingDisabled() {
|
||||
runner
|
||||
.withPropertyValues("otel.exporter.logging.enabled=false")
|
||||
.run(context -> assertThat(context.containsBean("otelLoggingMetricExporter")).isFalse());
|
||||
}
|
||||
|
||||
@Test
|
||||
void loggingMetricsDisabled() {
|
||||
runner
|
||||
.withPropertyValues("otel.exporter.logging.metrics.enabled=false")
|
||||
.run(context -> assertThat(context.containsBean("otelLoggingMetricExporter")).isFalse());
|
||||
}
|
||||
|
||||
@Test
|
||||
void noProperties() {
|
||||
runner.run(
|
||||
context ->
|
||||
assertThat(context.getBean("otelLoggingMetricExporter", LoggingMetricExporter.class))
|
||||
.isNotNull());
|
||||
}
|
||||
}
|
|
@ -3,13 +3,12 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.spring.autoconfigure.exporters;
|
||||
package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
|
||||
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
|
||||
import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging.LoggingSpanExporterAutoConfiguration;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
|
@ -27,7 +26,7 @@ class LoggingSpanExporterAutoConfigurationTest {
|
|||
|
||||
@Test
|
||||
@DisplayName("when exporters are ENABLED should initialize LoggingSpanExporter bean")
|
||||
void exportersEnabled() {
|
||||
void loggingEnabled() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("otel.exporter.logging.enabled=true")
|
||||
.run(
|
||||
|
@ -36,18 +35,36 @@ class LoggingSpanExporterAutoConfigurationTest {
|
|||
.isNotNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
void loggingTracesEnabled() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("otel.exporter.logging.traces.enabled=true")
|
||||
.run(
|
||||
context ->
|
||||
assertThat(context.getBean("otelLoggingSpanExporter", LoggingSpanExporter.class))
|
||||
.isNotNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("when exporters are DISABLED should NOT initialize LoggingSpanExporter bean")
|
||||
void disabledProperty() {
|
||||
void loggingDisabled() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("otel.exporter.logging.enabled=false")
|
||||
.run(context -> assertThat(context.containsBean("otelLoggingSpanExporter")).isFalse());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("when exporters are DISABLED should NOT initialize LoggingSpanExporter bean")
|
||||
void loggingTracesDisabled() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("otel.exporter.logging.traces.enabled=false")
|
||||
.run(context -> assertThat(context.containsBean("otelLoggingSpanExporter")).isFalse());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName(
|
||||
"when exporter enabled property is MISSING should initialize LoggingSpanExporter bean")
|
||||
void noProperty() {
|
||||
void exporterPresentByDefault() {
|
||||
this.contextRunner.run(
|
||||
context ->
|
||||
assertThat(context.getBean("otelLoggingSpanExporter", LoggingSpanExporter.class))
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
|
||||
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
class OtlpMetricExporterAutoConfigurationTest {
|
||||
|
||||
private final ApplicationContextRunner runner =
|
||||
new ApplicationContextRunner()
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(
|
||||
OpenTelemetryAutoConfiguration.class, OtlpMetricExporterAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void otlpEnabled() {
|
||||
runner
|
||||
.withPropertyValues("otel.exporter.otlp.enabled=true")
|
||||
.run(
|
||||
context ->
|
||||
assertThat(
|
||||
context.getBean("otelOtlpGrpcMetricExporter", OtlpGrpcMetricExporter.class))
|
||||
.isNotNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
void otlpMetricsEnabled() {
|
||||
runner
|
||||
.withPropertyValues("otel.exporter.otlp.metrics.enabled=true")
|
||||
.run(
|
||||
context ->
|
||||
assertThat(
|
||||
context.getBean("otelOtlpGrpcMetricExporter", OtlpGrpcMetricExporter.class))
|
||||
.isNotNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
void otlpDisabled() {
|
||||
runner
|
||||
.withPropertyValues("otel.exporter.otlp.enabled=false")
|
||||
.run(context -> assertThat(context.containsBean("otelOtlpGrpcMetricExporter")).isFalse());
|
||||
}
|
||||
|
||||
@Test
|
||||
void otlpMetricsDisabled() {
|
||||
runner
|
||||
.withPropertyValues("otel.exporter.otlp.metrics.enabled=false")
|
||||
.run(context -> assertThat(context.containsBean("otelOtlpGrpcMetricExporter")).isFalse());
|
||||
}
|
||||
|
||||
@Test
|
||||
void exporterPresentByDefault() {
|
||||
runner.run(
|
||||
context ->
|
||||
assertThat(context.getBean("otelOtlpGrpcMetricExporter", OtlpGrpcMetricExporter.class))
|
||||
.isNotNull());
|
||||
}
|
||||
}
|
|
@ -3,32 +3,29 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.spring.autoconfigure.exporters;
|
||||
package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
|
||||
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
|
||||
import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpGrpcSpanExporterAutoConfiguration;
|
||||
import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpGrpcSpanExporterProperties;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
/** Spring Boot auto configuration test for {@link OtlpGrpcSpanExporterAutoConfiguration}. */
|
||||
class OtlpGrpcSpanExporterAutoConfigurationTest {
|
||||
/** Spring Boot auto configuration test for {@link OtlpSpanExporterAutoConfiguration}. */
|
||||
class OtlpSpanExporterAutoConfigurationTest {
|
||||
|
||||
private final ApplicationContextRunner contextRunner =
|
||||
new ApplicationContextRunner()
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(
|
||||
OpenTelemetryAutoConfiguration.class,
|
||||
OtlpGrpcSpanExporterAutoConfiguration.class));
|
||||
OpenTelemetryAutoConfiguration.class, OtlpSpanExporterAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
@DisplayName("when exporters are ENABLED should initialize OtlpGrpcSpanExporter bean")
|
||||
void exportersEnabled() {
|
||||
void otlpEnabled() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("otel.exporter.otlp.enabled=true")
|
||||
.run(
|
||||
|
@ -38,35 +35,33 @@ class OtlpGrpcSpanExporterAutoConfigurationTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
@DisplayName(
|
||||
"when otel.exporter.otlp properties are set should initialize OtlpGrpcSpanExporterProperties")
|
||||
void handlesProperties() {
|
||||
void otlpTracesEnabled() {
|
||||
this.contextRunner
|
||||
.withPropertyValues(
|
||||
"otel.exporter.otlp.enabled=true",
|
||||
"otel.exporter.otlp.endpoint=http://localhost:8080/test",
|
||||
"otel.exporter.otlp.timeout=69ms")
|
||||
.withPropertyValues("otel.exporter.otlp.traces.enabled=true")
|
||||
.run(
|
||||
context -> {
|
||||
OtlpGrpcSpanExporterProperties otlpSpanExporterProperties =
|
||||
context.getBean(OtlpGrpcSpanExporterProperties.class);
|
||||
assertThat(otlpSpanExporterProperties.getEndpoint())
|
||||
.isEqualTo("http://localhost:8080/test");
|
||||
assertThat(otlpSpanExporterProperties.getTimeout()).hasMillis(69);
|
||||
});
|
||||
context ->
|
||||
assertThat(context.getBean("otelOtlpGrpcSpanExporter", OtlpGrpcSpanExporter.class))
|
||||
.isNotNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("when exporters are DISABLED should NOT initialize OtlpGrpcSpanExporter bean")
|
||||
void disabledProperty() {
|
||||
void otlpDisabled() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("otel.exporter.otlp.enabled=false")
|
||||
.run(context -> assertThat(context.containsBean("otelOtlpGrpcSpanExporter")).isFalse());
|
||||
}
|
||||
|
||||
@Test
|
||||
void otlpTracesDisabled() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("otel.exporter.otlp.traces.enabled=false")
|
||||
.run(context -> assertThat(context.containsBean("otelOtlpGrpcSpanExporter")).isFalse());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("when otlp enabled property is MISSING should initialize OtlpGrpcSpanExporter bean")
|
||||
void noProperty() {
|
||||
void exporterPresentByDefault() {
|
||||
this.contextRunner.run(
|
||||
context ->
|
||||
assertThat(context.getBean("otelOtlpGrpcSpanExporter", OtlpGrpcSpanExporter.class))
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.spring.autoconfigure.metrics;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import io.micrometer.core.instrument.MeterRegistry;
|
||||
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
|
||||
import io.opentelemetry.micrometer1shim.OpenTelemetryMeterRegistry;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
|
||||
class MicrometerShimAutoConfigurationTest {
|
||||
|
||||
private final ApplicationContextRunner runner =
|
||||
new ApplicationContextRunner()
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(
|
||||
OpenTelemetryAutoConfiguration.class, MicrometerShimAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void metricsEnabled() {
|
||||
runner
|
||||
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class))
|
||||
.withPropertyValues("otel.springboot.micrometer.enabled = true")
|
||||
.run(
|
||||
context ->
|
||||
assertThat(context.getBean("micrometerShim", MeterRegistry.class))
|
||||
.isNotNull()
|
||||
.isInstanceOf(OpenTelemetryMeterRegistry.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void metricsEnabledByDefault() {
|
||||
runner
|
||||
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class))
|
||||
.run(
|
||||
context ->
|
||||
assertThat(context.getBean("micrometerShim", MeterRegistry.class))
|
||||
.isNotNull()
|
||||
.isInstanceOf(OpenTelemetryMeterRegistry.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void metricsDisabled() {
|
||||
runner
|
||||
.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class))
|
||||
.withPropertyValues("otel.springboot.micrometer.enabled = false")
|
||||
.run(context -> assertThat(context.containsBean("micrometerShim")).isFalse());
|
||||
}
|
||||
|
||||
@Test
|
||||
void noActuatorAutoConfiguration() {
|
||||
runner
|
||||
.withPropertyValues("otel.springboot.micrometer.enabled = true")
|
||||
.run(context -> assertThat(context.containsBean("micrometerShim")).isFalse());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue