A Counter is a specialized Meter that can be incremented by a positive number (0 included - it can stay the same). For example, the number of pages views can be modeled as a counter, as it can only go up.

Creating a counter is quite straightforward, it all starts from the MeterRegistry . A MeterRegistry bean is provided by Spring Boot, so it only needs to be injected.

@Bean fun simpleCounter ( registry : MeterRegistry ) = registry . counter ( "simple.counter" )

There’s another option available: all of Meter children interfaces embed a fluent builder. This builder has a register(MeterRegistry) method.

The following snippet is equivalent to the above one:

@Bean fun simpleCounter2 ( registry : MeterRegistry ) = Counter . builder ( "simple.counter2" ) . register ( registry )

The builder function is in general more powerful as it provides more options

An alternative to Counter is FunctionCounter , though they are un-related to one another interface-wise. FunctionCounter allows to track a monotonically increasing function - a function which value can only increase (or stay the same) over time.

class TrackedObject { var value : Double = 0.0 get () { field += 1 return field } } @Bean fun tracked () = TrackedObject () @Bean fun simpleFunctionCounter ( registry : MeterRegistry , tracked : TrackedObject ) = registry . more () . counter ( "simple.functioncounter" , arrayListOf (), tracked ) { it . value } @Bean fun simpleFunctionCounter2 ( registry : MeterRegistry , tracked : TrackedObject ) = FunctionCounter . builder ( "simple.functioncounter2" , tracked ) { it . value } . register ( registry ) }

Micrometer only keeps a weak reference to the object parameter (the TrackedObject above). Unless the application code keeps a strong reference to it - just like in the above snippet where it’s part of the application context, it will be garbage collected. In general, it’s good. In this snippet, it means that if tracked is not injected, but the method creates a new TrackedObject() instance, the metric will be lost pretty soon.

Both above will create a meter that will increase by 1 after being queried. Obviously, this is not super useful. However, function counters can be bound to interesting metrics:

Page views

Cache eviction

etc.

@Bean fun guavaCache ( registry : MeterRegistry , guava : GuavaCacheMetrics ) = FunctionCounter . builder ( "cache.evictions" , guava ) { it . evictionCount (). doubleValue () } . register ( registry )