CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-quarkus--quarkus-micrometer-deployment

Quarkus Micrometer deployment module that provides build-time processing for metrics collection and monitoring capabilities in Quarkus applications

Pending
Overview
Eval results
Files

mp-metrics-compatibility.mddocs/

MicroProfile Metrics Compatibility

Compatibility layer providing seamless migration from MicroProfile Metrics to Micrometer, enabling existing applications to use MicroProfile Metrics annotations while leveraging Micrometer's backend infrastructure.

Capabilities

MicroProfile Metrics Processor

Main processor that handles MicroProfile Metrics API compatibility and annotation transformation.

/**
 * Deployment processor for MicroProfile Metrics API compatibility
 */
@BuildSteps
public class MicroprofileMetricsProcessor {
    
    /**
     * Adds MP Metrics API dependency to Jandex index
     * @return IndexDependencyBuildItem for MP Metrics API
     */
    @BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
    public IndexDependencyBuildItem addDependencies();
    
    /**
     * Enables auto-injection of @Metric annotations
     * @return AnnotationsTransformerBuildItem for @Metric injection
     */
    @BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
    public AnnotationsTransformerBuildItem autoInjectMetric();
    
    /**
     * Registers MP Metrics beans for CDI
     * @return AdditionalBeanBuildItem with MP Metrics bean classes
     */
    @BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
    public AdditionalBeanBuildItem registerBeanClasses();
    
    /**
     * Logs compatibility warnings for MP Metrics usage
     * @param indexBuildItem Combined index for annotation scanning
     */
    @BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
    public void logWarningForMpMetricsUsage(CombinedIndexBuildItem indexBuildItem);
    
    /**
     * Adds @Dependent scope to metrics beans
     * @return AnnotationsTransformerBuildItem for scope transformation
     */
    @BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
    public AnnotationsTransformerBuildItem transformBeanScope();
    
    /**
     * Processes MP Metrics annotations and generates adapter classes
     * @param indexBuildItem Combined index for annotation processing
     * @param generatedClasses Producer for generated class build items
     */
    @BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
    public void processAnnotatedMetrics(
        CombinedIndexBuildItem indexBuildItem,
        BuildProducer<GeneratedClassBuildItem> generatedClasses
    );
    
    /**
     * Configures MP Metrics registry adapter
     * @param rootRegistry Root meter registry build item
     * @return SyntheticBeanBuildItem for registry adapter
     */
    @BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
    @Record(ExecutionTime.RUNTIME_INIT)
    public SyntheticBeanBuildItem configureRegistry(
        RootMeterRegistryBuildItem rootRegistry
    );
    
    // Enablement condition
    public static class MicroprofileMetricsEnabled implements BooleanSupplier;
}

Metric Annotation Constants

Utility class providing DotName constants for all MicroProfile Metrics annotations.

/**
 * Constants for MicroProfile Metrics DotNames and utilities
 */
public final class MetricDotNames {
    
    // Package constant
    public static final String MICROMETER_EXTENSION_PKG = "io.quarkus.micrometer.runtime.binder.mpmetrics";
    
    // MP Metrics binder
    public static final DotName MP_METRICS_BINDER = DotName
        .createSimple("io.quarkus.micrometer.runtime.binder.mpmetrics.MpMetricsBinder");
    
    // MP Metrics annotation DotNames
    public static final DotName CONCURRENT_GAUGE_ANNOTATION = DotName
        .createSimple("org.eclipse.microprofile.metrics.annotation.ConcurrentGauge");
    public static final DotName COUNTED_ANNOTATION = DotName
        .createSimple("org.eclipse.microprofile.metrics.annotation.Counted");
    public static final DotName GAUGE_ANNOTATION = DotName
        .createSimple("org.eclipse.microprofile.metrics.annotation.Gauge");
    public static final DotName METERED_ANNOTATION = DotName
        .createSimple("org.eclipse.microprofile.metrics.annotation.Metered");
    public static final DotName SIMPLY_TIMED_ANNOTATION = DotName
        .createSimple("org.eclipse.microprofile.metrics.annotation.SimplyTimed");
    public static final DotName TIMED_ANNOTATION = DotName
        .createSimple("org.eclipse.microprofile.metrics.annotation.Timed");
    
    // Registry and metrics DotNames
    public static final DotName METRIC_REGISTRY = DotName
        .createSimple("org.eclipse.microprofile.metrics.MetricRegistry");
    public static final DotName METRIC_ANNOTATION = DotName
        .createSimple("org.eclipse.microprofile.metrics.annotation.Metric");
    public static final DotName METRIC = DotName
        .createSimple("org.eclipse.microprofile.metrics.Metric");
    public static final DotName ANNOTATED_GAUGE_ADAPTER = DotName
        .createSimple("io.quarkus.micrometer.runtime.binder.mpmetrics.AnnotatedGaugeAdapter");
    
