$ mn create-app my-app --features micrometer-atlas
Micronaut Micrometer
Provides integration between Micronaut and Micrometer
Version: 1.1.1
1 Introduction
This project integrates Micronaut and Micrometer allowing metrics collection for Micronaut applications.
Release Notes
1.1.0
-
Upgrade to Micrometer
1.1.2
-
Support for JCache Metrics
-
Support for @Timed annotation
-
New
/prometheus
Management Endpoint Added. See PrometheusEndpoint -
Support for AWS CloudWatch. Thanks to Nathan Zender.
2 Metrics Endpoint
Using the CLI
If you are creating your project using the Micronaut CLI, supply one of |
The metrics endpoint returns information about the "metrics" of the application. To execute the metrics endpoint, send a GET request to /metrics
. This will return a list of the metric names registered with the MeterRegistry
bean.
You can get specific metrics by using /metrics/[name]
such as /metrics/jvm.memory.used
. This would return something like:
{
"name": "jvm.memory.used",
"measurements": [
{
"statistic": "VALUE",
"value": 1.45397552E8
}
],
"availableTags": [
{
"tag": "area",
"values": [
"heap",
"nonheap"
]
},
{
"tag": "id",
"values": [
"Compressed Class Space",
"PS Survivor Space",
"PS Old Gen",
"Metaspace",
"PS Eden Space",
"Code Cache"
]
}
]
}
You can further limit the metric by using a tag like /metrics/jvm.memory.used?tag=id:PS%20Old%20Gen
.
{
"name": "jvm.memory.used",
"measurements": [
{
"statistic": "VALUE",
"value": 1.1434488E7
}
],
"availableTags": [
{
"tag": "area",
"values": [
"heap"
]
}
]
}
You may even use multiple/nested tags like /metrics/jvm.memory.used?tag=id:PS%20Old%20Gen&tag=area:heap
.
{
"name": "jvm.memory.used",
"measurements": [
{
"statistic": "VALUE",
"value": 1.1434488E7
}
]
}
Configuration
Currently the metrics endpoint will only be enabled if you include the micrometer-core
(or one of the typed registries such as micrometer-registry-statsd
or micrometer-registry-graphite
) AND the management
dependencies. You will also need to have the global metrics flag enabled (true by default).
micronaut:
metrics:
enabled: true
dependencies {
...
compile "io.micronaut.configuration:micronaut-micrometer-core"
// micrometer-registry-statsd also pulls in micrometer-core so included above to verbose example
compile "io.micronaut.configuration:micronaut-micrometer-registry-statsd"
// Also required to enable endpoint
compile "io.micronaut:micronaut-management"
...
}
<dependency>
<groupId>io.micronaut.configuration</groupId>
<artifactId>micronaut-micrometer-core</artifactId>
<version>${micronaut.version}</version>
</dependency>
<!-- micrometer-registry-statsd also pulls in micrometer-core so included above to verbose example -->
<dependency>
<groupId>io.micronaut.configuration</groupId>
<artifactId>micronaut-micrometer-registry-statsd</artifactId>
<version>${micronaut.version}</version>
</dependency>
<!-- Also required to enable endpoint -->
<dependency>
<groupId>io.micronaut</groupId>
<artifactId>micronaut-management</artifactId>
<version>${micronaut.version}</version>
</dependency>
To configure the metrics endpoint, supply configuration through endpoints.metrics
.
endpoints:
metrics:
enabled: Boolean
sensitive: Boolean
3 Metrics Concepts
Metric Concepts
Key Micrometer.io
concepts include
a MeterRegistry to register and use
meters. A Meter is something that produces metrics.
A MeterRegistry can have some customizations automatically applied.
Meter Registry Configurer
-
Any bean that implements
MeterRegistryConfigurer
gets applied to every applicable MeterRegistry bean on creation -
The implementation of the MeterRegistryConfigurer
supports()
method determines if the configurer is applied to a particular registry-
If you want all registries to get the customization, simply return return
true
-
Otherwise, you can evaluate the registry for its class type, its class hierarchy, or other criteria.
-
Remember you only get one shot for autoconfiguration; i.e. when the bean context is started.
-
However, in code, you can apply additional customizations to the registry config
-
/*
* Copyright 2017-2019 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micronaut.configuration.metrics.aggregator;
import io.micrometer.core.instrument.MeterRegistry;
/**
* Class that will configure meter registries. This is done on bean added event so that
* composite registry can be skipped and non-composite registries can be added to composite.
*
* @author Christian Oestreich
* @param <T> an instance of a meter registry that will be configured
* @since 1.0
*/
public interface MeterRegistryConfigurer<T extends MeterRegistry> {
/**
* Method to configure a meter registry with binders, filters, etc.
*
* @param meterRegistry Meter Registry
*/
void configure(T meterRegistry);
/**
* Method to determine if this configurer supports the meter registry type.
*
* @param meterRegistry a meter registry
* @return boolean whether is supported
*/
boolean supports(T meterRegistry);
}
/*
* Copyright 2017-2019 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micronaut.docs;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import io.micronaut.configuration.metrics.aggregator.MeterRegistryConfigurer;
public class SimpleMeterRegistryConfigurer implements MeterRegistryConfigurer {
@Override
public void configure(MeterRegistry meterRegistry) {
meterRegistry.config().commonTags("key", "value");
}
@Override
public boolean supports(MeterRegistry meterRegistry) {
return meterRegistry instanceof SimpleMeterRegistry;
}
}
Meter Filter
-
A meter filter can be used to determine if a Meter is to be added to the registry. See Meter Filters
-
Any bean that implements MeterFilter will be applied to all registries when the registry is first created
You can create custom filters similar to the following inside your application. Micrometer’s MeterFilter
class provides several convenience methods to help with the creation of these filters.
/*
* Copyright 2017-2019 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micronaut.docs;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.config.MeterFilter;
import io.micronaut.context.annotation.Bean;
import io.micronaut.context.annotation.Factory;
import javax.inject.Singleton;
import java.util.Arrays;
@Factory
public class MeterFilterFactory {
/**
* Exclude metrics starting with jvm
*
* @return meter filter
*/
@Bean
@Singleton
MeterFilter jvmExclusionFilter() {
return MeterFilter.denyNameStartsWith("jvm");
}
/**
* Add global tags to all metrics
*
* @return meter filter
*/
@Bean
@Singleton
MeterFilter addCommonTagFilter() {
return MeterFilter.commonTags(Arrays.asList(Tag.of("scope", "demo")));
}
/**
* Rename a tag key for every metric beginning with a given prefix.
* <p>
* This will rename the metric name http.server.requests tag value called `method` to `httpmethod`
* <p>
* OLD: http.server.requests ['method':'GET", ...]
* NEW: http.server.requests ['httpmethod':'GET", ...]
*
* @return meter filter
*/
@Bean
@Singleton
MeterFilter renameFilter() {
return MeterFilter.renameTag("http.server.requests", "method", "httpmethod");
}
}
Meter Binder
Meter Binders get applied to Meter Registry to mix in metrics producers. Micrometer.io defines several of these for cross-cutting metrics related to JVM metrics, caches, classloaders, etc. These all extend a simple interface MeterBinder, but these are not auto wired as beans and manual wiring is required given how micrometer is currently implemented.
Provided Binders
The following metrics currently have binders and are enabled by default. The settings listed below can disable the specific metric binders if you do not with to collect or report the specific metrics.
Jvm Metrics
The JVM metrics bindings will provide several jvm metrics.
Control Property: micronaut.metrics.binders.jvm.enabled
Name |
jvm.buffer.count |
jvm.buffer.memory.used |
jvm.buffer.total.capacity |
jvm.classes.loaded |
jvm.classes.unloaded |
jvm.gc.live.data.size |
jvm.gc.max.data.size |
jvm.gc.memory.allocated |
jvm.gc.memory.promoted |
jvm.memory.committed |
jvm.memory.max |
jvm.memory.used |
jvm.threads.daemon |
jvm.threads.live |
jvm.threads.peak |
Web Metrics
There is a default web filter provided for web metrics. All routes, status codes, methods and exceptions will be timed and counted.
Control Property: micronaut.metrics.binders.web.enabled
If enabled, be default the path /**
will be intercepted. If you wish to change which paths are run through the filter set the following property.
Control Property: micronaut.metrics.http.path
Name |
http.server.requests |
http.client.requests |
System Metrics
There are multiple metrics that can be separately toggled.
Uptime Metrics
The uptime metrics bindings will provide system uptime metrics.
Control Property: micronaut.metrics.binders.uptime.enabled
Name |
process.uptime |
process.start.time |
Processor Metrics
The processor metrics bindings will provide system processor metrics.
Control Property: micronaut.metrics.binders.processor.enabled
Name |
system.load.average.1m |
system.cpu.usage |
system.cpu.count |
process.cpu.usage |
File Descriptor Metrics
The file descriptor metrics bindings will provide system file descriptor metrics.
Control Property: micronaut.metrics.binders.files.enabled
Name |
process.files.open |
process.files.max |
Logback Metrics
The logging metrics bindings will provide logging metrics if using Logback.
Control Property: micronaut.metrics.binders.logback.enabled
Name |
logback.events |
Hibernate Metrics
You can enable metrics for Hibernate by setting the hibernate.generate_statistics
property to true
in configuration. For example for the default entity manager:
Enabling Hibernate Metrics
jpa:
default:
properties:
hibernate:
generate_statistics: true
Micrometer will automatically expose Hibernate statistics. See the source code for HibernateMetrics for the available metrics.
DataSource Metrics
The data source metrics bindings will provide data source pool metrics.
Control Property: micronaut.metrics.binders.jdbc.enabled
There is a different set of pool metric names for HikariCP and other pool providers. |
If you are using io.micronaut.configuration:micronaut-jdbc-hikari
you will get additional pool metrics as HikariCP has built in support for meter registries.
Name |
hikaricp.connections.idle |
hikaricp.connections.pending |
hikaricp.connections |
hikaricp.connections.active |
hikaricp.connections.creation |
hikaricp.connections.max |
hikaricp.connections.min |
hikaricp.connections.usage |
hikaricp.connections.timeout |
hikaricp.connections.acquire |
If you are using io.micronaut.configuration:micronaut-jdbc-tomcat
or io.micronaut.configuration:micronaut-jdbc-dbcp
you will get the following metrics
Name |
jdbc.connections.usage |
jdbc.connections.active |
jdbc.connections.max |
jdbc.connections.min |
Adding Custom Metrics
To add metrics to your application you can inject a MeterRegistry bean to your class and use the provided methods to access counters, timers, etc.
See the Micrometer.io docs at https://micrometer.io/docs for more information.
/*
* Copyright 2017-2019 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micronaut.docs;
import io.micrometer.core.instrument.MeterRegistry;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.reactivex.Single;
import javax.validation.constraints.NotBlank;
@Controller("/")
public class IndexController {
private MeterRegistry meterRegistry;
public IndexController(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}
@Get("/hello/{name}")
public Single hello(@NotBlank String name) {
meterRegistry
.counter("web.access", "controller", "index", "action", "hello")
.increment();
return Single.just("Hello " + name);
}
}
Metrics Registries & Reporters
By default there a metrics endpoint wired up and metrics are provided to it for viewing or retrieving via http. If you want to register a specific type of reporter you will need to include a typed registry configuration. The following are the currently supported libraries for reporting metrics.
Statsd Registry
You can include the statsd reporter via io.micronaut.configuration:micronaut-micrometer-registry-statsd:${micronaut.version}
compile 'io.micronaut.configuration:micronaut-micrometer-registry-statsd'
<dependency>
<groupId>io.micronaut.configuration</groupId>
<artifactId>micronaut-micrometer-registry-statsd</artifactId>
</dependency>
You can configure this reporter using micronaut.metrics.export.statsd
. The most commonly changed configuration properties are listed below, but see StatdsConfig for more options
Name |
Description |
enabled |
Whether to enable the reporter. Could disable to local dev for example. Default: |
flavor |
The type of metric to use (datadog, etsy or telegraf). Default: |
step |
How frequently to report metrics. Default: |
host |
The host to communicate to statsd on. Default: |
port |
The port to communicate to statsd on. Default: |
micronaut:
metrics:
enabled: true
export:
statsd:
enabled: true
flavor: datadog
step: PT1M
host: localhost
port: 8125
Graphite Registry
You can include the graphite reporter via io.micronaut.configuration:micronaut-micrometer-registry-graphite:${micronaut.version}
compile 'io.micronaut.configuration:micronaut-micrometer-registry-graphite'
<dependency>
<groupId>io.micronaut.configuration</groupId>
<artifactId>micronaut-micrometer-registry-graphite</artifactId>
</dependency>
You can configure this reporter using micronaut.metrics.export.graphite
. The most commonly changed configuration properties are listed below, but see GraphiteConfig for more options
Name |
Description |
enabled |
Whether to enable the reporter. Could disable to local dev for example. Default: |
step |
How frequently to report metrics. Default: |
host |
The host to communicate with graphite. Default: |
port |
The port to communicate with graphite. Default: |
micronaut:
metrics:
enabled: true
export:
graphite:
enabled: true
step: PT1M
host: localhost
port: 2004
Atlas Registry
You can include the atlas reporter via io.micronaut.configuration:micronaut-micrometer-registry-atlas:${micronaut.version}
compile 'io.micronaut.configuration:micronaut-micrometer-registry-atlas'
<dependency>
<groupId>io.micronaut.configuration</groupId>
<artifactId>micronaut-micrometer-registry-atlas</artifactId>
</dependency>
You can configure this reporter using micronaut.metrics.export.atlas
. The most commonly changed configuration properties are listed below, but see AtlasConfig for more options
Name |
Description |
enabled |
Whether to enable the reporter. Could disable to local dev for example. Default: |
step |
How frequently to report metrics. Default: |
uri |
The uri for the atlas backend. Default: |
micronaut:
metrics:
enabled: true
export:
atlas:
enabled: true
uri: http://localhost:7101/api/v1/publish
step: PT1M
Prometheus Registry
You can include the prometheus reporter via io.micronaut.configuration:micronaut-micrometer-registry-prometheus:${micronaut.version}
compile 'io.micronaut.configuration:micronaut-micrometer-registry-prometheus'
<dependency>
<groupId>io.micronaut.configuration</groupId>
<artifactId>micronaut-micrometer-registry-prometheus</artifactId>
</dependency>
You can configure this reporter using micronaut.metrics.export.prometheus
. The most commonly changed configuration properties are listed below, but see PrometheusConfig for more options
Name |
Description |
enabled |
Whether to enable the reporter. Could disable to local dev for example. Default: |
step |
How frequently to report metrics. Default: |
descriptions |
Boolean if meter descriptions should be sent to Prometheus. Turn this off to minimize the amount of data sent on each scrape. Default: |
micronaut:
metrics:
enabled: true
export:
prometheus:
enabled: true
step: PT1M
descriptions: true
CloudWatch Registry
You can include the cloudwatch reporter via io.micronaut.configuration:micronaut-micrometer-registry-cloudwatch:${micronaut.version}
compile 'io.micronaut.configuration:micronaut-micrometer-registry-cloudwatch'
<dependency>
<groupId>io.micronaut.configuration</groupId>
<artifactId>micronaut-micrometer-registry-cloudwatch</artifactId>
</dependency>
You can configure this reporter using micronaut.metrics.export.cloudwatch
. The most commonly changed configuration properties are listed below, but see CloudWatchConfig for more options
Name |
Description |
enabled |
Boolean whether to enable the reporter. Could disable to local dev for example. Default: |
namespace |
String Namespace that will show up in cloudwatch for these metrics. Default: |
batchSize |
Number Number of metrics to send in a batch to Cloudwatch. Default: |
micronaut:
metrics:
enabled: true
export:
cloudwatch:
enabled: true
namespace: myAwesomeAppMetrics
batchSize: 10