From fb5cdbd11c3dbf9ea137223247a7b5477cfee7b1 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Thu, 17 Nov 2022 13:04:29 -0800 Subject: [PATCH] Create ApplicationTags in common WavefrontAutoConfiguration Relocate `ApplicationTags` `@Bean` method from `WavefrontTracingAutoConfiguration` to `WavefrontAutoConfiguration` since it is now shared between tracing and metrics. The `application-name`, `service-name`, `cluster-name` and `shard-name` have also been relocated from `management.wavefront.tracing` to `management.wavefront`. Fixes gh-33244 --- ...vefrontMetricsExportAutoConfiguration.java | 3 +- .../WavefrontTracingAutoConfiguration.java | 120 ++++++----------- .../wavefront/WavefrontAutoConfiguration.java | 82 ++++++++++++ .../wavefront/WavefrontProperties.java | 121 ++++++++---------- .../WavefrontSenderConfiguration.java | 2 +- ...ot.autoconfigure.AutoConfiguration.imports | 3 +- ...ntMetricsExportAutoConfigurationTests.java | 23 +++- ...avefrontTracingAutoConfigurationTests.java | 17 +-- .../WavefrontAutoConfigurationTests.java | 96 ++++++++++++++ 9 files changed, 302 insertions(+), 165 deletions(-) create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfiguration.java create mode 100644 spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfigurationTests.java diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfiguration.java index 4204950b7222..1bdf18344fe9 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfiguration.java @@ -31,6 +31,7 @@ import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport; import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties; import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontSenderConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -53,7 +54,7 @@ */ @AutoConfiguration( before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class }, - after = MetricsAutoConfiguration.class) + after = { MetricsAutoConfiguration.class, WavefrontAutoConfiguration.class }) @ConditionalOnBean(Clock.class) @ConditionalOnClass({ WavefrontMeterRegistry.class, WavefrontSender.class }) @ConditionalOnEnabledMetricsExport("wavefront") diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java index a07fb4217d95..e58316419d70 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfiguration.java @@ -17,7 +17,6 @@ package org.springframework.boot.actuate.autoconfigure.tracing.wavefront; import java.util.Collections; -import java.util.function.Supplier; import brave.handler.SpanHandler; import com.wavefront.sdk.common.WavefrontSender; @@ -32,8 +31,8 @@ import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.tracing.ConditionalOnEnabledTracing; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties; -import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties.Tracing; import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontSenderConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -41,12 +40,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.core.env.Environment; -import org.springframework.util.StringUtils; /** * {@link EnableAutoConfiguration Auto-configuration} for Wavefront tracing. @@ -55,107 +51,67 @@ * @author Glenn Oppegard * @since 3.0.0 */ -@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class }) +@AutoConfiguration(after = { MetricsAutoConfiguration.class, CompositeMeterRegistryAutoConfiguration.class, + WavefrontAutoConfiguration.class }) +@ConditionalOnClass({ WavefrontSender.class, WavefrontSpanHandler.class }) +@ConditionalOnEnabledTracing @EnableConfigurationProperties(WavefrontProperties.class) -@ConditionalOnClass(WavefrontSender.class) @Import(WavefrontSenderConfiguration.class) -@ConditionalOnEnabledTracing public class WavefrontTracingAutoConfiguration { - /** - * Default value for the Wavefront Application name. - * @see Wavefront - * Application Tags - */ - private static final String DEFAULT_APPLICATION_NAME = "unnamed_application"; - - /** - * Default value for the Wavefront Service name if {@code spring.application.name} is - * not set. - * @see Wavefront - * Application Tags - */ - private static final String DEFAULT_SERVICE_NAME = "unnamed_service"; - @Bean @ConditionalOnMissingBean - public ApplicationTags wavefrontApplicationTags(Environment environment, WavefrontProperties properties) { - Tracing tracing = properties.getTracing(); - String wavefrontServiceName = getName(tracing.getServiceName(), - () -> environment.getProperty("spring.application.name", DEFAULT_SERVICE_NAME)); - String wavefrontApplicationName = getName(tracing.getApplicationName(), () -> DEFAULT_APPLICATION_NAME); - PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); - ApplicationTags.Builder builder = new ApplicationTags.Builder(wavefrontApplicationName, wavefrontServiceName); - map.from(tracing::getClusterName).to(builder::cluster); - map.from(tracing::getShardName).to(builder::shard); - return builder.build(); - } - - private String getName(String value, Supplier fallback) { - return (StringUtils.hasText(value)) ? value : fallback.get(); + @ConditionalOnBean(WavefrontSender.class) + WavefrontSpanHandler wavefrontSpanHandler(WavefrontProperties properties, WavefrontSender wavefrontSender, + SpanMetrics spanMetrics, ApplicationTags applicationTags) { + return new WavefrontSpanHandler(properties.getSender().getMaxQueueSize(), wavefrontSender, spanMetrics, + properties.getSourceOrDefault(), applicationTags, Collections.emptySet()); } @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(WavefrontSpanHandler.class) - static class WavefrontMicrometer { + @ConditionalOnBean(MeterRegistry.class) + static class MeterRegistrySpanMetricsConfiguration { @Bean @ConditionalOnMissingBean - @ConditionalOnBean(WavefrontSender.class) - WavefrontSpanHandler wavefrontSpanHandler(WavefrontProperties properties, WavefrontSender wavefrontSender, - SpanMetrics spanMetrics, ApplicationTags applicationTags) { - return new WavefrontSpanHandler(properties.getSender().getMaxQueueSize(), wavefrontSender, spanMetrics, - properties.getSourceOrDefault(), applicationTags, Collections.emptySet()); + MeterRegistrySpanMetrics meterRegistrySpanMetrics(MeterRegistry meterRegistry) { + return new MeterRegistrySpanMetrics(meterRegistry); } - @Configuration(proxyBeanMethods = false) - @ConditionalOnBean(MeterRegistry.class) - static class MeterRegistrySpanMetricsConfiguration { - - @Bean - @ConditionalOnMissingBean - MeterRegistrySpanMetrics meterRegistrySpanMetrics(MeterRegistry meterRegistry) { - return new MeterRegistrySpanMetrics(meterRegistry); - } - - } - - @Configuration(proxyBeanMethods = false) - @ConditionalOnMissingBean(MeterRegistry.class) - static class NoopSpanMetricsConfiguration { + } - @Bean - @ConditionalOnMissingBean - SpanMetrics meterRegistrySpanMetrics() { - return SpanMetrics.NOOP; - } + @Configuration(proxyBeanMethods = false) + @ConditionalOnMissingBean(MeterRegistry.class) + static class NoopSpanMetricsConfiguration { + @Bean + @ConditionalOnMissingBean + SpanMetrics meterRegistrySpanMetrics() { + return SpanMetrics.NOOP; } - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(SpanHandler.class) - static class WavefrontBrave { + } - @Bean - @ConditionalOnMissingBean - WavefrontBraveSpanHandler wavefrontBraveSpanHandler(WavefrontSpanHandler wavefrontSpanHandler) { - return new WavefrontBraveSpanHandler(wavefrontSpanHandler); - } + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(SpanHandler.class) + static class WavefrontBrave { + @Bean + @ConditionalOnMissingBean + WavefrontBraveSpanHandler wavefrontBraveSpanHandler(WavefrontSpanHandler wavefrontSpanHandler) { + return new WavefrontBraveSpanHandler(wavefrontSpanHandler); } - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(SpanExporter.class) - static class WavefrontOpenTelemetry { + } - @Bean - @ConditionalOnMissingBean - WavefrontOtelSpanExporter wavefrontOtelSpanExporter(WavefrontSpanHandler wavefrontSpanHandler) { - return new WavefrontOtelSpanExporter(wavefrontSpanHandler); - } + @Configuration(proxyBeanMethods = false) + @ConditionalOnClass(SpanExporter.class) + static class WavefrontOpenTelemetry { + @Bean + @ConditionalOnMissingBean + WavefrontOtelSpanExporter wavefrontOtelSpanExporter(WavefrontSpanHandler wavefrontSpanHandler) { + return new WavefrontOtelSpanExporter(wavefrontSpanHandler); } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfiguration.java new file mode 100644 index 000000000000..6dc0c052b304 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfiguration.java @@ -0,0 +1,82 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * 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 + * + * https://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 org.springframework.boot.actuate.autoconfigure.wavefront; + +import java.util.function.Supplier; + +import com.wavefront.sdk.common.WavefrontSender; +import com.wavefront.sdk.common.application.ApplicationTags; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.context.properties.PropertyMapper; +import org.springframework.context.annotation.Bean; +import org.springframework.core.env.Environment; +import org.springframework.util.StringUtils; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for for Wavefront common + * infrastructure. + * + * @author Moritz Halbritter + * @author Glenn Oppegard + * @author Phillip Webb + * @since 3.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ ApplicationTags.class, WavefrontSender.class }) +@EnableConfigurationProperties(WavefrontProperties.class) +public class WavefrontAutoConfiguration { + + /** + * Default value for the Wavefront Service name if {@code spring.application.name} is + * not set. + * @see Wavefront + * Application Tags + */ + private static final String DEFAULT_SERVICE_NAME = "unnamed_service"; + + /** + * Default value for the Wavefront Application name. + * @see Wavefront + * Application Tags + */ + private static final String DEFAULT_APPLICATION_NAME = "unnamed_application"; + + @Bean + @ConditionalOnMissingBean + public ApplicationTags wavefrontApplicationTags(Environment environment, WavefrontProperties properties) { + String wavefrontServiceName = getName(properties.getServiceName(), + () -> environment.getProperty("spring.application.name", DEFAULT_SERVICE_NAME)); + String wavefrontApplicationName = getName(properties.getApplicationName(), () -> DEFAULT_APPLICATION_NAME); + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); + ApplicationTags.Builder builder = new ApplicationTags.Builder(wavefrontApplicationName, wavefrontServiceName); + map.from(properties::getClusterName).to(builder::cluster); + map.from(properties::getShardName).to(builder::shard); + return builder.build(); + } + + private String getName(String value, Supplier fallback) { + return (StringUtils.hasText(value)) ? value : fallback.get(); + } + +} diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontProperties.java index 4d8fac75fa33..dc2a407b2b8d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontProperties.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontProperties.java @@ -53,6 +53,28 @@ public class WavefrontProperties { */ private String apiToken; + /** + * Wavefront Application name used in ApplicationTags. Defaults to + * 'unnamed_application'. + */ + private String applicationName; + + /** + * Wavefront Service name used in ApplicationTags, falling back to + * 'spring.application.name'. If both are unset it defaults to 'unnamed_service'. + */ + private String serviceName; + + /** + * Optional Wavefront Cluster name used in ApplicationTags. + */ + private String clusterName; + + /** + * Optional Wavefront Shard name used in ApplicationTags. + */ + private String shardName; + /** * Sender configuration. */ @@ -63,11 +85,6 @@ public class WavefrontProperties { */ private final Metrics metrics = new Metrics(); - /** - * Tracing configuration. - */ - private final Tracing tracing = new Tracing(); - public Sender getSender() { return this.sender; } @@ -76,10 +93,6 @@ public Metrics getMetrics() { return this.metrics; } - public Tracing getTracing() { - return this.tracing; - } - public URI getUri() { return this.uri; } @@ -104,6 +117,38 @@ public void setApiToken(String apiToken) { this.apiToken = apiToken; } + public String getServiceName() { + return this.serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getApplicationName() { + return this.applicationName; + } + + public void setApplicationName(String applicationName) { + this.applicationName = applicationName; + } + + public String getClusterName() { + return this.clusterName; + } + + public void setClusterName(String clusterName) { + this.clusterName = clusterName; + } + + public String getShardName() { + return this.shardName; + } + + public void setShardName(String shardName) { + this.shardName = shardName; + } + /** * Returns the effective URI of the wavefront instance. This will not be the same URI * given through {@link #setUri(URI)} when a proxy is used. @@ -259,62 +304,4 @@ public void setBatchSize(Integer batchSize) { } - public static class Tracing { - - /** - * Wavefront Application name used in ApplicationTags. Defaults to - * 'unnamed_application'. - */ - private String applicationName; - - /** - * Wavefront Service name used in ApplicationTags, falling back to - * 'spring.application.name'. If both are unset it defaults to 'unnamed_service'. - */ - private String serviceName; - - /** - * Optional Wavefront Cluster name used in ApplicationTags. - */ - private String clusterName; - - /** - * Optional Wavefront Shard name used in ApplicationTags. - */ - private String shardName; - - public String getServiceName() { - return this.serviceName; - } - - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - public String getApplicationName() { - return this.applicationName; - } - - public void setApplicationName(String applicationName) { - this.applicationName = applicationName; - } - - public String getClusterName() { - return this.clusterName; - } - - public void setClusterName(String clusterName) { - this.clusterName = clusterName; - } - - public String getShardName() { - return this.shardName; - } - - public void setShardName(String shardName) { - this.shardName = shardName; - } - - } - } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontSenderConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontSenderConfiguration.java index eb14940697a3..6cb11ae31df3 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontSenderConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontSenderConfiguration.java @@ -32,7 +32,7 @@ import org.springframework.util.unit.DataSize; /** - * Configuration for Wavefront common infrastructure. This configuration is imported from + * Configuration for {@link WavefrontSender}. This configuration is imported from * {@link WavefrontMetricsExportAutoConfiguration} and * {@link WavefrontTracingAutoConfiguration}. * diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index a1a38524d95b..c4f5e4c08f60 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -103,9 +103,10 @@ org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfigur org.springframework.boot.actuate.autoconfigure.tracing.prometheus.PrometheusExemplarsAutoConfiguration org.springframework.boot.actuate.autoconfigure.tracing.wavefront.WavefrontTracingAutoConfiguration org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinAutoConfiguration +org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.exchanges.HttpExchangesEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.mappings.MappingsEndpointAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration -org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration +org.springframework.boot.actuate.autoconfigure.web.servlet.ServletManagementContextAutoConfiguration \ No newline at end of file diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfigurationTests.java index 28efcc5463ab..9487d4df9d4b 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/metrics/export/wavefront/WavefrontMetricsExportAutoConfigurationTests.java @@ -26,6 +26,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; @@ -44,8 +45,8 @@ */ class WavefrontMetricsExportAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(WavefrontMetricsExportAutoConfiguration.class)); + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration( + AutoConfigurations.of(WavefrontAutoConfiguration.class, WavefrontMetricsExportAutoConfiguration.class)); @Test void backsOffWithoutAClock() { @@ -87,7 +88,7 @@ void allowsRegistryToBeCustomized() { } @Test - void exportsApplicationTagsInWavefrontRegistry() { + void exportsApplicationTagsInWavefrontRegistryWhenApplicationTagsBean() { ApplicationTags.Builder builder = new ApplicationTags.Builder("super-application", "super-service"); builder.cluster("super-cluster"); builder.shard("super-shard"); @@ -103,6 +104,22 @@ void exportsApplicationTagsInWavefrontRegistry() { }); } + @Test + void exportsApplicationTagsInWavefrontRegistryWhenInProperties() { + this.contextRunner.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class)) + .withPropertyValues("management.wavefront.service-name=super-service", + "management.wavefront.application-name=super-application", + "management.wavefront.cluster-name=super-cluster", + "management.wavefront.shard-name=super-shard") + .withUserConfiguration(BaseConfiguration.class).run((context) -> { + WavefrontMeterRegistry registry = context.getBean(WavefrontMeterRegistry.class); + registry.counter("my.counter", "env", "qa"); + assertThat(registry.find("my.counter").tags("env", "qa").tags("application", "super-application") + .tags("service", "super-service").tags("cluster", "super-cluster") + .tags("shard", "super-shard").counter()).isNotNull(); + }); + } + @Test void stopsMeterRegistryWhenContextIsClosed() { this.contextRunner.withUserConfiguration(BaseConfiguration.class) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java index c4926b7e955b..07b6d987fa65 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/wavefront/WavefrontTracingAutoConfigurationTests.java @@ -26,6 +26,7 @@ import io.micrometer.tracing.reporter.wavefront.WavefrontSpanHandler; import org.junit.jupiter.api.Test; +import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontAutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -43,8 +44,8 @@ */ class WavefrontTracingAutoConfigurationTests { - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(WavefrontTracingAutoConfiguration.class)); + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration( + AutoConfigurations.of(WavefrontAutoConfiguration.class, WavefrontTracingAutoConfiguration.class)); @Test void shouldSupplyBeans() { @@ -83,7 +84,6 @@ void shouldNotSupplyBeansIfMicrometerReporterWavefrontIsMissing() { void shouldNotSupplyBeansIfTracingIsDisabled() { this.contextRunner.withPropertyValues("management.tracing.enabled=false") .withUserConfiguration(WavefrontSenderConfiguration.class).run((context) -> { - assertThat(context).doesNotHaveBean(ApplicationTags.class); assertThat(context).doesNotHaveBean(WavefrontSpanHandler.class); assertThat(context).doesNotHaveBean(SpanMetrics.class); assertThat(context).doesNotHaveBean(WavefrontBraveSpanHandler.class); @@ -137,13 +137,10 @@ void shouldUseSpringApplicationNameForServiceName() { @Test void shouldHonorConfigProperties() { - this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class) - .withPropertyValues("spring.application.name=ignored", - "management.wavefront.tracing.application-name=super-application", - "management.wavefront.tracing.service-name=super-service", - "management.wavefront.tracing.cluster-name=super-cluster", - "management.wavefront.tracing.shard-name=super-shard") - .run((context) -> { + this.contextRunner.withUserConfiguration(WavefrontSenderConfiguration.class).withPropertyValues( + "spring.application.name=ignored", "management.wavefront.application-name=super-application", + "management.wavefront.service-name=super-service", "management.wavefront.cluster-name=super-cluster", + "management.wavefront.shard-name=super-shard").run((context) -> { ApplicationTags applicationTags = context.getBean(ApplicationTags.class); assertThat(applicationTags.getApplication()).isEqualTo("super-application"); assertThat(applicationTags.getService()).isEqualTo("super-service"); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfigurationTests.java new file mode 100644 index 000000000000..378925c401d7 --- /dev/null +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/wavefront/WavefrontAutoConfigurationTests.java @@ -0,0 +1,96 @@ +/* + * Copyright 2012-2022 the original author or authors. + * + * 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 + * + * https://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 org.springframework.boot.actuate.autoconfigure.wavefront; + +import java.util.ArrayList; +import java.util.List; + +import com.wavefront.sdk.common.application.ApplicationTags; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WavefrontAutoConfiguration}. + * + * @author Phillip Webb + */ +class WavefrontAutoConfigurationTests { + + ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(WavefrontAutoConfiguration.class)); + + @Test + void wavefrontApplicationTagsWhenHasUserBeanBacksOff() { + this.contextRunner.withUserConfiguration(TestApplicationTagsConfiguration.class).run((context) -> { + ApplicationTags tags = context.getBean(ApplicationTags.class); + assertThat(tags.getApplication()).isEqualTo("test-application"); + assertThat(tags.getService()).isEqualTo("test-service"); + }); + } + + @Test + void wavefrontApplicationTagsMapsProperties() { + List properties = new ArrayList<>(); + properties.add("management.wavefront.application-name=test-application"); + properties.add("management.wavefront.service-name=test-service"); + properties.add("management.wavefront.cluster-name=test-cluster"); + properties.add("management.wavefront.shard-name=test-shard"); + this.contextRunner.withPropertyValues(properties.toArray(String[]::new)).run((context) -> { + ApplicationTags tags = context.getBean(ApplicationTags.class); + assertThat(tags.getApplication()).isEqualTo("test-application"); + assertThat(tags.getService()).isEqualTo("test-service"); + assertThat(tags.getCluster()).isEqualTo("test-cluster"); + assertThat(tags.getShard()).isEqualTo("test-shard"); + }); + } + + @Test + void wavefrontApplicationTagsWhenNoPropertiesUsesDefaults() { + this.contextRunner.withPropertyValues("spring.application.name=spring-app").run((context) -> { + ApplicationTags tags = context.getBean(ApplicationTags.class); + assertThat(tags.getApplication()).isEqualTo("unnamed_application"); + assertThat(tags.getService()).isEqualTo("spring-app"); + assertThat(tags.getCluster()).isNull(); + assertThat(tags.getShard()).isNull(); + }); + } + + @Test + void wavefrontApplicationTagsWhenHasNoServiceNamePropertyAndNoSpringApplicationNameUsesDefault() { + this.contextRunner.run((context) -> { + ApplicationTags tags = context.getBean(ApplicationTags.class); + assertThat(tags.getService()).isEqualTo("unnamed_service"); + }); + } + + @Configuration(proxyBeanMethods = false) + static class TestApplicationTagsConfiguration { + + @Bean + ApplicationTags applicationTags() { + return new ApplicationTags.Builder("test-application", "test-service").build(); + } + + } + +}