diff --git a/wavefront-spring-boot-bom/pom.xml b/wavefront-spring-boot-bom/pom.xml index 14a140e..c379f9f 100644 --- a/wavefront-spring-boot-bom/pom.xml +++ b/wavefront-spring-boot-bom/pom.xml @@ -47,6 +47,21 @@ + + + src/main/resources + + META-INF/wavefront-spring-boot/*.properties + + + + src/main/resources + true + + META-INF/wavefront-spring-boot/*.properties + + + org.codehaus.mojo diff --git a/wavefront-spring-boot/src/main/java/com/wavefront/spring/autoconfigure/WavefrontMetricsConfiguration.java b/wavefront-spring-boot/src/main/java/com/wavefront/spring/autoconfigure/WavefrontMetricsConfiguration.java index bac9aa3..386df99 100644 --- a/wavefront-spring-boot/src/main/java/com/wavefront/spring/autoconfigure/WavefrontMetricsConfiguration.java +++ b/wavefront-spring-boot/src/main/java/com/wavefront/spring/autoconfigure/WavefrontMetricsConfiguration.java @@ -1,10 +1,15 @@ package com.wavefront.spring.autoconfigure; +import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import com.wavefront.internal.reporter.WavefrontInternalReporter; +import com.wavefront.internal_reporter_java.io.dropwizard.metrics5.MetricName; import com.wavefront.sdk.appagent.jvm.reporter.WavefrontJvmReporter; +import com.wavefront.sdk.common.Utils; import com.wavefront.sdk.common.WavefrontSender; import com.wavefront.sdk.common.application.ApplicationTags; import io.micrometer.core.instrument.Tag; @@ -31,6 +36,7 @@ @Configuration(proxyBeanMethods = false) @ConditionalOnBean(WavefrontSender.class) class WavefrontMetricsConfiguration { + public static final String SDK_INTERNAL_METRIC_PREFIX = "~sdk.java.wavefront_spring_boot_starter"; @Bean @ConditionalOnMissingBean @@ -43,6 +49,18 @@ WavefrontJvmReporter wavefrontJvmReporter(WavefrontSender wavefrontSender, Appli return reporter; } + @Bean + @ConditionalOnMissingBean + WavefrontInternalReporter wavefrontInternalReporter(WavefrontSender wavefrontSender, + WavefrontConfig wavefrontConfig) { + WavefrontInternalReporter reporter = new WavefrontInternalReporter.Builder(). + prefixedWith(SDK_INTERNAL_METRIC_PREFIX).withSource(wavefrontConfig.source()). + build(wavefrontSender); + Double sdkVersion = Utils.getSemVerGauge("wavefront-spring-boot"); + reporter.newGauge(new MetricName("version", Collections.EMPTY_MAP), () -> (() -> sdkVersion)); + reporter.start(1, TimeUnit.MINUTES); + return reporter; + } @Configuration(proxyBeanMethods = false) @ConditionalOnClass({ WavefrontMeterRegistry.class, MeterRegistryCustomizer.class }) diff --git a/wavefront-spring-boot/src/main/java/com/wavefront/spring/autoconfigure/WavefrontSleuthSpanHandler.java b/wavefront-spring-boot/src/main/java/com/wavefront/spring/autoconfigure/WavefrontSleuthSpanHandler.java index 284e6a2..e231759 100644 --- a/wavefront-spring-boot/src/main/java/com/wavefront/spring/autoconfigure/WavefrontSleuthSpanHandler.java +++ b/wavefront-spring-boot/src/main/java/com/wavefront/spring/autoconfigure/WavefrontSleuthSpanHandler.java @@ -24,6 +24,7 @@ import com.wavefront.java_sdk.com.google.common.collect.Sets; import com.wavefront.sdk.common.NamedThreadFactory; import com.wavefront.sdk.common.Pair; +import com.wavefront.sdk.common.Utils; import com.wavefront.sdk.common.WavefrontSender; import com.wavefront.sdk.common.application.ApplicationTags; import com.wavefront.sdk.entities.tracing.SpanLog; diff --git a/wavefront-spring-boot/src/main/resources/META-INF/wavefront-spring-boot/build.properties b/wavefront-spring-boot/src/main/resources/META-INF/wavefront-spring-boot/build.properties new file mode 100644 index 0000000..616e4be --- /dev/null +++ b/wavefront-spring-boot/src/main/resources/META-INF/wavefront-spring-boot/build.properties @@ -0,0 +1 @@ +project.version=${project.version} \ No newline at end of file diff --git a/wavefront-spring-boot/src/test/java/com/wavefront/spring/autoconfigure/WavefrontAutoConfigurationTests.java b/wavefront-spring-boot/src/test/java/com/wavefront/spring/autoconfigure/WavefrontAutoConfigurationTests.java index fe1ec5a..609330f 100644 --- a/wavefront-spring-boot/src/test/java/com/wavefront/spring/autoconfigure/WavefrontAutoConfigurationTests.java +++ b/wavefront-spring-boot/src/test/java/com/wavefront/spring/autoconfigure/WavefrontAutoConfigurationTests.java @@ -1,5 +1,7 @@ package com.wavefront.spring.autoconfigure; +import java.lang.reflect.Field; +import java.util.Collections; import java.util.Set; import java.util.function.Function; import java.util.function.Supplier; @@ -7,6 +9,10 @@ import brave.Tracer; import brave.TracingCustomizer; import brave.handler.SpanHandler; + +import com.wavefront.internal.reporter.WavefrontInternalReporter; +import com.wavefront.internal_reporter_java.io.dropwizard.metrics5.MetricName; +import com.wavefront.internal_reporter_java.io.dropwizard.metrics5.MetricRegistry; import com.wavefront.opentracing.WavefrontTracer; import com.wavefront.opentracing.reporting.Reporter; import com.wavefront.sdk.appagent.jvm.reporter.WavefrontJvmReporter; @@ -29,6 +35,7 @@ import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration; import org.springframework.test.util.ReflectionTestUtils; +import static com.wavefront.spring.autoconfigure.WavefrontMetricsConfiguration.SDK_INTERNAL_METRIC_PREFIX; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; @@ -136,6 +143,42 @@ void applicationTagsAreNotExportedToNonWavefrontRegistry() { }); } + @Test + void internalReporterIsConfiguredWhenNoneExists() { + this.contextRunner + .with(wavefrontMetrics(() -> mock(WavefrontSender.class))) + .run((context) -> { + assertThat(context).hasSingleBean(WavefrontInternalReporter.class); + MetricRegistry internalMetricRegistry = (MetricRegistry)extractMetricRegistry(context + .getBean(WavefrontInternalReporter.class)); + assertThat(internalMetricRegistry.getGauges().containsKey(new MetricName + (SDK_INTERNAL_METRIC_PREFIX + ".version", Collections.EMPTY_MAP))); + }); + } + + private Object extractMetricRegistry(WavefrontInternalReporter wavefrontInternalReporter) throws + NoSuchFieldException, IllegalAccessException { + Field field = wavefrontInternalReporter.getClass().getDeclaredField("internalRegistry"); + field.setAccessible(true); + return field.get(wavefrontInternalReporter); + } + + @Test + void internalReporterCanBeCustomized() { + WavefrontInternalReporter reporter = mock(WavefrontInternalReporter.class); + this.contextRunner + .with(wavefrontMetrics(() -> mock(WavefrontSender.class))) + .withBean(WavefrontInternalReporter.class, () -> reporter) + .run((context) -> assertThat(context).getBean(WavefrontInternalReporter.class).isEqualTo(reporter)); + } + + @Test + void internalReporterNotConfiguredWithoutWavefrontSender() { + this.contextRunner + .with(metrics()) + .run(context -> assertThat(context).doesNotHaveBean(WavefrontInternalReporter.class)); + } + @Test void jvmReporterIsConfiguredWhenNoneExists() { this.contextRunner