0
# MicroProfile Metrics Compatibility
1
2
Compatibility layer providing seamless migration from MicroProfile Metrics to Micrometer, enabling existing applications to use MicroProfile Metrics annotations while leveraging Micrometer's backend infrastructure.
3
4
## Capabilities
5
6
### MicroProfile Metrics Processor
7
8
Main processor that handles MicroProfile Metrics API compatibility and annotation transformation.
9
10
```java { .api }
11
/**
12
* Deployment processor for MicroProfile Metrics API compatibility
13
*/
14
@BuildSteps
15
public class MicroprofileMetricsProcessor {
16
17
/**
18
* Adds MP Metrics API dependency to Jandex index
19
* @return IndexDependencyBuildItem for MP Metrics API
20
*/
21
@BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
22
public IndexDependencyBuildItem addDependencies();
23
24
/**
25
* Enables auto-injection of @Metric annotations
26
* @return AnnotationsTransformerBuildItem for @Metric injection
27
*/
28
@BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
29
public AnnotationsTransformerBuildItem autoInjectMetric();
30
31
/**
32
* Registers MP Metrics beans for CDI
33
* @return AdditionalBeanBuildItem with MP Metrics bean classes
34
*/
35
@BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
36
public AdditionalBeanBuildItem registerBeanClasses();
37
38
/**
39
* Logs compatibility warnings for MP Metrics usage
40
* @param indexBuildItem Combined index for annotation scanning
41
*/
42
@BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
43
public void logWarningForMpMetricsUsage(CombinedIndexBuildItem indexBuildItem);
44
45
/**
46
* Adds @Dependent scope to metrics beans
47
* @return AnnotationsTransformerBuildItem for scope transformation
48
*/
49
@BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
50
public AnnotationsTransformerBuildItem transformBeanScope();
51
52
/**
53
* Processes MP Metrics annotations and generates adapter classes
54
* @param indexBuildItem Combined index for annotation processing
55
* @param generatedClasses Producer for generated class build items
56
*/
57
@BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
58
public void processAnnotatedMetrics(
59
CombinedIndexBuildItem indexBuildItem,
60
BuildProducer<GeneratedClassBuildItem> generatedClasses
61
);
62
63
/**
64
* Configures MP Metrics registry adapter
65
* @param rootRegistry Root meter registry build item
66
* @return SyntheticBeanBuildItem for registry adapter
67
*/
68
@BuildStep(onlyIf = MicroprofileMetricsEnabled.class)
69
@Record(ExecutionTime.RUNTIME_INIT)
70
public SyntheticBeanBuildItem configureRegistry(
71
RootMeterRegistryBuildItem rootRegistry
72
);
73
74
// Enablement condition
75
public static class MicroprofileMetricsEnabled implements BooleanSupplier;
76
}
77
```
78
79
### Metric Annotation Constants
80
81
Utility class providing DotName constants for all MicroProfile Metrics annotations.
82
83
```java { .api }
84
/**
85
* Constants for MicroProfile Metrics DotNames and utilities
86
*/
87
public final class MetricDotNames {
88
89
// Package constant
90
public static final String MICROMETER_EXTENSION_PKG = "io.quarkus.micrometer.runtime.binder.mpmetrics";
91
92
// MP Metrics binder
93
public static final DotName MP_METRICS_BINDER = DotName
94
.createSimple("io.quarkus.micrometer.runtime.binder.mpmetrics.MpMetricsBinder");
95
96
// MP Metrics annotation DotNames
97
public static final DotName CONCURRENT_GAUGE_ANNOTATION = DotName
98
.createSimple("org.eclipse.microprofile.metrics.annotation.ConcurrentGauge");
99
public static final DotName COUNTED_ANNOTATION = DotName
100
.createSimple("org.eclipse.microprofile.metrics.annotation.Counted");
101
public static final DotName GAUGE_ANNOTATION = DotName
102
.createSimple("org.eclipse.microprofile.metrics.annotation.Gauge");
103
public static final DotName METERED_ANNOTATION = DotName
104
.createSimple("org.eclipse.microprofile.metrics.annotation.Metered");
105
public static final DotName SIMPLY_TIMED_ANNOTATION = DotName
106
.createSimple("org.eclipse.microprofile.metrics.annotation.SimplyTimed");
107
public static final DotName TIMED_ANNOTATION = DotName
108
.createSimple("org.eclipse.microprofile.metrics.annotation.Timed");
109
110
// Registry and metrics DotNames
111
public static final DotName METRIC_REGISTRY = DotName
112
.createSimple("org.eclipse.microprofile.metrics.MetricRegistry");
113
public static final DotName METRIC_ANNOTATION = DotName
114
.createSimple("org.eclipse.microprofile.metrics.annotation.Metric");
115
public static final DotName METRIC = DotName
116
.createSimple("org.eclipse.microprofile.metrics.Metric");
117
public static final DotName ANNOTATED_GAUGE_ADAPTER = DotName
118
.createSimple("io.quarkus.micrometer.runtime.binder.mpmetrics.AnnotatedGaugeAdapter");
119
120
// JAX-RS and REST related DotNames
121
public static final DotName JAXRS_PATH = DotName.createSimple("jakarta.ws.rs.Path");
122
public static final DotName REST_CONTROLLER = DotName
123
.createSimple("org.springframework.web.bind.annotation.RestController");
124
125
// Interceptor and producer DotNames
126
public static final DotName CONCURRENT_GAUGE_INTERCEPTOR = DotName
127
.createSimple("io.quarkus.micrometer.runtime.binder.mpmetrics.ConcurrentGaugeInterceptor");
128
public static final DotName COUNTED_INTERCEPTOR = DotName
129
.createSimple("io.quarkus.micrometer.runtime.binder.mpmetrics.CountedInterceptor");
130
public static final DotName INJECTED_METRIC_PRODUCER = DotName
131
.createSimple("io.quarkus.micrometer.runtime.binder.mpmetrics.InjectedMetricProducer");
132
public static final DotName TIMED_INTERCEPTOR = DotName
133
.createSimple("io.quarkus.micrometer.runtime.binder.mpmetrics.TimedInterceptor");
134
public static final DotName MP_METRICS_REGISTRY_PRODUCER = DotName
135
.createSimple("io.quarkus.micrometer.runtime.binder.mpmetrics.MpMetricsRegistryProducer");
136
137
// Set of all individual metric annotation DotNames
138
public static final Set<DotName> individualMetrics = new HashSet<>(Arrays.asList(
139
CONCURRENT_GAUGE_ANNOTATION,
140
COUNTED_ANNOTATION,
141
GAUGE_ANNOTATION,
142
METERED_ANNOTATION,
143
SIMPLY_TIMED_ANNOTATION,
144
TIMED_ANNOTATION
145
));
146
147
/**
148
* Check if annotation map contains any MP Metrics annotations
149
* @param annotations Map of annotations to check
150
* @return true if any MP Metrics annotations are present
151
*/
152
public static boolean containsMetricAnnotation(Map<DotName, List<AnnotationInstance>> annotations);
153
154
/**
155
* Check if class is a known metrics subsystem class
156
* @param classInfo Class information to analyze
157
* @return true if class is part of metrics subsystem
158
*/
159
public static boolean knownClass(ClassInfo classInfo);
160
161
/**
162
* Check if class is single-instance (REST endpoint or singleton scope)
163
* @param classInfo Class information to analyze
164
* @return true if class is single-instance
165
*/
166
public static boolean isSingleInstance(ClassInfo classInfo);
167
}
168
```
169
170
### Annotation Transformation Handler
171
172
Utility class for transforming MicroProfile Metrics annotations to Micrometer equivalents.
173
174
```java { .api }
175
/**
176
* Utility for transforming MP Metrics annotations for Micrometer compatibility
177
*/
178
public final class AnnotationHandler {
179
180
/**
181
* Creates annotation transformer for single annotation type
182
* @param index Jandex index for annotation scanning
183
* @param sourceAnnotation Source MP Metrics annotation to transform
184
* @return AnnotationTransformerBuildItem for transformation
185
*/
186
public static AnnotationTransformerBuildItem transformAnnotations(
187
IndexView index,
188
DotName sourceAnnotation
189
);
190
191
/**
192
* Creates annotation transformer with source and target annotations
193
* @param index Jandex index for annotation scanning
194
* @param sourceAnnotation Source MP Metrics annotation
195
* @param targetAnnotation Target Micrometer annotation
196
* @return AnnotationTransformerBuildItem for transformation
197
*/
198
public static AnnotationTransformerBuildItem transformAnnotations(
199
IndexView index,
200
DotName sourceAnnotation,
201
DotName targetAnnotation
202
);
203
204
/**
205
* Removes @Counted annotation when @Timed is present (avoids duplication)
206
* @param index Jandex index for annotation scanning
207
* @return AnnotationTransformerBuildItem for removing conflicting annotations
208
*/
209
public static AnnotationTransformerBuildItem removeCountedWhenTimed(IndexView index);
210
}
211
```
212
213
### Gauge Annotation Handler
214
215
Specialized handler for processing @Gauge annotations and generating adapter classes.
216
217
```java { .api }
218
/**
219
* Handler for @Gauge annotation processing and adapter class generation
220
*/
221
public final class GaugeAnnotationHandler {
222
223
/**
224
* Processes all @Gauge annotations and generates adapter classes
225
* @param index Jandex index for annotation scanning
226
* @param generatedClasses Producer for generated class build items
227
*/
228
public static void processAnnotatedGauges(
229
IndexView index,
230
BuildProducer<GeneratedClassBuildItem> generatedClasses
231
);
232
233
/**
234
* Creates adapter class for specific @Gauge annotation
235
* @param method Method annotated with @Gauge
236
* @param gauge The @Gauge annotation instance
237
* @param generatedClasses Producer for generated class build items
238
*/
239
public static void createClass(
240
MethodInfo method,
241
AnnotationInstance gauge,
242
BuildProducer<GeneratedClassBuildItem> generatedClasses
243
);
244
}
245
```
246
247
### Metric Annotation Information Processor
248
249
Data class that processes and normalizes MicroProfile Metrics annotation attributes.
250
251
```java { .api }
252
/**
253
* Processes and normalizes MP Metrics annotation attributes
254
*/
255
public final class MetricAnnotationInfo {
256
257
/** Processed metric name */
258
public final String name;
259
260
/** Metric description */
261
public final String description;
262
263
/** Metric unit */
264
public final String unit;
265
266
/** Processed tags array */
267
public final String[] tags;
268
269
/**
270
* Constructor that processes annotation attributes
271
* @param annotation The MP Metrics annotation instance
272
* @param classInfo Class containing the annotation
273
*/
274
public MetricAnnotationInfo(AnnotationInstance annotation, ClassInfo classInfo);
275
276
/**
277
* Returns processed annotation values as array
278
* @return String array with name, description, unit, and tags
279
*/
280
public String[] getAnnotationValues();
281
282
/**
283
* Static utility for metric name concatenation
284
* @param prefix Name prefix
285
* @param suffix Name suffix
286
* @return Concatenated metric name
287
*/
288
public static String append(String prefix, String suffix);
289
290
/**
291
* Static utility for processing tag attributes
292
* @param annotation Annotation containing tag information
293
* @return Processed tags array
294
*/
295
public static String[] createTags(AnnotationInstance annotation);
296
}
297
```
298
299
**Usage Examples:**
300
301
```java
302
// Example MP Metrics annotations that are automatically transformed:
303
304
@Timed(name = "process_duration", description = "Time to process request")
305
@Counted(name = "process_count", description = "Number of processed requests")
306
public class ProcessingService {
307
308
@Gauge(name = "queue_size", unit = "items")
309
public int getQueueSize() {
310
return queue.size();
311
}
312
313
@Metered(name = "error_rate")
314
public void processWithErrorTracking() {
315
// Processing logic
316
}
317
}
318
319
// The compatibility layer automatically transforms these to Micrometer equivalents:
320
// @Timed -> @io.micrometer.core.annotation.Timed
321
// @Counted -> @io.micrometer.core.annotation.Counted
322
// @Gauge -> Generated adapter class + Micrometer Gauge registration
323
// @Metered -> Micrometer meter registration
324
```
325
326
**Annotation Transformation Examples:**
327
328
```java
329
// Custom extension using MP Metrics compatibility
330
@BuildSteps
331
public class CustomMpMetricsProcessor {
332
333
@BuildStep(onlyIf = MicroprofileMetricsProcessor.MicroprofileMetricsEnabled.class)
334
AnnotationTransformerBuildItem transformCustomAnnotations(CombinedIndexBuildItem index) {
335
return AnnotationHandler.transformAnnotations(
336
index.getIndex(),
337
DotName.createSimple("org.eclipse.microprofile.metrics.annotation.Timed")
338
);
339
}
340
341
@BuildStep
342
void processCustomGauges(
343
CombinedIndexBuildItem indexBuildItem,
344
BuildProducer<GeneratedClassBuildItem> generatedClasses
345
) {
346
GaugeAnnotationHandler.processAnnotatedGauges(
347
indexBuildItem.getIndex(),
348
generatedClasses
349
);
350
}
351
}
352
353
// Checking for MP Metrics usage
354
@BuildStep
355
void validateMetricsUsage(CombinedIndexBuildItem indexBuildItem) {
356
Collection<AnnotationInstance> annotations = indexBuildItem.getIndex()
357
.getAnnotations(MetricDotNames.TIMED_ANNOTATION);
358
359
if (MetricDotNames.containsMetricAnnotation(annotations)) {
360
// Handle MP Metrics annotation presence
361
}
362
}
363
```
364
365
**Configuration Examples:**
366
367
```properties
368
# Enable MicroProfile Metrics compatibility (enabled by default when MP Metrics API is present)
369
quarkus.micrometer.binder.mp-metrics.enabled=true
370
371
# Configure MP Metrics registry adapter
372
quarkus.micrometer.registry-config.add-mp-metrics-tags=true
373
374
# Enable compatibility warnings
375
quarkus.log.category."io.quarkus.micrometer.deployment.binder.mpmetrics".level=WARN
376
```
377
378
The MicroProfile Metrics compatibility layer provides seamless migration by:
379
380
1. **Annotation Transformation**: Automatically converting MP Metrics annotations to Micrometer equivalents
381
2. **Gauge Adapter Generation**: Creating runtime adapters for @Gauge methods
382
3. **Registry Bridging**: Providing MP Metrics registry API backed by Micrometer registries
383
4. **CDI Integration**: Ensuring proper scope and injection behavior
384
5. **Migration Warnings**: Logging guidance for complete migration to Micrometer APIs