or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-processors.mdframework-binders.mdindex.mdmp-metrics-compatibility.mdregistry-exports.md

mp-metrics-compatibility.mddocs/

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