How it works...

To enable exporting metrics via Graphite, we added an extra dependency on the io.micrometer:micrometer-registry-graphite library. Under the hood, however, it depends on the Dropwizard metrics library to provide Graphite integration, so it will add the following new dependencies to our build file:

  • io.dropwizard.metrics:metrics-core: This dependency adds the basic Dropwizard functionality, MetricsRegistry, common API interfaces, and base classes. This is the bare minimum that is required to get Dropwizard working and integrated into Spring Boot to handle the metrics.
  • io.dropwizard.metrics:metrics-graphite: This adds support for GraphiteReporter and is needed in order to configure Dropwizard to send the monitoring data that it collects to our Graphite instance.

In order to keep things clean and nicely separated, we created a separate configuration class with all the monitoring-related beans and settings: MonitoringConfiguration. In this class, we configured three @Bean instances: a custom MeterRegistryCustomizer implementation to customize the GraphiteMeterRegistry instance, HigherarchicalNameMapper, and NamingConvention to go along with it.

The reason why we had to create our own customization is twofold. We wanted to comply with the classic Graphite metric naming scheme, which uses the dot (.) notation to separate metric names in a hierarchy. Unfortunately, for whatever reason, Micrometer Graphite implementation has opted for using the camelCase collapsing notation instead, which made metric names like counter.datasource.BookRepository translate into the counterDatasourceBookRepository name to be displayed inside Graphite. Having such a long name, without hierarchical tree makes for a very difficult search and discovery inside Graphite UI, when many metrics are present. Also, all the metrics get placed under a root (/) tree, without creating a dedicated application folder, which also leads to poor readability and usage. We have added code to our HigherarchicalNameMapper instance to prepend the application prefix to all the metrics being exported to Graphite so that they all get put into subtree: /bookpub/app/*.:

String prefix = "bookpub.app."; 
... 
return prefix + id.getConventionName(convention) + tags; 

The NamingConvention provides precise configuration about how to convert particular Meter names, keys, values, and tags into proper Graphite variants. Inside the format(String name) method, we declare that we want to use a dot (.) separation between elements via the NamingConvention.dot implementation.

The management.metrics.export.graphite group of properties define how to send the data to the Graphite instance. We configured it to do so every 1 minute, translate all the time duration intervals, such as the latency measurements, into milliseconds and all the variable rates, such as the number of requests per some time frame, into seconds. Most of these values have their default configuration settings for Graphite provided, but can be changed, if desired.

Notice that we've used the @ConditionalOnClass annotation to indicate that we only want to apply this @Configuration if the Micrometer Graphite provided class GraphiteMeterRegistry.class is present in the classpath. This is needed to not try to instantiate Graphite beans during tests, as there might not be a Graphite instance running and available in the testing environment.

As you can see from the available metrics from Graphite UI, there are many metrics that are provided out of the box. Some notable ones are about JVM and OS metrics, which expose the memory and thread metrics to Graphite in the memory and threads data nodes among other data. They can be found in Metrics/bookpub/app/jvmMetrics/bookpub/app/process, or Metrics/bookpub/app/system in the Graphite tree.

Micrometer core library provides a number of meter binders for additional system metrics. If there is a need to export things like thread or executor information, or get a view into the file descriptors, one can export additional beans by simply declaring a method returning new JvmThreadMetrics() or new FileDescriptorMetrics() for example.

The running application will gather all the metrics registered with MeterRegistry and every configured exporter (in our case, GraphiteMeterRegistry) reports all these metrics at a timed interval to its destination. The proper exporter implementations run in a separate ThreadPool, thus outside of the main application threads and not interfering with them. However, this should be kept in mind in case the Meter implementations use some ThreadLocal data internally, which would not be available to exporters.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.43.140