    // JAX-RS and REST related DotNames
    public static final DotName JAXRS_PATH = DotName.createSimple("jakarta.ws.rs.Path");
    public static final DotName REST_CONTROLLER = DotName
        .createSimple("org.springframework.web.bind.annotation.RestController");
    
    // Interceptor and producer DotNames
    public static final DotName CONCURRENT_GAUGE_INTERCEPTOR = DotName
        .createSimple("io.quarkus.micrometer.runtime.binder.mpmetrics.ConcurrentGaugeInterceptor");
    public static final DotName COUNTED_INTERCEPTOR = DotName
        .createSimple("io.quarkus.micrometer.runtime.binder.mpmetrics.CountedInterceptor");
    public static final DotName INJECTED_METRIC_PRODUCER = DotName
        .createSimple("io.quarkus.micrometer.runtime.binder.mpmetrics.InjectedMetricProducer");
    public static final DotName TIMED_INTERCEPTOR = DotName
        .createSimple("io.quarkus.micrometer.runtime.binder.mpmetrics.TimedInterceptor");
    public static final DotName MP_METRICS_REGISTRY_PRODUCER = DotName
        .createSimple("io.quarkus.micrometer.runtime.binder.mpmetrics.MpMetricsRegistryProducer");
    
    // Set of all individual metric annotation DotNames
    public static final Set<DotName> individualMetrics = new HashSet<>(Arrays.asList(
        CONCURRENT_GAUGE_ANNOTATION,
        COUNTED_ANNOTATION,
        GAUGE_ANNOTATION,
        METERED_ANNOTATION,
        SIMPLY_TIMED_ANNOTATION,
        TIMED_ANNOTATION
    ));
    
    /**
     * Check if annotation map contains any MP Metrics annotations
     * @param annotations Map of annotations to check
     * @return true if any MP Metrics annotations are present
     */
    public static boolean containsMetricAnnotation(Map<DotName, List<AnnotationInstance>> annotations);
    
    /**
     * Check if class is a known metrics subsystem class
     * @param classInfo Class information to analyze
     * @return true if class is part of metrics subsystem
     */
    public static boolean knownClass(ClassInfo classInfo);
    
    /**
     * Check if class is single-instance (REST endpoint or singleton scope)
     * @param classInfo Class information to analyze
     * @return true if class is single-instance
     */
    public static boolean isSingleInstance(ClassInfo classInfo);
}

Annotation Transformation Handler

Utility class for transforming MicroProfile Metrics annotations to Micrometer equivalents.

/**
 * Utility for transforming MP Metrics annotations for Micrometer compatibility
 */
public final class AnnotationHandler {
    
    /**
     * Creates annotation transformer for single annotation type
     * @param index Jandex index for annotation scanning
     * @param sourceAnnotation Source MP Metrics annotation to transform
     * @return AnnotationTransformerBuildItem for transformation
     */
    public static AnnotationTransformerBuildItem transformAnnotations(
        IndexView index, 
        DotName sourceAnnotation
    );
    
    /**
     * Creates annotation transformer with source and target annotations
     * @param index Jandex index for annotation scanning
     * @param sourceAnnotation Source MP Metrics annotation
     * @param targetAnnotation Target Micrometer annotation
     * @return AnnotationTransformerBuildItem for transformation
     */
    public static AnnotationTransformerBuildItem transformAnnotations(
        IndexView index,
        DotName sourceAnnotation,
        DotName targetAnnotation
    );
    
    /**
     * Removes @Counted annotation when @Timed is present (avoids duplication)
     * @param index Jandex index for annotation scanning
     * @return AnnotationTransformerBuildItem for removing conflicting annotations
     */
    public static AnnotationTransformerBuildItem removeCountedWhenTimed(IndexView index);
}

Gauge Annotation Handler

Specialized handler for processing @Gauge annotations and generating adapter classes.

/**
 * Handler for @Gauge annotation processing and adapter class generation
 */
public final class GaugeAnnotationHandler {
    
    /**
     * Processes all @Gauge annotations and generates adapter classes
     * @param index Jandex index for annotation scanning
     * @param generatedClasses Producer for generated class build items
     */
    public static void processAnnotatedGauges(
        IndexView index,
        BuildProducer<GeneratedClassBuildItem> generatedClasses
    );
    
