diff --git a/applications/parent/pom.xml b/applications/parent/pom.xml index 95e0dd6c576..4405238918d 100644 --- a/applications/parent/pom.xml +++ b/applications/parent/pom.xml @@ -41,8 +41,8 @@ 3.6.0 3.1.0 3.1.2 - 4.0.14 - 4.0.14 + 4.0.15 + 4.0.15 3.3.0 0.10.2 1.5.0.Final diff --git a/docs/src/main/asciidoc/includes/attributes.adoc b/docs/src/main/asciidoc/includes/attributes.adoc index 5b0f4b0970b..1921e8a3392 100644 --- a/docs/src/main/asciidoc/includes/attributes.adoc +++ b/docs/src/main/asciidoc/includes/attributes.adoc @@ -277,7 +277,7 @@ endif::[] :oracle-ucp-javadoc-base-url: https://docs.oracle.com/en/database/oracle/oracle-database/{version-lib-oracle-ucp}/jjuar :micrometer-url: https://micrometer.io -:micrometer-api-url: https://docs.micrometer.io/micrometer/reference/concepts.html +:micrometer-api-url: https://docs.micrometer.io/micrometer/reference/concepts :micrometer-javadoc-base-url: https://javadoc.io/doc/io.micrometer :micrometer-javadoc-registry-prometheus-base-url: {micrometer-javadoc-base-url}/micrometer-registry-prometheus/{version-lib-micrometer}/io/micrometer/prometheus @@ -290,6 +290,10 @@ endif::[] :openapi-generator-tool-generators-docs-url: {openapi-generator-tool-docs-url}/generators :openapi-generator-tool-site-url: https://openapi-generator.tech +// Exposition formats for metrics +:prometheus-exposition-format-doc-url: https://github.com/prometheus/docs/blob/main/content/docs/instrumenting/exposition_formats.md +:openmetrics-format-doc-url: https://github.com/prometheus/OpenMetrics/blob/main/specification/OpenMetrics.md + // GraalVM :graalvm-jdk-version: 21 :graalvm-doc-url: https://www.graalvm.org/jdk{graalvm-jdk-version}/ diff --git a/docs/src/main/asciidoc/includes/metrics/metrics-shared.adoc b/docs/src/main/asciidoc/includes/metrics/metrics-shared.adoc index f341dbe2c37..2c6c560a7f0 100644 --- a/docs/src/main/asciidoc/includes/metrics/metrics-shared.adoc +++ b/docs/src/main/asciidoc/includes/metrics/metrics-shared.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2021, 2024 Oracle and/or its affiliates. + Copyright (c) 2021, 2025 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. @@ -23,6 +23,8 @@ ifndef::flavor-lc[:flavor-lc: se] :description: Helidon metrics :keywords: helidon, metrics :writing-code-content: code which explicitly invokes the metrics API to register {metrics}, retrieve previously-registered {metrics}, and update {metric} values. +ifdef::se-flavor[:prom-output-scope-prefix: ] +ifdef::mp-flavor[:prom-output-scope-prefix: mp_] * a unified way for ifdef::mp-flavor[MicroProfile] @@ -73,8 +75,58 @@ Later sections of this document describe how to do ifdef::mp-flavor[each of these.] ifdef::se-flavor[this.] +// tag::meter-types-summary[] +=== {metric_uc} Types + +Helidon supports meters +ifdef::se-flavor[inspired by link:{micrometer-url}[Micrometer]] +ifdef::mp-flavor[described by the link:{microprofile-metrics-spec-url}[MicroProfile Metrics] spec] +and summarized in the following table: + +.Types of {metrics_uc} +[cols="3,8,2"] +|==== +| {metric_uc} Type | Description | +ifdef::se-flavor[Micrometer reference] +ifdef::mp-flavor[Related MicroProfile annotation] + +| +ifdef::se-flavor[link:{metrics-javadoc-base-url}/io/helidon/metrics/api/Counter.html[`Counter`]] +ifdef::mp-flavor[link:{microprofile-metrics-javadoc-metric-url}/Counter.html[`Counter`]] +| Monotonically-increasing `long` value. | +ifdef::se-flavor[link:{micrometer-api-url}/counters.html[Counters]] +ifdef::mp-flavor[link:{microprofile-metrics-javadoc-annotation-url}/Counted.html[`@Counted`]] + +| +ifdef::se-flavor[link:{metrics-javadoc-base-url}/io/helidon/metrics/api/DistributionSummary.html[`DistributionSummary`]] +ifdef::mp-flavor[link:{microprofile-metrics-javadoc-metric-url}/Histogram.html[`Histogram`]] + +| Summary of samples each with a `long` value. Reports aggregate information over all samples (count, total, mean, max) as well as the distribution of sample values using percentiles and bucket counts. | +ifdef::se-flavor[link:{micrometer-api-url}/distribution-summaries.html[Distribution summaries]] +ifdef::mp-flavor[(none)] + +| +ifdef::se-flavor[link:{metrics-javadoc-base-url}/io/helidon/metrics/api/Timer.html[`Timer`]] +ifdef::mp-flavor[link:{microprofile-metrics-javadoc-metric-url}/Timer.html[`Timer`]] +| Accumulation of short-duration (typically under a minute) intervals. Typically updated using a Java link:{jdk-javadoc-url}/java.base/java/time/Duration.html[`Duration`] or by recording the time taken by a method invocation or lambda. Reports the count, total time, max, and mean; provides a +ifdef::se-flavor[distribution summary] +ifdef::mp-flavor[histogram] +of the samples. | +ifdef::se-flavor[link:{micrometer-api-url}/timers.html[Timers]] +ifdef::mp-flavor[link:{microprofile-metrics-javadoc-annotation-url}/Timed.html[`@Timed`]] + +| +ifdef::se-flavor[link:{metrics-javadoc-base-url}/io/helidon/metrics/api/Gauge.html[`Gauge`]] +ifdef::mp-flavor[link:{microprofile-metrics-javadoc-metric-url}/Gauge.html[`Gauge`]] +| View of a value that is assignment-compatible with a subtype of Java link:{jdk-javadoc-url}/java.base/java.lang.Number.html[`Number`]. The underlying value is updated by code elsewhere in the system, not by invoking methods on the gauge itself. | +ifdef::se-flavor[link:{micrometer-api-url}/gauges.html[Gauges]] +ifdef::mp-flavor[link:{microprofile-metrics-javadoc-annotation-url}/Gauge.html[`@Gauge`]] +|==== + +// end::meter-types-summary[] + === Categorizing Types of {Metrics_uc} -Helidon distinguishes among _scopes_, or types, of +Helidon distinguishes among _scopes_, or categories, of ifdef::se-flavor[{metrics}.] ifdef::mp-flavor[{metrics} as described in the link:{microprofile-metrics-spec-url}[MP metrics specification].] @@ -82,7 +134,7 @@ Helidon includes {metrics} in the built-in scopes described below. Applications often register their own {metrics} in the `application` scope but can create their own scopes and register {metrics} within them. .Built-in {metric} scopes -[%autowidth] +[cols="2,8"] |==== | Built-in Scope | Typical Usage @@ -134,12 +186,13 @@ Further, clients can narrow down to a specific metric name by adding the name as curl -s -H 'Accept: text/plain' -X GET http://localhost:8080{metrics-endpoint} ---- -[source,text] +[source,text,subs="attributes+"] ---- -# 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 +# HELP classloader_loadedClasses_count Displays the number of classes that are currently loaded in the Java virtual machine. +# TYPE classloader_loadedClasses_count gauge +classloader_loadedClasses_count{{prom-output-scope-prefix}scope="base",} 5297.0 ---- +See the summary of the <> for more information. [source,bash,subs="attributes+"] .Example Reporting: JSON format @@ -161,6 +214,59 @@ curl -s -H 'Accept: application/json' -X GET http://localhost:8080{metrics-endpo In addition to your application {metrics}, the reports contain other {metrics} of interest such as system and VM information. +==== OpenMetrics and Prometheus Format +The link:{openmetrics-format-doc-url}[OpenMetrics format] and the link:{prometheus-exposition-format-doc-url}[Prometheus exposition format] are very similar in most important respects but are not identical. This brief summary treats them as the same. + +The OpenMetrics/Prometheus format represents each {metric} using three lines of output as summarized in the following table. + +.OpenMetrics/Prometheus format +[cols="1,6,6"] +|==== +| Line prefix | Purpose | Format + +| `# TYPE` | Displays the scope, name, and type of the {metric} | `TYPE : <{metric}-type>` +| `# HELP` | Displays the scope, name, and description of the {metric} | `HELP : ` +| (none) | Displays the scope, {metric} ID, and current value of the {metric} | `: ` +|==== +The OpenMetrics/Prometheus output converts {metric} IDs in these ways: + +* Names in camel case are converted to "snake case" and dots are converted to underscores. +* Names include any units specified for the {metric}. +* For percentiles, the ID includes a tag identifying which percentile the line of output describes. + +As the earlier example output showed, for a {metric} with multiple values, such as a timer or a +ifdef::se-flavor[distribution summary,] +ifdef::mp-flavor[histogram,] +(with, among others, `max`, `mean`, and `count`), the OpenMetrics/Prometheus output reports a "metric family" which includes a separate family member {metric} for each of the multiple values. The name for each member in the family is derived from the registered name for the {metric} plus a suffix indicating which one of the {metric}'s multiple values the line refers to. + +The following table summarizes the naming for each {metric} type. + +.OpenMetrics/Prometheus {metric_uc} Naming +|==== +| {metric_uc} Type | Example registered name | {metric_uc} family member | Name Suffix | Example displayed name + +.1+| `Counter` | `requests.count` | count | `_total` | `requests_count_total` + +.4+| +ifdef::se-flavor[`DistributionSummary`] +ifdef::mp-flavor[`Histogram`] +.4+| `nameLengths` +| count | `_count` | `nameLengths_count` +| sum | `_sum` | `nameLengths_sum` +| max | `_max` | `nameLengths_max` +| percentile | none | `nameLengths{{prom-output-scope-prefix}scope="base",quantile="0.5",}` + +.1+| `Gauge` | `classloader.loadedClasses.count` | value | none | `classloader_loadedClasses_count` + +.4+| `Timer` ^1^ +.4+| `vthreads.recentPinned` +| count | `_count` | `vthreads_recentPinned_seconds_count` +| sum | `_sum` | `vthreads_recentPinned_seconds_sum` +| max | `_max` | `vthreads_recentPinned_seconds_max` +| percentile | none | `vthreads_recentPinned_seconds{{prom-output-scope-prefix}scope="base",quantile="0.5",}` +|==== +^1^ The OpenMetrics/Prometheus output format reports a timer as a `summary` with units of `seconds`. + // end::usage-retrieving[] // tag::metric-registry-api[] @@ -223,3 +329,9 @@ ifdef::se-flavor[] endif::[] // end::example-apps[] + +// tag::format-refcs-no-heading[] +link:{openmetrics-format-doc-url}[OpenMetrics format] + +link:{prometheus-exposition-format-doc-url}[Prometheus exposition format] +// end::format-refcs-no-heading[] diff --git a/docs/src/main/asciidoc/mp/metrics/metrics.adoc b/docs/src/main/asciidoc/mp/metrics/metrics.adoc index 636a4c7e0e6..d0beececff2 100644 --- a/docs/src/main/asciidoc/mp/metrics/metrics.adoc +++ b/docs/src/main/asciidoc/mp/metrics/metrics.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2022, 2024 Oracle and/or its affiliates. + Copyright (c) 2022, 2025 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. @@ -86,17 +86,16 @@ The MicroProfile Metrics specification describes several metric types you can cr | Annotation | Usage | link:{microprofile-metrics-javadoc-annotation-url}/Counted.html[`@Counted`] -| Monotonically increasing count of events. +| Automatically registers a monotonically-increasing `Counter` and increments it with each invocation of the annotated constructor or method. ^1^ | link:{microprofile-metrics-javadoc-annotation-url}/Gauge.html[`@Gauge`] -| Access to a value managed by other code in the service. +| Automatically registers a `Gauge` whose value is provided by the annotated method. Code elsewhere in the system updates the underlying value. | link:{microprofile-metrics-javadoc-annotation-url}/Timed.html[`@Timed`] -| Frequency of invocations and the distribution of how long the invocations take. +| Automatically registers a `Timer` and updates it with each invocation of the annotated constructor or method. ^1^ |==== - -Place annotations on constructors or methods to measure those specific executables. If you annotate the class instead, Helidon applies that annotation to all constructors and methods which the class declares. +^1^ Place annotations on constructors or methods to measure those specific executables. If you annotate the class instead, Helidon applies that annotation to all constructors and methods which the class declares. ==== Metric-referencing Annotations To get a reference to a specific metric, use a metric-referencing annotation in any bean, including your REST resource classes. @@ -405,3 +404,5 @@ include::{rootdir}/includes/guides/metrics.adoc[tag=k8s-and-prometheus-integrati link:{microprofile-metrics-spec-url}[MicroProfile Metrics specification] link:{microprofile-metrics-javadoc-url}/org/eclipse/microprofile/metrics/package-summary.html[MicroProfile Metrics API] + +include::{rootdir}/includes/metrics/metrics-shared.adoc[tag=format-refcs-no-heading] diff --git a/docs/src/main/asciidoc/se/metrics/metrics.adoc b/docs/src/main/asciidoc/se/metrics/metrics.adoc index be776226fd1..34dd879e84c 100644 --- a/docs/src/main/asciidoc/se/metrics/metrics.adoc +++ b/docs/src/main/asciidoc/se/metrics/metrics.adoc @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// - Copyright (c) 2018, 2024 Oracle and/or its affiliates. + Copyright (c) 2018, 2025 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. @@ -45,6 +45,7 @@ include::{rootdir}/includes/se.adoc[] ** <> ** <> - <> +** <> ** <> == Overview @@ -270,6 +271,12 @@ include::{rootdir}/includes/metrics/metrics-config.adoc[tag=config-examples] == Additional Information +=== References + +link:{micrometer-api-url}[Micrometer Metrics concepts documentation] + +include::{rootdir}/includes/metrics/metrics-shared.adoc[tag=format-refcs-no-heading] + === Support for the Prometheus Metrics API - <> - <> diff --git a/metrics/api/src/main/java/io/helidon/metrics/api/Counter.java b/metrics/api/src/main/java/io/helidon/metrics/api/Counter.java index 20d60f1620a..b212997359e 100644 --- a/metrics/api/src/main/java/io/helidon/metrics/api/Counter.java +++ b/metrics/api/src/main/java/io/helidon/metrics/api/Counter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024 Oracle and/or its affiliates. + * Copyright (c) 2023, 2025 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. @@ -16,7 +16,7 @@ package io.helidon.metrics.api; /** - * Records a monotonically increasing value. + * Records a monotonically increasing value that is updated by invoking methods on the {@code Counter} instance. */ public interface Counter extends Meter { diff --git a/metrics/api/src/main/java/io/helidon/metrics/api/DistributionSummary.java b/metrics/api/src/main/java/io/helidon/metrics/api/DistributionSummary.java index 33a71aa4e98..5852df4ca79 100644 --- a/metrics/api/src/main/java/io/helidon/metrics/api/DistributionSummary.java +++ b/metrics/api/src/main/java/io/helidon/metrics/api/DistributionSummary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024 Oracle and/or its affiliates. + * Copyright (c) 2023, 2025 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. @@ -18,7 +18,9 @@ import java.util.Optional; /** - * Records a distribution of values (e.g., sizes of responses returned by a server). + * Records a distribution of samples (e.g., sizes of responses returned by a server), each with a {@code long} value, and + * reports statistics over all samples (count, total, mean, max) as well as grouping samples using percentiles or bucket + * boundaries. */ public interface DistributionSummary extends Meter { diff --git a/metrics/api/src/main/java/io/helidon/metrics/api/Gauge.java b/metrics/api/src/main/java/io/helidon/metrics/api/Gauge.java index 3875f8ee75c..c395a304db3 100644 --- a/metrics/api/src/main/java/io/helidon/metrics/api/Gauge.java +++ b/metrics/api/src/main/java/io/helidon/metrics/api/Gauge.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024 Oracle and/or its affiliates. + * Copyright (c) 2023, 2025 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. @@ -19,7 +19,7 @@ import java.util.function.ToDoubleFunction; /** - * Measures a value that can increase or decrease and is updated by external logic, not by explicit invocations + * Exposes as a meter a value that can increase or decrease and is updated by external logic, not by explicit invocations * of methods on this type. * * @param subtype of {@link Number} which a specific gauge reports diff --git a/metrics/api/src/main/java/io/helidon/metrics/api/Timer.java b/metrics/api/src/main/java/io/helidon/metrics/api/Timer.java index 1570b1604ea..5d39ffd1e05 100644 --- a/metrics/api/src/main/java/io/helidon/metrics/api/Timer.java +++ b/metrics/api/src/main/java/io/helidon/metrics/api/Timer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024 Oracle and/or its affiliates. + * Copyright (c) 2023, 2025 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. @@ -22,7 +22,9 @@ import java.util.function.Supplier; /** - * Records timing information about large numbers of short-running events (e.g., HTTP requests). + * Accumulates timing information about large numbers of short-running events (e.g., HTTP requests), each with a + * {@link java.time.Duration} value, and reports statistics over all samples (count, total time, mean, max) as well as grouping + * samples using percentiles or bucket boundaries. */ public interface Timer extends Meter, HistogramSupport { diff --git a/parent/pom.xml b/parent/pom.xml index 91c42706b7a..9e74bd1c5d8 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -168,7 +168,7 @@ io.helidon.build-tools helidon-build-cache-maven-plugin - 4.0.14 + 4.0.15 diff --git a/pom.xml b/pom.xml index 2e5c8752724..6e5230fa3b8 100644 --- a/pom.xml +++ b/pom.xml @@ -124,7 +124,7 @@ 3.1.0 3.1.2 2.3 - 4.0.14 + 4.0.15 ${version.lib.hibernate} 3.1.2 3.2.2