se.metrics.metrics.adoc Maven / Gradle / Ivy
The newest version!
///////////////////////////////////////////////////////////////////////////////
Copyright (c) 2018, 2024 Oracle and/or its affiliates.
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.
///////////////////////////////////////////////////////////////////////////////
= Metrics in Helidon SE
:description: Helidon metrics
:keywords: helidon, metrics
:feature-name: metrics
:rootdir: {docdir}/../..
include::{rootdir}/includes/se.adoc[]
:metric: meter
:metrics: meters
:metric_uc: Meter
:metrics_uc: Meters
:meter: meter
:meters: meters
:meter_uc: Meter
:meters_uc: Meters
:metrics-endpoint: /observe/metrics
== Contents
- <>
- <>
- <>
- <>
** <>
- <>
- <>
** <>
** <>
- <>
** <>
== Overview
Helidon SE metrics is a neutral metrics API which provides
include::{rootdir}/includes/metrics/metrics-shared.adoc[tag=overview]
=== A Word about Terminology
Helidon {flavor-uc} uses the term "metrics" to refer to the subsystem in Helidon which manages the registration of, updates to,
and reporting of aggregate statistical measurements about the service.
The term "{meter}" refers to an entity which collects these measurements, such as a counter or a timer.
// Maven coordinates comes next
include::{rootdir}/includes/dependencies.adoc[]
.Packaging the metrics API
[source,xml]
----
io.helidon.metrics
helidon-metrics-api
----
This dependency adds the metrics API and a no-op implementation of that API to your project.
The no-op implementation:
* does not register {metrics} in a registry
* does not update {metric} values
* does not expose the metrics endpoint for reporting {metric} values.
To include the full-featured metrics implementation, add the following dependency to your project:
.Packaging a full-featured metrics implementation
[source,xml]
----
io.helidon.webserver.observe
helidon-webserver-observe-metrics
----
Adding this dependency packages the full-featured metrics implementation and support for the metrics endpoint with your service.
You might notice the transitive dependency `io.helidon.metrics.providers:helidon-metrics-providers-micrometer` in your project.
This component contains an implementation of the Helidon metrics API that uses Micrometer as the underlying metrics technology.
Helidon provides several built-in {meters} in a separate artifact.
To include the build-in {meters}, add the following dependency to your project:
.Packaging the built-in {meters}
[source,xml]
----
io.helidon.metrics
helidon-metrics-system-meters
runtime
----
== Usage
include::{rootdir}/includes/metrics/metrics-shared.adoc[tag=usage-body]
=== Meter Registry
Helidon stores all meters in a _meter registry_. Typically, applications use the global meter registry which is the registry where Helidon stores built-in meters.
Application code refers to the global registry using `Metrics.globalRegistry()`.
include::{rootdir}/includes/metrics/metrics-shared.adoc[tag=usage-retrieving]
=== Enabling the Metrics REST Service
If you add the dependencies described above, your service automatically supports the metrics REST endpoint as long as the `WebServer` is configured to discover features automatically.
If you disable auto-discovery, you can add the metrics observer explicitly.
. Create an instance of `MetricsObserver`, either directly as shown below or using its builder.
. Include the `MetricsObserver` instance in your application's `ObserveFeature`.
. Register your `ObserveFeature` with your `WebServer`.
[source,java]
----
include::{sourcedir}/se/metrics/MetricsSnippets.java[tag=snippet_1, indent=0]
----
== API
To work with Helidon Metrics in your code, follow these steps:
. Use the static `globalRegistry` method on the link:{metrics-javadoc-base-url}/io/helidon/metrics/api/Metrics.html[`Metrics`] interface to get a reference to the global link:{metrics-javadoc-base-url}/io/helidon/metrics/api/MeterRegistry.html[`MeterRegistry`] instance.
. Use the `MeterRegistry` instance to register new {metrics} and look up previously-registered {metrics}.
. Use the {metric} reference returned from the `MeterRegistry` to update the {metric} or get its value.
You can also use the `MeterRegistry` to remove an existing {metric}.
=== Helidon Metrics API
The Helidon Metrics API defines the classes and interfaces for {metric} types and other related items.
The following table summarizes the {metric} types.
.{Metric_uc} Types
[%autowidth]
|====
| {Metric_uc} Type | Usage
| link:{metrics-javadoc-base-url}/io/helidon/metrics/api/Counter.html[`Counter`]
| Monotonically increasing count of events.
| link:{metrics-javadoc-base-url}/io/helidon/metrics/api/Gauge.html[`Gauge`]
| Access to a value managed by other code in the service.
|link:{metrics-javadoc-base-url}/io/helidon/metrics/api/DistributionSummary.html[`DistributionSummary`]
|Calculates the distribution of a value.
| link:{metrics-javadoc-base-url}/io/helidon/metrics/api/Timer.html[`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 value.
=== The `MeterRegistry` API
To register or look up {meters} programmatically, your service code uses the global `MeterRegistry`.
Simply invoke `Metrics.globalRegistry()` to get a reference to the global meter registry.
To locate an existing meter or register a new one, your code:
. Creates a builder of the appropriate type of meter, setting the name and possibly other characteristics of the meter.
. Invokes the `MeterRegistry.getOrCreate` method, passing the builder.
The meter registry returns a reference to a previously-registered meter with the specified name and tags or, if none exists, a newly-registered meter.
Your code can then operate on the returned meter as needed to record new measurements or retrieve existing data.
The example code in the <> section below illustrates how to register, retrieve, and update meters.
=== Accessing the Underlying Implementation: `unwrap`
The neutral Helidon metrics API is an abstraction of common metrics behavior independent from any given implementation. As such, we intentionally excluded some implementation-specific behavior from the API.
Sometimes you might want access to methods that are present in a particular metrics implementation but not in the Helidon API. Helidon allows that via the `unwrap` method on the meter types and on their builders. Each full implementation of the Helidon meter types and their builders refers to a delegate meter or delegate builder internally. The `unwrap` method lets you obtain the delegate, cast to the type you want.
Of course, using this technique binds your code to a particular metrics implementation.
The link:{metrics-javadoc-base-url}/io/helidon/metrics/api/Wrapper.html[`Wrapper`] interface declares the `unwrap` method which accepts a class parameter to which the delegate is cast. You can then invoke any method declared on the implementation-specific type.
// Here's Configuration.
include::{rootdir}/includes/metrics/metrics-config.adoc[tag=config-intro]
== Examples
include::{rootdir}/includes/metrics/metrics-shared.adoc[tag=example-apps]
The rest of this section shows how to add a custom meter to your code and how to configure the Helidon metrics subsystem.
=== Example Application Code
The following example, based on the Helidon SE QuickStart application, shows how to register and update a new `Counter` in application code.
The counter tracks the number of times any of the service endpoints is accessed.
.Define and use a `Counter`
[source,java]
----
include::{sourcedir}/se/metrics/MetricsSnippets.java[tag=snippet_2, indent=0]
----
<1> Get the global meter registry.
<2> Create (or find) a counter named "accessctr" in the global registry.
<3> Route every request to the `countAccess` method.
<4> Increment the access counter for every request.
Perform the following steps to see the new counter in action.
.Build and run the application
[source,bash]
----
mvn package
java -jar target/helidon-quickstart-se.jar
----
.Retrieve `application` metrics
[source, bash]
----
curl 'http://localhost:8080/observe/metrics?scope=application' # <1>
----
[source,text]
.Response
----
# HELP accessctr_total
# TYPE accessctr_total counter
accessctr_total{scope="application",} 0.0 # <2>
----
<1> Access the metrics endpoint, selecting only application meters.
<2> Note the counter is zero; we have not accessed a service endpoint yet.
.Access a service endpoint to retrieve a greeting
[source,bash]
----
curl http://localhost:8080/greet
----
[source,json]
.JSON response:
----
{"message":"Hello World"}
----
.Retrieve `application` metrics again
[source,bash]
----
curl 'http://localhost:8080/observe/metrics?scope=application'
----
[source,text]
.Response
----
# HELP accessctr_total
# TYPE accessctr_total counter
accessctr_total{scope="application",} 1.0 # <1>
----
<1> The counter now reports 1, reflecting our earlier access to the `/greet` endpoint.
// example configuration
include::{rootdir}/includes/metrics/metrics-config.adoc[tag=config-examples]
== Additional 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/.
NOTE: 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.
[[prom-maven-coordinates]]
==== Maven Coordinates
.Dependency for Helidon Prometheus API support
[source,xml]
----
io.helidon.metrics
helidon-metrics-prometheus
----
[[prom-usage]]
==== 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.
[[prom-api]]
==== API
Your code creates a link:{prometheus-javadoc-base-url}/io/helidon/metrics/prometheus/PrometheusSupport.html[`PrometheusSupport`] object either using a static factory method (shown in the following example) or by using its link:{prometheus-javadoc-base-url}/io/helidon/metrics/prometheus/PrometheusSupport.Builder.html[`Builder`].
[source,java]
----
include::{sourcedir}/se/metrics/MetricsSnippets.java[tag=snippet_3, indent=0]
----
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.