    /**
     * Creates adapter class for specific @Gauge annotation
     * @param method Method annotated with @Gauge
     * @param gauge The @Gauge annotation instance
     * @param generatedClasses Producer for generated class build items
     */
    public static void createClass(
        MethodInfo method,
        AnnotationInstance gauge,
        BuildProducer<GeneratedClassBuildItem> generatedClasses
    );
}

Metric Annotation Information Processor

Data class that processes and normalizes MicroProfile Metrics annotation attributes.

/**
 * Processes and normalizes MP Metrics annotation attributes
 */
public final class MetricAnnotationInfo {
    
    /** Processed metric name */
    public final String name;
    
    /** Metric description */
    public final String description;
    
    /** Metric unit */
    public final String unit;
    
    /** Processed tags array */
    public final String[] tags;
    
    /**
     * Constructor that processes annotation attributes
     * @param annotation The MP Metrics annotation instance
     * @param classInfo Class containing the annotation
     */
    public MetricAnnotationInfo(AnnotationInstance annotation, ClassInfo classInfo);
    
    /**
     * Returns processed annotation values as array
     * @return String array with name, description, unit, and tags
     */
    public String[] getAnnotationValues();
    
    /**
     * Static utility for metric name concatenation
     * @param prefix Name prefix
     * @param suffix Name suffix
     * @return Concatenated metric name
     */
    public static String append(String prefix, String suffix);
    
    /**
     * Static utility for processing tag attributes
     * @param annotation Annotation containing tag information
     * @return Processed tags array
     */
    public static String[] createTags(AnnotationInstance annotation);
}

Usage Examples:

// Example MP Metrics annotations that are automatically transformed:

@Timed(name = "process_duration", description = "Time to process request")
@Counted(name = "process_count", description = "Number of processed requests")
public class ProcessingService {
    
    @Gauge(name = "queue_size", unit = "items")
    public int getQueueSize() {
        return queue.size();
    }
    
    @Metered(name = "error_rate")
    public void processWithErrorTracking() {
        // Processing logic
    }
}

// The compatibility layer automatically transforms these to Micrometer equivalents:
// @Timed -> @io.micrometer.core.annotation.Timed
// @Counted -> @io.micrometer.core.annotation.Counted
// @Gauge -> Generated adapter class + Micrometer Gauge registration
// @Metered -> Micrometer meter registration

Annotation Transformation Examples:

// Custom extension using MP Metrics compatibility
@BuildSteps
public class CustomMpMetricsProcessor {
    
    @BuildStep(onlyIf = MicroprofileMetricsProcessor.MicroprofileMetricsEnabled.class)
    AnnotationTransformerBuildItem transformCustomAnnotations(CombinedIndexBuildItem index) {
        return AnnotationHandler.transformAnnotations(
            index.getIndex(),
            DotName.createSimple("org.eclipse.microprofile.metrics.annotation.Timed")
        );
    }
    
    @BuildStep
    void processCustomGauges(
        CombinedIndexBuildItem indexBuildItem,
        BuildProducer<GeneratedClassBuildItem> generatedClasses
    ) {
        GaugeAnnotationHandler.processAnnotatedGauges(
            indexBuildItem.getIndex(),
            generatedClasses
        );
    }
}

// Checking for MP Metrics usage
@BuildStep
void validateMetricsUsage(CombinedIndexBuildItem indexBuildItem) {
    Collection<AnnotationInstance> annotations = indexBuildItem.getIndex()
        .getAnnotations(MetricDotNames.TIMED_ANNOTATION);
    
    if (MetricDotNames.containsMetricAnnotation(annotations)) {
        // Handle MP Metrics annotation presence
    }
}

Configuration Examples:

# Enable MicroProfile Metrics compatibility (enabled by default when MP Metrics API is present)
quarkus.micrometer.binder.mp-metrics.enabled=true

# Configure MP Metrics registry adapter
quarkus.micrometer.registry-config.add-mp-metrics-tags=true

# Enable compatibility warnings
quarkus.log.category."io.quarkus.micrometer.deployment.binder.mpmetrics".level=WARN

The MicroProfile Metrics compatibility layer provides seamless migration by:

  1. Annotation Transformation: Automatically converting MP Metrics annotations to Micrometer equivalents
  2. Gauge Adapter Generation: Creating runtime adapters for @Gauge methods
  3. Registry Bridging: Providing MP Metrics registry API backed by Micrometer registries
  4. CDI Integration: Ensuring proper scope and injection behavior
  5. Migration Warnings: Logging guidance for complete migration to Micrometer APIs

Install with Tessl CLI

npx tessl i tessl/maven-io-quarkus--quarkus-micrometer-deployment

docs

core-processors.md

framework-binders.md

index.md

mp-metrics-compatibility.md

registry-exports.md

tile.json