Are you an LLM? You can read better optimized documentation at /guide/advanced/metrics.md for this page in Markdown format
Metrics
The Wow framework integrates Micrometer metrics collection functionality, providing comprehensive performance monitoring and observability for all core components.
Installation
kotlin
implementation("io.micrometer:micrometer-core")groovy
implementation 'io.micrometer:micrometer-core'xml
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>Automatic Metrics Collection
The Wow framework automatically collects metrics for the following components:
Command Bus Metrics
wow.command.bus.send: Command send count and latencywow.command.bus.receive: Command receive count and latency- Metrics categorized by aggregate type and command type
Event Bus Metrics
wow.event.bus.send: Event publish count and latencywow.event.bus.receive: Event receive count and latency- Metrics categorized by aggregate type and event type
Event Store Metrics
wow.eventstore.append: Event append count and latencywow.eventstore.load: Event load count and latency- Metrics categorized by aggregate type
Snapshot Metrics
wow.snapshot.save: Snapshot save count and latencywow.snapshot.load: Snapshot load count and latency- Metrics categorized by aggregate type
Handler Metrics
wow.command.handler: Command processing count and latencywow.event.handler: Event processing count and latencywow.projection.handler: Projection processing count and latencywow.saga.handler: Saga processing count and latency
Metrics Tags
All metrics include the following tags:
aggregate: Aggregate namecontext: Bounded context nametype: Component type (command, event, projection, saga)name: Handler or bus name
Custom Metrics
Manual Metrics Collection
kotlin
import io.micrometer.core.instrument.MeterRegistry
import io.micrometer.core.instrument.Timer
@Service
class OrderService(
private val meterRegistry: MeterRegistry,
private val commandGateway: CommandGateway
) {
private val orderCreationTimer = Timer.builder("wow.business.order.creation")
.description("Order creation duration")
.register(meterRegistry)
fun createOrder(request: CreateOrderRequest): Mono<OrderSummary> {
return Mono.fromCallable {
Timer.Sample.start(meterRegistry)
}.flatMap { sample ->
commandGateway.sendAndWait(createOrderCommand, WaitStrategy.PROCESSED)
.doOnSuccess { result ->
sample.stop(orderCreationTimer)
// Business success metrics
meterRegistry.counter("wow.business.order.created").increment()
}
.doOnError { error ->
sample.stop(orderCreationTimer)
// Business failure metrics
meterRegistry.counter("wow.business.order.failed").increment()
}
}
}
}Reactive Stream Metrics
kotlin
fun <T> Flux<T>.tagMetrics(operation: String): Flux<T> {
return this.tag(operation)
.metrics()
}
fun <T> Mono<T>.tagMetrics(operation: String): Mono<T> {
return this.tag(operation)
.metrics()
}Configuration
Micrometer Configuration
yaml
management:
metrics:
export:
prometheus:
enabled: true
tags:
application: ${spring.application.name}Wow Metrics Configuration
Wow framework metrics collection is enabled by default and can be controlled as follows:
yaml
wow:
metrics:
enabled: true # Enabled by defaultMonitoring Dashboard
Prometheus + Grafana
Use Prometheus to collect metrics and Grafana to create dashboards:
yaml
# Prometheus configuration
scrape_configs:
- job_name: 'wow-application'
static_configs:
- targets: ['localhost:8080']
metrics_path: '/actuator/prometheus'Common Queries
yaml
# Command processing latency
histogram_quantile(0.95, rate(wow_command_handler_duration_seconds_bucket[5m]))
# Event publishing rate
rate(wow_event_bus_send_total[5m])
# Error rate
rate(wow_command_handler_errors_total[5m]) / rate(wow_command_handler_total[5m])Performance Impact
- Lightweight: Metrics collection uses efficient counters and histograms
- Asynchronous: Does not block business logic execution
- Configurable: Can enable or disable specific metrics as needed
Best Practices
- Choose appropriate metrics: Only collect metrics that are truly needed
- Set reasonable tags: Avoid performance issues caused by too many tags
- Monitoring alerts: Set alert thresholds for critical business metrics
- Regular review: Regularly review and clean up metrics that are no longer needed
Troubleshooting
Metrics Not Showing
Check:
- Whether Micrometer dependencies are correctly added
- Whether MeterRegistry Bean is correctly configured
- Whether
/actuator/metricsendpoint is accessible
Performance Issues
If metrics collection affects performance:
- Reduce the number of metrics collected
- Use sampling rates instead of full collection
- Consider asynchronous metrics collection