Micrometer Graphite

Graphite is one of the most popular current hierarchical metrics systems backed by a fixed-size database, similar in design and purpose to RRDtool. It originated at Orbitz in 2006 and was open sourced in 2008.

1. Installing micrometer-registry-graphite

It is recommended to use the BOM provided by Micrometer (or your framework if any), you can see how to configure it here. The examples below assume you are using a BOM.

1.1. Gradle

After the BOM is configured, add the following dependency:

implementation 'io.micrometer:micrometer-registry-graphite'
The version is not needed for this dependency since it is defined by the BOM.

1.2. Maven

After the BOM is configured, add the following dependency:

<dependency>
  <groupId>io.micrometer</groupId>
  <artifactId>micrometer-registry-graphite</artifactId>
</dependency>
The version is not needed for this dependency since it is defined by the BOM.

2. Configuring

The following example configures a Graphite instance:

GraphiteConfig graphiteConfig = new GraphiteConfig() {
    @Override
    public String host() {
        return "mygraphitehost";
    }

    @Override
    public String get(String k) {
        return null; // accept the rest of the defaults
    }
};

MeterRegistry registry = new GraphiteMeterRegistry(graphiteConfig, Clock.SYSTEM, HierarchicalNameMapper.DEFAULT);

Micrometer uses Dropwizard Metrics as the underlying instrumentation library when recording metrics destined for Graphite. GraphiteConfig is an interface with a set of default methods. If, in the implementation of get(String k), rather than returning null, you instead bind it to a property source, you can override the default configuration. For example, Spring Boot’s Micrometer support binds its application properties directly to the GraphiteConfig. See Spring Boot Reference Documentation for details.

3. Graphite Tag Support

As of Micrometer version 1.4.0, Micrometer supports exporting Graphite metrics by using tags instead of the traditional hierarchical format. By default, metrics are exported by using the tag format, unless any tagsAsPrefix values are configured. Tag support was added to Graphite in the 1.1.0 Graphite release. If you wish to revert to the traditional hierarchical format, ensure that the graphiteTagsEnabled config value is set to false. The following documentation sections on hierarchical name mapping and metrics prefixing are only applicable if tag support is disabled.

4. Hierarchical name mapping

Micrometer provides a HierarchicalNameMapper interface that governs how a dimensional meter ID is mapped to flat hierarchical names.

The default (HierarchicalNameMapper.DEFAULT) sorts tags alphabetically by key and appends tag key/value pairs to the base meter name with '.' — for example, http_server_requests.method.GET.response.200. The name and tag keys have the registry’s naming convention applied to them first.

If there is something special about your naming scheme that you need to honor, you can provide your own HierarchicalNameMapper implementation. The most common cause of a custom mapper comes from a need to prefix something to the front of every metric (generally something like app.<name>.http_server_requests.method.GET.response.200).

5. Prefixing Your Metrics

To add a prefix to all metrics that go to graphite, use the GraphiteConfig#tagsAsPrefix configuration option. This option applies the tag value of a set of common tags as a prefix. For example, if tagsAsPrefix contains application, and a meter named myTimer is created with a tag of application=APPNAME, it appears in Graphite as APPNAME.myTimer.

Generally, when you use tagsAsPrefix, you should add common tags to the registry so that the tags are present on all meters that belong to that registry:

@Bean
public MeterRegistryCustomizer<MeterRegistry> commonTags() {
   return r -> r.config().commonTags("application", "APPNAME");
}

We do it this way because, generally, a tag prefix in Graphite is correlated to a common tag elsewhere. Prefixes tend to be something like app name or host. By applying those values as common tags, you make your metrics more portable (if you ever switch to a dimensional monitoring system, you are set).

You can use this when the order of the prefix matters. Micrometer always sorts tags, but the order of tag keys in tagsAsPrefix is preserved, so adding host and application to tagsAsPrefix results in a prefixed metric, such as HOST.APP.myCounter.

To meet your specific naming needs, you can also provide a custom hierarchical name mapper when creating GraphiteMeterRegistry, as follows:

GraphiteMeterRegistry r = new GraphiteMeterRegistry(
            GraphiteConfig.DEFAULT,
            Clock.SYSTEM,
            (id, convention) -> "prefix." + HierarchicalNameMapper.DEFAULT.toHierarchicalName(id, convention));
If you use a custom HierarchicalNameMapper, tagsAsPrefix is ignored.

6. Further Customizing the GraphiteReporter

We give you the option to configure GraphiteReporter yourself if you need further customization. To do so, use this constructor and provide your own GraphiteReporter:

GraphiteMeterRegistry(GraphiteConfig config, Clock clock, HierarchicalNameMapper nameMapper,
                      MetricRegistry metricRegistry, GraphiteReporter reporter)

7. Graphing

This section serves as a quick start to rendering useful representations in Graphite for metrics originating in Micrometer.

7.1. Counters

Graphite counters measure mean throughput and one-, five-, and fifteen-minute exponentially-weighted moving average throughputs.

Graphite-rendered counter
Figure 1. A Graphite rendered graph of the random walk counter.