or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

builtin-endpoints.mdconfiguration-properties.mdendpoint-framework.mdhealth-system.mdindex.mdmetrics-system.md

metrics-system.mddocs/

0

# Metrics System

1

2

Spring Boot Actuator integrates with Micrometer to provide comprehensive application metrics collection, measurement, and export capabilities. It automatically configures metrics for common application components and supports export to various monitoring systems.

3

4

## Capabilities

5

6

### Metrics Endpoint

7

8

Primary endpoint for accessing collected application metrics.

9

10

```java { .api }

11

/**

12

* Endpoint for application metrics

13

*/

14

@Endpoint(id = "metrics")

15

public class MetricsEndpoint {

16

17

/**

18

* List all available metric names

19

* @return response containing all metric names

20

*/

21

@ReadOperation

22

public ListNamesResponse listNames() { /* ... */ }

23

24

/**

25

* Get details for a specific metric

26

* @param requiredMetricName the name of the metric

27

* @param tag optional tag filters in the format key:value

28

* @return the metric response with measurements and metadata

29

*/

30

@ReadOperation

31

public MetricResponse metric(@Selector String requiredMetricName,

32

@Nullable List<String> tag) { /* ... */ }

33

34

/**

35

* Response containing available metric names

36

*/

37

public static final class ListNamesResponse {

38

private final Set<String> names;

39

40

public Set<String> getNames() { return this.names; }

41

}

42

43

/**

44

* Response containing metric details

45

*/

46

public static final class MetricResponse {

47

private final String name;

48

private final String description;

49

private final String baseUnit;

50

private final List<Sample> measurements;

51

private final List<AvailableTag> availableTags;

52

53

public String getName() { return this.name; }

54

public String getDescription() { return this.description; }

55

public String getBaseUnit() { return this.baseUnit; }

56

public List<Sample> getMeasurements() { return this.measurements; }

57

public List<AvailableTag> getAvailableTags() { return this.availableTags; }

58

}

59

60

/**

61

* A single metric measurement sample

62

*/

63

public static final class Sample {

64

private final Statistic statistic;

65

private final Double value;

66

67

public Statistic getStatistic() { return this.statistic; }

68

public Double getValue() { return this.value; }

69

}

70

71

/**

72

* Available tag for filtering metrics

73

*/

74

public static final class AvailableTag {

75

private final String tag;

76

private final Set<String> values;

77

78

public String getTag() { return this.tag; }

79

public Set<String> getValues() { return this.values; }

80

}

81

}

82

```

83

84

### Automatic Timing Configuration

85

86

Configuration for automatic timing of web requests and method calls.

87

88

```java { .api }

89

/**

90

* Configuration for automatic timing

91

*/

92

public final class AutoTimer {

93

94

/**

95

* AutoTimer that is enabled

96

*/

97

public static final AutoTimer ENABLED = new AutoTimer(true);

98

99

/**

100

* AutoTimer that is disabled

101

*/

102

public static final AutoTimer DISABLED = new AutoTimer(false);

103

104

/**

105

* Create a new AutoTimer

106

* @param enabled whether timing is enabled

107

*/

108

public AutoTimer(boolean enabled) { /* ... */ }

109

110

/**

111

* Return whether auto-timing is enabled

112

* @return true if enabled

113

*/

114

public boolean isEnabled() { /* ... */ }

115

}

116

```

117

118

### Prometheus Integration

119

120

Endpoints and utilities for Prometheus metrics export.

121

122

