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 470d4f919aa1..7ea9678cbff6 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 @@ -16,12 +16,18 @@ package org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront; +import java.util.Map; + import com.wavefront.sdk.common.WavefrontSender; +import com.wavefront.sdk.common.application.ApplicationTags; import io.micrometer.core.instrument.Clock; +import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.Tags; import io.micrometer.wavefront.WavefrontConfig; import io.micrometer.wavefront.WavefrontMeterRegistry; import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration; +import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer; 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; @@ -42,6 +48,7 @@ * @author Jon Schneider * @author Artsiom Yudovin * @author Stephane Nicoll + * @author Glenn Oppegard * @since 2.0.0 */ @AutoConfiguration( @@ -68,4 +75,17 @@ public WavefrontMeterRegistry wavefrontMeterRegistry(WavefrontConfig wavefrontCo return WavefrontMeterRegistry.builder(wavefrontConfig).clock(clock).wavefrontSender(wavefrontSender).build(); } + @Bean + @ConditionalOnBean(ApplicationTags.class) + @ConditionalOnClass(MeterRegistryCustomizer.class) + MeterRegistryCustomizer applicationTagsCustomizer(ApplicationTags applicationTags) { + Tags commonTags = Tags.of(applicationTags.toPointTags().entrySet().stream() + .map(WavefrontMetricsExportAutoConfiguration::asTag).toList()); + return (registry) -> registry.config().commonTags(commonTags); + } + + private static Tag asTag(Map.Entry entry) { + return Tag.of(entry.getKey(), entry.getValue()); + } + } 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 d8901202f041..cab7731afd87 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 @@ -16,12 +16,17 @@ package org.springframework.boot.actuate.autoconfigure.metrics.export.wavefront; +import java.util.Map; + import com.wavefront.sdk.common.WavefrontSender; +import com.wavefront.sdk.common.application.ApplicationTags; + import io.micrometer.core.instrument.Clock; import io.micrometer.wavefront.WavefrontConfig; import io.micrometer.wavefront.WavefrontMeterRegistry; 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; import org.springframework.context.annotation.Bean; @@ -36,6 +41,7 @@ * * @author Jon Schneider * @author Stephane Nicoll + * @author Glenn Oppegard */ class WavefrontMetricsExportAutoConfigurationTests { @@ -81,6 +87,24 @@ void allowsRegistryToBeCustomized() { .hasSingleBean(WavefrontMeterRegistry.class).hasBean("customRegistry")); } + @Test + void exportsApplicationTagsInWavefrontRegistry() { + ApplicationTags.Builder appTagsBuilder = new ApplicationTags.Builder("super-application", "super-service"); + appTagsBuilder.cluster("super-cluster"); + appTagsBuilder.shard("super-shard"); + appTagsBuilder.customTags(Map.of("custom-key", "custom-val")); + + this.contextRunner.withConfiguration(AutoConfigurations.of(MetricsAutoConfiguration.class)) + .withUserConfiguration(BaseConfiguration.class).withBean(ApplicationTags.class, appTagsBuilder::build) + .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").tags("custom-key", "custom-val").counter()).isNotNull(); + }); + } + @Test void stopsMeterRegistryWhenContextIsClosed() { this.contextRunner.withUserConfiguration(BaseConfiguration.class)