Skip to content

Commit

Permalink
Micrometer: allow veto of default MeterRegistry
Browse files Browse the repository at this point in the history
  • Loading branch information
ebullient committed May 29, 2021
1 parent e689e1c commit 8fffbd7
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package io.quarkus.micrometer.deployment;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BooleanSupplier;

import javax.enterprise.inject.Vetoed;

import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.ClassInfo;
Expand Down Expand Up @@ -96,6 +99,8 @@ MetricsCapabilityBuildItem metricsCapabilityPrometheusBuildItem(
@BuildStep(onlyIf = MicrometerEnabled.class)
UnremovableBeanBuildItem registerAdditionalBeans(CombinedIndexBuildItem indexBuildItem,
BuildProducer<MicrometerRegistryProviderBuildItem> providerClasses,
BuildProducer<AnnotationsTransformerBuildItem> annotationsTransformers,
List<VetoDefaultMeterRegistryBuildItem> vetoedRegistries,
BuildProducer<ReflectiveClassBuildItem> reflectiveClasses,
BuildProducer<AdditionalBeanBuildItem> additionalBeans) {

Expand All @@ -121,7 +126,7 @@ UnremovableBeanBuildItem registerAdditionalBeans(CombinedIndexBuildItem indexBui
IndexView index = indexBuildItem.getIndex();

// Find classes that define MeterRegistries, MeterBinders, and MeterFilters
Collection<String> knownRegistries = new HashSet<>();
final Collection<String> knownRegistries = new HashSet<>();
collectNames(index.getAllKnownSubclasses(METER_REGISTRY), knownRegistries);

Collection<String> knownClasses = new HashSet<>();
Expand Down Expand Up @@ -164,6 +169,34 @@ UnremovableBeanBuildItem registerAdditionalBeans(CombinedIndexBuildItem indexBui
}
}

if (vetoedRegistries.size() > 0) {
List<DotName> vetoedClassNames = new ArrayList<>();
for (VetoDefaultMeterRegistryBuildItem x : vetoedRegistries) {
vetoedClassNames.add(x.meterRegistryProducerClassName);
}

annotationsTransformers.produce(new AnnotationsTransformerBuildItem(new AnnotationsTransformer() {
@Override
public boolean appliesTo(AnnotationTarget.Kind kind) {
return kind == org.jboss.jandex.AnnotationTarget.Kind.METHOD;
}

@Override
public void transform(TransformationContext ctx) {
MethodInfo method = ctx.getTarget().asMethod();

// if this targets a class in the vetoedRegistries list
// and the method produces a known MeterRegistry type
// and it is a @Produces method .. veto it
if (vetoedClassNames.contains(method.declaringClass().name())
&& knownRegistries.contains(method.returnType().name().toString())
&& method.hasAnnotation(DotNames.PRODUCES)) {
ctx.transform().removeAll().add(Vetoed.class).done();
}
}
}));
}

reflectiveClasses.produce(createReflectiveBuildItem(COUNTED_ANNOTATION, index));
reflectiveClasses.produce(createReflectiveBuildItem(TIMED_ANNOTATION, index));
reflectiveClasses.produce(ReflectiveClassBuildItem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ public String toString() {
+ clazz
+ '}';
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package io.quarkus.micrometer.deployment;

import org.jboss.jandex.DotName;

import io.quarkus.builder.item.MultiBuildItem;

public final class VetoDefaultMeterRegistryBuildItem extends MultiBuildItem {
final DotName meterRegistryProducerClassName;

public VetoDefaultMeterRegistryBuildItem(Class<?> meterRegistryProducerClass) {
this(DotName.createSimple(meterRegistryProducerClass.getName()));
}

public VetoDefaultMeterRegistryBuildItem(DotName meterRegistryProducerClass) {
this.meterRegistryProducerClassName = meterRegistryProducerClass;
}

@Override
public String toString() {
return "VetoDefaultMeterRegistryBuildItem"
+ "{meterRegistryProducerClassName=" + meterRegistryProducerClassName
+ '}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.micrometer.deployment.MicrometerRegistryProviderBuildItem;
import io.quarkus.micrometer.deployment.VetoDefaultMeterRegistryBuildItem;
import io.quarkus.micrometer.runtime.MicrometerRecorder;
import io.quarkus.micrometer.runtime.config.MicrometerConfig;
import io.quarkus.micrometer.runtime.config.PrometheusConfigGroup;
Expand Down Expand Up @@ -39,13 +40,21 @@ public boolean getAsBoolean() {

@BuildStep(onlyIf = PrometheusEnabled.class)
MicrometerRegistryProviderBuildItem createPrometheusRegistry(
MicrometerConfig mConfig,
BuildProducer<VetoDefaultMeterRegistryBuildItem> vetoedRegistries,
BuildProducer<AdditionalBeanBuildItem> additionalBeans) {

// Add the Prometheus Registry Producer
additionalBeans.produce(AdditionalBeanBuildItem.builder()
.addBeanClass(PrometheusMeterRegistryProvider.class)
.setUnremovable().build());

PrometheusConfigGroup pConfig = mConfig.export.prometheus;
if (!pConfig.defaultRegistry) {
log.info("Default Prometheus MeterRegistry is disabled.");
vetoedRegistries.produce(new VetoDefaultMeterRegistryBuildItem(PrometheusMeterRegistryProvider.class));
}

// Include the PrometheusMeterRegistry in a possible CompositeMeterRegistry
return new MicrometerRegistryProviderBuildItem(REGISTRY_CLASS);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.quarkus.micrometer.deployment.export;

import java.util.Set;

import javax.inject.Inject;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.quarkus.micrometer.test.Util;
import io.quarkus.test.QuarkusUnitTest;

public class NoDefaultPrometheusTest {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.setFlatClassPath(true)
.withConfigurationResource("test-logging.properties")
.overrideConfigKey("quarkus.micrometer.binder-enabled-default", "false")
.overrideConfigKey("quarkus.micrometer.export.prometheus.enabled", "true")
.overrideConfigKey("quarkus.micrometer.export.prometheus.default-registry", "false")
.overrideConfigKey("quarkus.micrometer.registry-enabled-default", "false")
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(Util.class,
PrometheusRegistryProcessor.REGISTRY_CLASS,
SecondPrometheusProvider.class));

@Inject
MeterRegistry registry;

@Inject
PrometheusMeterRegistry promRegistry;

@Test
public void testMeterRegistryPresent() {
// Prometheus is enabled (only registry)
Assertions.assertNotNull(registry, "A registry should be configured");
Set<MeterRegistry> subRegistries = ((CompositeMeterRegistry) registry).getRegistries();

PrometheusMeterRegistry subPromRegistry = (PrometheusMeterRegistry) subRegistries.iterator().next();
Assertions.assertEquals(PrometheusMeterRegistry.class, subPromRegistry.getClass(), "Should be PrometheusMeterRegistry");
Assertions.assertEquals(subPromRegistry, promRegistry,
"The only MeterRegistry should be the same bean as the PrometheusMeterRegistry");

String result = promRegistry.scrape();
Assertions.assertTrue(result.contains("customKey=\"customValue\""),
"Scrape result should contain common tags from the custom registry configration. Found\n" + result);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ public class PrometheusEnabledTest {
.overrideConfigKey("quarkus.micrometer.binder-enabled-default", "false")
.overrideConfigKey("quarkus.micrometer.export.prometheus.enabled", "true")
.overrideConfigKey("quarkus.micrometer.registry-enabled-default", "false")
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClass(PrometheusRegistryProcessor.REGISTRY_CLASS));
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class));

@Inject
MeterRegistry registry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public class SecondPrometheusProvider {
@Produces
@Singleton
public PrometheusMeterRegistry registry(CollectorRegistry collectorRegistry, Clock clock) {
return new PrometheusMeterRegistry(PrometheusConfig.DEFAULT, collectorRegistry, clock);
PrometheusMeterRegistry customRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT, collectorRegistry,
clock);
customRegistry.config().commonTags("customKey", "customValue");
return customRegistry;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public void configureRegistries(MicrometerConfig config,
.getReference(i, MeterRegistry.class, beanManager.createCreationalContext(i));

// Add & configure non-root registries
if (registry != Metrics.globalRegistry) {
if (registry != Metrics.globalRegistry && registry != null) {
applyMeterFilters(registry, globalFilters);
applyMeterFilters(registry, classMeterFilters.get(registry.getClass()));
log.debugf("Adding configured registry %s", registry.getClass(), registry);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ public class PrometheusConfigGroup implements MicrometerConfig.CapabilityEnabled
@ConfigItem(defaultValue = "metrics")
public String path;

/**
* By default, this extension will create a Prometheus MeterRegistry instance.
* <p>
* Use this attribute to veto the creation of the default Prometheus MeterRegistry.
*/
@ConfigItem(defaultValue = "true")
public boolean defaultRegistry;

@Override
public Optional<Boolean> getEnabled() {
return enabled;
Expand All @@ -35,6 +43,7 @@ public String toString() {
return this.getClass().getSimpleName()
+ "{path='" + path
+ ",enabled=" + enabled
+ ",defaultRegistry=" + defaultRegistry
+ '}';
}
}

0 comments on commit 8fffbd7

Please sign in to comment.