```java { .api }

123

/**

124

* Endpoint for Prometheus metrics scraping

125

*/

126

@Endpoint(id = "prometheus", enableByDefault = false)

127

public class PrometheusScrapeEndpoint {

128

129

/**

130

* Scrape metrics in Prometheus format

131

* @return metrics in Prometheus text format

132

*/

133

@ReadOperation(produces = "text/plain;version=0.0.4;charset=utf-8")

134

public String scrape() { /* ... */ }

135

136

/**

137

* Scrape metrics for specific names

138

* @param includedNames names of metrics to include

139

* @return filtered metrics in Prometheus format

140

*/

141

@ReadOperation(produces = "text/plain;version=0.0.4;charset=utf-8")

142

public String scrape(@Nullable Set<String> includedNames) { /* ... */ }

143

}

144

145

/**

146

* Output format options for Prometheus metrics

147

*/

148

public enum PrometheusOutputFormat {

149

150

/**

151

* Prometheus text format version 0.0.4

152

*/

153

CONTENT_TYPE_004("text/plain;version=0.0.4;charset=utf-8"),

154

155

/**

156

* OpenMetrics text format version 1.0.0

157

*/

158

CONTENT_TYPE_OPENMETRICS_100("application/openmetrics-text;version=1.0.0;charset=utf-8");

159

160

private final String type;

161

162

PrometheusOutputFormat(String type) { this.type = type; }

163

164

public String getType() { return this.type; }

165

}

166

167

/**

168

* Manager for Prometheus push gateway integration

169

*/

170

public class PrometheusPushGatewayManager {

171

172

/**

173

* Create a new push gateway manager

174

* @param pushGateway the Prometheus push gateway

175

* @param registry the meter registry

176

* @param scheduler the task scheduler

177

*/

178

public PrometheusPushGatewayManager(PushGateway pushGateway,

179

CollectorRegistry registry,

180

TaskScheduler scheduler) { /* ... */ }

181

182

/**

183

* Push metrics to the gateway

184

*/

185

public void push() { /* ... */ }

186

187

/**

188

* Shutdown the push gateway manager

189

*/

190

public void shutdown() { /* ... */ }

191

}

192

```

193

194

### Cache Metrics

195

196

Metrics providers for various caching solutions.

197

198

```java { .api }

199

/**

200

* Provider for cache meter binders

201

*/

202

@FunctionalInterface

203

public interface CacheMeterBinderProvider<C> {

204

205

/**

206

* Return a MeterBinder for the given cache

207

* @param cache the cache to instrument

208

* @param tags additional tags

209

* @return the meter binder or null if not supported

210

*/

211

@Nullable

212

MeterBinder getMeterBinder(C cache, Iterable<Tag> tags);

213

}

214

```

215

216

### Database Connection Pool Metrics

217

218

Metrics for monitoring database connection pools.

219

220

```java { .api }

221

/**

222

* Metrics for data source connection pools

223

*/

224

public class DataSourcePoolMetrics {

225

226

/**

227

* Create metrics for a data source

228

* @param dataSource the data source

229

* @param dataSourceName the data source name

230

* @param tags additional tags

231

* @return the meter binder

232

*/

233

public static MeterBinder createMeterBinder(DataSource dataSource,

234

String dataSourceName,

235

Iterable<Tag> tags) { /* ... */ }

236

}

237

238

/**

239

* Metrics for R2DBC connection pools

240

*/

241

public class ConnectionPoolMetrics {

242

243

/**

244

* Create metrics for an R2DBC connection pool

245

* @param connectionPool the connection pool

246

* @param name the pool name

247

* @param tags additional tags

248

* @return the meter binder

249

*/

250

public static MeterBinder createMeterBinder(ConnectionPool connectionPool,

251

String name,

252

Iterable<Tag> tags) { /* ... */ }

253

}

254

```

255

256

## Usage Examples

257

258

### Accessing Metrics via HTTP

259

260

```bash

261

# List all available metrics

262

curl http://localhost:8080/actuator/metrics

263

264

# Get JVM memory usage

265

curl http://localhost:8080/actuator/metrics/jvm.memory.used

266

267

# Get HTTP request metrics with tags

268

curl "http://localhost:8080/actuator/metrics/http.server.requests?tag=status:200&tag=method:GET"

269

270

# Get database connection pool metrics

271

curl http://localhost:8080/actuator/metrics/hikaricp.connections.active

272

```

273

274

### Custom Metrics with Micrometer

275

276

