Contents
Overview
Helidon SE metrics is inspired by—but does not fully implement—the MicroProfile Metrics specification. In particular, the Helidon metrics subsystem furnishes
a unified way for Helidon servers to export monitoring data—telemetry—to management agents, and
a unified Java API which all application programmers can use to register and update metrics to expose telemetry data from their services.
Learn more about the MicroProfile Metrics specification.
Maven Coordinates
To enable metrics add the following dependency to your project’s pom.xml (see Managing Dependencies).
<dependency>
<groupId>io.helidon.metrics</groupId>
<artifactId>helidon-metrics</artifactId>
</dependency>Adding this dependency packages the full-featured metrics implementation with your service.
Other Packaging Options
Helidon gives you flexibility in how you make metrics available to your service. This document explains your options.
Usage
Instrumenting Your Service
You add metrics to your service by writing code which explicitly invokes the metrics API to register metrics, retrieve previously-registered metrics, and update metric values.
Later sections of this document describe how to do this.
Categorizing the Types of Metrics
Helidon distinguishes among three general types, or scopes, of metrics, as described in the MP metrics specification.
| Type/scope | Typical Usage |
|---|---|
| base | Mandated by the MP metrics specification, such as OS or Java runtime measurements (available heap, disk space, etc.). |
| vendor | Implemented by vendors, including the REST.request metrics and other key performance indicator measurements (described in later sections). |
| application | Declared via annotations or programmatically registered by your service code. |
When you add metrics annotations to your service code, Helidon registers the resulting metrics as type application.
Metric Registries
A metric registry collects registered metrics of a given type. Helidon supports three registries, one for each of the three metrics types.
When you add code to your service to create a metric programmatically, the code first locates the appropriate registry and then registers the metric with that registry.
Retrieving Metrics Reports From Your Service
When you add the metrics dependency to your project, Helidon automatically provides a built-in REST endpoint /metrics which responds with a report of the registered metrics and their values.
Clients can request a particular output format.
/metrics output| Format | Requested by |
|---|---|
| OpenMetrics (Prometheus) | default (text/plain) |
| JSON | Header Accept: application/json |
Clients can also limit the report by appending the metric type to the path:
/metrics/base/metrics/vendor/metrics/application
Further, clients can narrow down to a specific metric name by adding the name as a subpath such as /metrics/application/myCount.
curl -s -H 'Accept: text/plain' -X GET http://localhost:8080/metrics/# TYPE base:classloader_total_loaded_class_count counter # HELP base:classloader_total_loaded_class_count Displays the total number of classes that have been loaded since the Java virtual machine has started execution. base:classloader_total_loaded_class_count 3157
curl -s -H 'Accept: application/json' -X GET http://localhost:8080/metrics/{
"base" : {
"memory.maxHeap" : 3817865216,
"memory.committedHeap" : 335544320,
}
}In addition to your application metrics, the reports contain other metrics of interest such as system and VM information.
Enabling the MetricsSupport REST Service
To enable the metrics REST endpoint:
- Create an instance of
MetricsSupport, either directly as shown below or using itsBuilder. - Include the
MetricsSupportinstance in your application’s routing.
import io.helidon.metrics.serviceapi.MetricsSupport;
Routing.builder()
.register(MetricsSupport.create())
.register("/myapp", new MyService())
.build();API
To work with Helidon Metrics in your code, follow these steps:
- Use a static method on the
RegistryFactoryto get a reference to theMetricRegistryinstance you want to use. - Use the
MetricRegistryinstance to register new metrics and look up previously-registered metrics. - Use the metric reference returned from the
MetricRegistryto update the metric or get its value.
You can also use the MetricRegistry to remove an existing metric.
Helidon Metrics API
The Helidon Metrics API is aligned with the MicroProfile Metrics API. That API defines the classes and interfaces for metric types, metric registries, and other related items. Helidon Metrics reuses that API for classes and interfaces (but not for annotations which Helidon SE does not support).
The following table summarizes the metric types.
| Metric Type | Usage |
|---|---|
Counter | Monotonically increasing count of events. |
ConcurrentGauge | Increasing and decreasing measurement of currently-executing blocks of code. |
Gauge | Access to a value managed by other code in the service. |
Histogram | Calculates the distribution of a value. |
Meter | Count of invocations and how frequently invocations have occurred. |
SimpleTimer | Count of invocations and the total duration consumed by those invocations. |
Timer | Frequency of invocations and the distribution of how long the invocations take. |
Each metric type has its own set of methods for updating and retrieving the metric’s value.
The MetricRegistry API
To register or look up metrics programmatically, your service code uses one of the three MetricRegistry instances (base, vendor, and application) which Helidon furnishes automatically.
To get a MetricRegistry reference, first get a Helidon RegistryFactory. Then invoke getRegistry on the RegistryFactory instance.
The MetricRegistry allows your code to register new metrics, look up previously-registered metrics, and remove metrics.
Configuration
To control how the Helidon metrics subsystem behaves, add a metrics section to your configuration file, such as application.yaml.
Type: io.helidon.metrics.serviceapi.MetricsSupport
Configuration Options
| key | type | default value | description |
|---|---|---|---|
appName | string | Sets the value for the | |
base | Set the base metrics settings. | ||
cors | Sets the cross-origin config builder for use in establishing CORS support for the service endpoints. | ||
enabled | boolean | Sets whether metrics should be enabled. | |
key-performance-indicators | Set the KPI metrics settings. | ||
registries | Sets the registry settings for the specified registry type. | ||
routing | string | Sets the routing name to use for setting up the service’s endpoint. | |
tags | Map<string, string> | Sets the global tags to be applied to all metrics. | |
web-context | string | Sets the web context to use for the service’s endpoint. |
Examples
Helidon SE includes several prewritten example applications illustrating aspects of metrics:
Enabling/disabling metrics using
MetricsSettingsControlling key performance indicator metrics using configuration and
KeyPerformanceIndicatorMetricsSettings.
The rest of this section shows how to add a metric to your code and how to configure the Helidon metrics subsystem.
Example Application Code
The following example illustrates registering and updating a new Counter in application code.
Counterimport io.helidon.metrics.api.RegistryFactory;
import org.eclipse.microprofile.metrics.Counter;
import org.eclipse.microprofile.metrics.MetricRegistry;
//...
public class MyService implements Service {
private final MetricRegistry registry = RegistryFactory.getInstance()
.getRegistry(MetricRegistry.Type.APPLICATION);
private final Counter accessCtr = registry.counter("accessctr");
@Override
public void update(Routing.Rules rules) {
rules
.any(this::countAccess)
.get("/", this::myGet);
}
private void countAccess(ServerRequest request, ServerResponse response) {
accessCtr.inc();
request.next();
}
}- Get the application metric registry.
- Create a counter in that registry.
- Increment the counter for every request.
Helidon-provided endpoints for /metrics do their work synchronously, using the same thread on which the request arrived via Netty. To prevent performance degradation, avoid including long-running code that can be invoked by these handlers while Helidon is responding to the metric. For example, if you implement your own application-specific metric types, you will write logic to format the JSON and OpenMetrics output for those metric types. Helidon invokes this formatting logic whenever a client accesses the /metrics endpoints, so make that formatting code as efficient as possible.
Example Configuration
Metrics configuration is quite extensive and powerful and, therefore, a bit complicated. The rest of this section illustrates some of the most common scenarios.
Disable Metrics Subsystem
metrics:
enabled: falseHelidon does not update metrics, and the /metrics endpoints respond with 404 plus a message that the metrics subsystem is disabled.
Disable Selected Metrics
You can be even more selective. Within a registry type you can configure up to two regular expression patterns:
one matching metric names to exclude, and
one matching metric names to include.
Helidon updates and reports a metric only if two conditions hold:
the metric name does not match the
excluderegex pattern (if you define one), andeither
there is no
includeregex pattern, orthe metric name matches the
includepattern.
Note
Make sure any include regex pattern you specify matches all the metric names you want to capture.
Suppose your application creates and updates a group of metrics with names such as myapp.xxx.queries, myapp.xxx.creates, myapp.xxx.updates, and myapp.xxx.deletes where xxx can be either supplier or customer.
The following example gathers all metrics except those from your application regarding suppliers although supplier updates are included:
metrics:
registries:
- type: application
filter:
exclude: "myapp\.supplier\..*"
include: "myapp\.supplier\.updates"This setting excludes metrics with names starting with myapp.supplier except for the metric myapp.supplier.updates. The exclude and include values are regular expressions.
Collecting Basic and Extended Key Performance Indicator (KPI) Metrics
Any time you include the Helidon metrics module in your application, Helidon tracks two basic performance indicator metrics:
a
Counterof all requests received (requests.count), anda
Meterof all requests received (requests.meter).
Helidon SE also includes additional, extended KPI metrics which are disabled by default:
current number of requests in-flight - a
ConcurrentGauge(requests.inFlight) of requests currently being processedlong-running requests - a
Meter(requests.longRunning) measuring the rate at which Helidon processes requests which take at least a given amount of time to complete; configurable, defaults to 10000 milliseconds (10 seconds)load - a
Meter(requests.load) measuring the rate at which requests are worked on (as opposed to received)deferred - a
Meter(requests.deferred) measuring the rate at which a request’s processing is delayed after Helidon receives the request
You can enable and control these metrics using configuration:
metrics:
key-performance-indicators:
extended: true
long-running:
threshold-ms: 2000Additional Information
Support for the Prometheus Metrics API
Helidon provides optional support for the Prometheus metrics API.
To use it, your service registers Prometheus support with your routing set-up. You can customize its configuration. For information about using Prometheus, see the Prometheus documentation: https://prometheus.io/docs/introduction/overview/.
Helidon’s fully-functional, built-in metrics implementation supports Prometheus (OpenMetrics) output. Use the optional support described in this section only if you want to use the Prometheus API from your application code.
Maven Coordinates
<dependency>
<groupId>io.helidon.metrics</groupId>
<artifactId>helidon-metrics-prometheus</artifactId>
</dependency>Usage
Your application code uses the Prometheus API to manage metrics. To expose those metrics to clients via a REST endpoint, your code uses the PrometheusSupport interface which Helidon provides.
API
Your code creates a PrometheusSupport object either using a static factory method (shown in the following example) or by using its Builder.
import io.helidon.metrics.prometheus.PrometheusSupport;
Routing.builder()
.register(PrometheusSupport.create())
.register("/myapp", new MyService())
.build();This example uses the default Prometheus CollectorRegistry. By default, the PrometheusSupport and exposes its REST endpoint at the path /metrics. Use the builder obtained by PrometheusSupport.builder() to configure a different CollectorRegistry or a different path.