```java

277

@Service

278

public class BusinessMetricsService {

279

280

private final Counter orderCounter;

281

private final Timer orderProcessingTimer;

282

private final Gauge activeUsersGauge;

283

private final DistributionSummary orderValueSummary;

284

285

public BusinessMetricsService(MeterRegistry meterRegistry) {

286

this.orderCounter = Counter.builder("orders.placed")

287

.description("Number of orders placed")

288

.tag("type", "business")

289

.register(meterRegistry);

290

291

this.orderProcessingTimer = Timer.builder("order.processing.time")

292

.description("Time taken to process orders")

293

.register(meterRegistry);

294

295

this.activeUsersGauge = Gauge.builder("users.active")

296

.description("Number of active users")

297

.register(meterRegistry, this, BusinessMetricsService::getActiveUserCount);

298

299

this.orderValueSummary = DistributionSummary.builder("order.value")

300

.description("Distribution of order values")

301

.baseUnit("USD")

302

.register(meterRegistry);

303

}

304

305

public void recordOrderPlaced(Order order) {

306

orderCounter.increment(Tags.of("product", order.getProduct()));

307

orderValueSummary.record(order.getValue());

308

}

309

310

public void recordOrderProcessing(Runnable orderProcessing) {

311

orderProcessingTimer.recordCallable(() -> {

312

orderProcessing.run();

313

return null;

314

});

315

}

316

317

private double getActiveUserCount() {

318

// Implementation to get active user count

319

return 0.0;

320

}

321

}

322

```

323

324

### Automatic Web Request Timing

325

326

```java

327

@Configuration

328

public class MetricsConfiguration {

329

330

@Bean

331

public WebMvcMetricsFilter webMvcMetricsFilter(MeterRegistry registry) {

332

return new WebMvcMetricsFilter(registry,

333

new DefaultWebMvcTagsProvider(),

334

"http.server.requests",

335

AutoTimer.ENABLED);

336

}

337

338

@Bean

339

public TimedAspect timedAspect(MeterRegistry registry) {

340

return new TimedAspect(registry);

341

}

342

}

343

344

@RestController

345

public class OrderController {

346

347

@Timed(name = "orders.create", description = "Time taken to create order")

348

@PostMapping("/orders")

349

public ResponseEntity<Order> createOrder(@RequestBody CreateOrderRequest request) {

350

// Order creation logic

351

return ResponseEntity.ok(order);

352

}

353

}

354

```

355

356

### Custom Health Indicator with Metrics

357

358

```java

359

@Component

360

public class DatabaseHealthWithMetrics extends AbstractHealthIndicator {

361

362

private final DataSource dataSource;

363

private final Counter healthCheckCounter;

364

private final Timer healthCheckTimer;

365

366

public DatabaseHealthWithMetrics(DataSource dataSource, MeterRegistry registry) {

367

this.dataSource = dataSource;

368

this.healthCheckCounter = Counter.builder("health.check")

369

.description("Database health check attempts")

370

.tag("component", "database")

371

.register(registry);

372

this.healthCheckTimer = Timer.builder("health.check.time")

373

.description("Database health check duration")

374

.tag("component", "database")

375

.register(registry);

376

}

377

378

@Override

379

protected void doHealthCheck(Health.Builder builder) throws Exception {

380

healthCheckCounter.increment();

381

382

Timer.Sample sample = Timer.start();

383

try {

384

// Perform health check

385

try (Connection connection = dataSource.getConnection()) {

386

// Simple query to verify connection

387

connection.isValid(1);

388

builder.up()

389

.withDetail("database", "available")

390

.withDetail("validationQuery", "connection.isValid(1)");

391

}

392

} finally {

393

sample.stop(healthCheckTimer);

394

}

395

}

396

}

397

```

398

399

### Prometheus Configuration

400

401

```java

402

@Configuration

403

@ConditionalOnProperty(name = "management.metrics.export.prometheus.enabled",

404

havingValue = "true", matchIfMissing = true)

405

public class PrometheusConfiguration {

406

407

@Bean

408

public PrometheusMeterRegistry prometheusMeterRegistry(PrometheusConfig config,

409

CollectorRegistry registry,

410

Clock clock) {

411

return new PrometheusMeterRegistry(config, registry, clock);

412

}

413

414

@Bean

415

@ConditionalOnProperty(name = "management.metrics.export.prometheus.pushgateway.enabled",

416

havingValue = "true")

417

public PrometheusPushGatewayManager prometheusPushGatewayManager(

418

PrometheusProperties.Pushgateway properties,

419

CollectorRegistry registry,

420

TaskScheduler scheduler) {

421

422

PushGateway pushGateway = new PushGateway(properties.getBaseUrl());

423

return new PrometheusPushGatewayManager(pushGateway, registry, scheduler);

424

}

425

}

426

```

427

428

### Cache Metrics Integration

429

430

```java

431

@Configuration

432

@EnableCaching

433

public class CacheMetricsConfiguration {

434

435

@Bean

436

public CacheManager cacheManager(MeterRegistry meterRegistry) {

437

CaffeineCacheManager cacheManager = new CaffeineCacheManager();

438

cacheManager.setCacheSpecification("maximumSize=1000,expireAfterWrite=10m");

439

440

// Bind cache metrics

441

cacheManager.getCacheNames().forEach(cacheName -> {

442

Cache cache = cacheManager.getCache(cacheName);

443

if (cache instanceof CaffeineCache) {

444

CaffeineCacheMetrics.monitor(meterRegistry,

445

((CaffeineCache) cache).getNativeCache(),

446

cacheName);

447

}

448

});

449

450

return cacheManager;

451

}

452

}

453

```

454

455

## Built-in Metrics

456

457

Spring Boot automatically provides metrics for:

458

459

### JVM Metrics

460

- `jvm.memory.used` - JVM memory usage

461

- `jvm.memory.committed` - JVM committed memory

462

- `jvm.memory.max` - JVM maximum memory

463

- `jvm.gc.pause` - Garbage collection pause times

464

- `jvm.threads.live` - Live thread count

465

- `jvm.classes.loaded` - Loaded class count

466

467

### Web Metrics

468

- `http.server.requests` - HTTP request metrics

469

- `tomcat.sessions.active.max` - Maximum active sessions

470

- `tomcat.threads.busy` - Busy thread count

471

472

### Database Metrics

473

- `hikaricp.connections.active` - Active database connections

474

- `hikaricp.connections.idle` - Idle database connections

475

- `hikaricp.connections.pending` - Pending database connections

476

477

### Cache Metrics

478

- `cache.gets` - Cache get operations

479

- `cache.puts` - Cache put operations

480

- `cache.evictions` - Cache evictions

481

- `cache.size` - Cache size

482

483

## Configuration

484

485

Metrics system behavior can be configured through application properties:

486

487

```properties

488

# Enable/disable metrics endpoint

489

management.endpoint.metrics.enabled=true

490

491

# Configure Micrometer registry

492

management.metrics.enable.all=true

493

management.metrics.enable.jvm=true

494

management.metrics.enable.system=true

495

management.metrics.enable.web=true

496

497

# Prometheus export configuration

498

management.metrics.export.prometheus.enabled=true

499

management.endpoint.prometheus.enabled=true

500

501

# Push gateway configuration

502

management.metrics.export.prometheus.pushgateway.enabled=true

503

management.metrics.export.prometheus.pushgateway.base-url=http://localhost:9091

504

management.metrics.export.prometheus.pushgateway.job=spring-boot-app

505

506

# Distribution percentiles

507

management.metrics.distribution.percentiles.http.server.requests=0.5,0.95,0.99

508

management.metrics.distribution.slo.http.server.requests=50ms,100ms,200ms,500ms

509

510

# Tags for all metrics

511

management.metrics.tags.application=my-app

512

management.metrics.tags.environment=production

513

514

# Web request timing

515

management.metrics.web.server.request.autotime.enabled=true

516

management.metrics.web.server.request.autotime.percentiles=0.5,0.95,0.99

517

518

# Database metrics

519

management.metrics.jdbc.datasource-proxy.enabled=true

520

521

# Cache metrics

522

management.metrics.cache.instrument-cache=true

523

```