Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for MP Metrics 2.3 #2245

Merged
merged 54 commits into from
Aug 12, 2020
Merged
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
b37bc4a
First impl of and tests for HelidonSimpleTimer
tjquinno Jul 8, 2020
d9c4a1a
MP changes for metrics 2.3.2
tjquinno Jul 9, 2020
ac7f14a
Fix incorrect JSON keys; add a few missing additions of new simple ti…
tjquinno Jul 10, 2020
ae1f734
Slight changes to fix omissions
tjquinno Jul 10, 2020
de43855
Remove FinalRegistry and its use for the base registry; part of movin…
tjquinno Jul 17, 2020
5b1d387
First impl of and tests for HelidonSimpleTimer
tjquinno Jul 8, 2020
cfa18e7
MP changes for metrics 2.3.2
tjquinno Jul 9, 2020
8d0e593
Fix incorrect JSON keys; add a few missing additions of new simple ti…
tjquinno Jul 10, 2020
2297a07
Slight changes to fix omissions
tjquinno Jul 10, 2020
db9cb71
Merge branch 'metrics-2.3' of github.com:tjquinno/helidon into metric…
tjquinno Jul 17, 2020
01ce3b8
Work-in-progress for triggering interceptor behavior for syntheticall…
tjquinno Jul 18, 2020
2c5f7fe
Concurrent changes
tjquinno Jul 21, 2020
108f9aa
Changes to implement REST.request inferred metric on JAX-RS endpoints
tjquinno Jul 24, 2020
d82e90e
Simplify logic for creating and updating synthetic REST.request Simpl…
tjquinno Jul 26, 2020
86bff51
Fix synthetic simple metric name to include parameter types
tjquinno Jul 27, 2020
b09aafe
Clarify synthetic, dynamically-added annotation added to JAX-RS endpo…
tjquinno Jul 27, 2020
23ff301
A few improvements and comment changes
tjquinno Jul 28, 2020
f2026a8
Add config control over synthetic SimplyTimed annos on JAX-RS endpoin…
tjquinno Jul 29, 2020
a08d9c3
Some clean-up
tjquinno Jul 29, 2020
1c8af5d
Update the TCK pom
tjquinno Jul 29, 2020
1af2430
Slight revision in tests
tjquinno Jul 29, 2020
cabd202
Concurrent changes
tjquinno Aug 5, 2020
340b642
Add non-public method to retrieve MetricID/HelidonMetric pairs given …
tjquinno Aug 6, 2020
14c2c3c
Make sure TYPE is emitted to Prometheus/OpenMetrics output only when …
tjquinno Aug 6, 2020
d79fc7b
Fix behavior of /metrics/registryName/metricName to report all matchi…
tjquinno Aug 6, 2020
5cc6706
Significant further steps in passing the 2.3 TCK
tjquinno Aug 7, 2020
de312fd
Undo temp change in module-info
tjquinno Aug 7, 2020
3901384
Restore earlier blank in module-info
tjquinno Aug 7, 2020
54ff8bc
Concurrent changes
tjquinno Aug 7, 2020
25af2c9
Move custom param converter and related logic from microprofile/metri…
tjquinno Aug 7, 2020
46c1ab4
Expose a way to retrieve the current Helidon flavor from features
tjquinno Aug 10, 2020
043dcb9
Add support for optional MP REST.request metrics from SE
tjquinno Aug 10, 2020
8ab874f
Change config key used for controlling REST.request feature
tjquinno Aug 10, 2020
ea9e8ce
Reflect change in config key controlling REST.request behavior
tjquinno Aug 10, 2020
4e3f9e2
Update QuickStart examples for REST.request support
tjquinno Aug 10, 2020
22e2f49
Fix typo in comments about which registry REST.request metrics appear in
tjquinno Aug 10, 2020
9918846
Enable REST.request metrics in hello-world implicit and explicit exam…
tjquinno Aug 10, 2020
e2ea732
Update doc pages to reflect SimpleTimer and, for MP, SimplyTimed and …
tjquinno Aug 11, 2020
b7f7c56
Turn on REST.request support in MP quickstart archetype; remove SE qu…
tjquinno Aug 11, 2020
05b1916
Remove changes supporting SE implementation of REST.request convenien…
tjquinno Aug 11, 2020
e5f9039
Resolve deployment URI for Arquillian in optional TCK tests for REST.…
tjquinno Aug 11, 2020
6247ab0
Fix incorrect change to HelidonFeatures; meant to remove the new meth…
tjquinno Aug 11, 2020
5c527ab
Remove now-unused setting for SE REST.request enable setting
tjquinno Aug 11, 2020
3ac7790
Restore accidentally-removed exclusion
tjquinno Aug 11, 2020
58a19d6
Fix typo in earlier correction
tjquinno Aug 11, 2020
fc4dc09
Explicitly disable REST.request support in MP examples and the MP bar…
tjquinno Aug 11, 2020
433d336
Some clean-up: remove unused code, etc.
tjquinno Aug 11, 2020
dd8b365
Remove unused import
tjquinno Aug 11, 2020
5b08e3f
Fix typo in name
tjquinno Aug 11, 2020
2a32e16
Fix missing blank line at end of file
tjquinno Aug 11, 2020
6c2db84
Fix copyright errors
tjquinno Aug 11, 2020
41f4604
Add link to the metrics spec
tjquinno Aug 11, 2020
e5620d8
Open microprofile/metrics to io.helidon.microprofile.cdi also
tjquinno Aug 12, 2020
8be8ca2
Fix module opens for integration tests
tjquinno Aug 12, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ app.greeting=Hello
# Microprofile server properties
server.port=8080
server.host=0.0.0.0

# Change the following to true to enable the optional MicroProfile Metrics REST.request metrics
metrics.rest-request.enabled=false
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ javax.sql.DataSource.test.dataSource.password=
# Microprofile server properties
server.port=8080
server.host=0.0.0.0

# Change the following to true to enable the optional MicroProfile Metrics REST.request metrics
metrics.rest-request.enabled=false
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ app.greeting=Hello
# Microprofile server properties
server.port=8080
server.host=0.0.0.0

# Turn on support for REST.request SimpleTimers for all JAX-RS endpoints
metrics.rest-request.enabled=true
13 changes: 12 additions & 1 deletion dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
<version.lib.microprofile-config>1.4</version.lib.microprofile-config>
<version.lib.microprofile-health>2.1</version.lib.microprofile-health>
<version.lib.microprofile-jwt>1.1.1</version.lib.microprofile-jwt>
<version.lib.microprofile-metrics-api>2.2</version.lib.microprofile-metrics-api>
<version.lib.microprofile-metrics-api>2.3.2</version.lib.microprofile-metrics-api>
<version.lib.microprofile-openapi-api>1.1.2</version.lib.microprofile-openapi-api>
<version.lib.microprofile-fault-tolerance-api>2.0.2</version.lib.microprofile-fault-tolerance-api>
<version.lib.microprofile-tracing>1.3.1</version.lib.microprofile-tracing>
Expand Down Expand Up @@ -656,6 +656,17 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.metrics</groupId>
<artifactId>microprofile-metrics-optional-tck</artifactId>
<version>${version.lib.microprofile-metrics-api}</version>
<exclusions>
<exclusion>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.metrics</groupId>
<artifactId>microprofile-metrics-api-tck</artifactId>
Expand Down
43 changes: 40 additions & 3 deletions docs/mp/guides/05_metrics.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ curl http://localhost:8080/metrics
[source,text]
.Text response:
----
# TYPE base_REST_request_total counter
# HELP base_REST_request_total The number of invocations and total response time of RESTful resource methods since the start of the server.
base_REST_request_total{class="io.helidon.examples.quickstart.mp.GreetResource",method="getDefaultMessage"} 0
# TYPE base_REST_request_elapsedTime_seconds gauge
base_REST_request_elapsedTime_seconds{class="io.helidon.examples.quickstart.mp.GreetResource",method="getDefaultMessage"} 0.0
base_REST_request_total{class="io.helidon.examples.quickstart.mp.GreetResource",method="getMessage_java.lang.String"} 0
base_REST_request_elapsedTime_seconds{class="io.helidon.examples.quickstart.mp.GreetResource",method="getMessage_java.lang.String"} 0.0
base_REST_request_total{class="io.helidon.examples.quickstart.mp.GreetResource",method="updateGreeting_javax.json.JsonObject"} 0
base_REST_request_elapsedTime_seconds{class="io.helidon.examples.quickstart.mp.GreetResource",method="updateGreeting_javax.json.JsonObject"} 0.0
# TYPE base:classloader_current_loaded_class_count counter
# HELP base:classloader_current_loaded_class_count Displays the number of classes that are currently loaded in the Java virtual machine.
base:classloader_current_loaded_class_count 7511
Expand All @@ -104,6 +113,15 @@ curl -H "Accept: application/json" http://localhost:8080/metrics
----
{
"base": {
"REST.request":
{
"count;class=io.helidon.examples.quickstart.mp.GreetResource;method=getDefaultMessage":0,
"elapsedTime;class=io.helidon.examples.quickstart.mp.GreetResource;method=getDefaultMessage":0.0,
"count;class=io.helidon.examples.quickstart.mp.GreetResource;method=getMessage_java.lang.String":0,
"elapsedTime;class=io.helidon.examples.quickstart.mp.GreetResource;method=getMessage_java.lang.String":0.0,
"count;class=io.helidon.examples.quickstart.mp.GreetResource;method=updateGreeting_javax.json.JsonObject":0,
"elapsedTime;class=io.helidon.examples.quickstart.mp.GreetResource;method=updateGreeting_javax.json.JsonObject":0.0
},
"classloader.currentLoadedClass.count": 7534,
"classloader.totalLoadedClass.count": 7538,
"classloader.totalUnloadedClass.count": 1,
Expand Down Expand Up @@ -166,6 +184,19 @@ curl -H "Accept: application/json" http://localhost:8080/metrics/vendor/grpc.re

NOTE: You cannot get the individual fields of a metric. For example, you cannot target http://localhost:8080/metrics/vendor/grpc.requests.meter.count.

==== Controlling `REST.request` metrics
Helidon implements the optional family of metrics, all with the name `REST.request`, as described in the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a link here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sigh. I had started to include one and got distracted and forgot to. Adding it.

MicroProfile Metrics specification.
Each instance is a `SimpleTimer` with tags `class` and `method` identifying exactly which REST endpoint Java
method that instance measures.

By default, Helidon MP does _not_ enable this feature.
Enable it by editing your application configuration to set `metrics.rest-request.enabled` to `true`.

Note that the applications you generate using the full Helidon archetype _do_ enable this feature in the
generated config file.
You can see the results in the sample output shown in earlier example runs.

=== Metrics metadata

Each metric has associated metadata that describes:
Expand Down Expand Up @@ -222,11 +253,12 @@ Each metric annotation has mandatory and optional fields. The name field, for ex

==== Method level metrics

There are three metrics that you can use by annotating a method:
There are four metrics that you can use by annotating a method:

1. `@Counted` - Register a `Counter` metric
2. `@Timed` - Register a `Timer` metric
3. `@Metered` - Register a `Meter` metric
4. `@SimplyTimed` - Register a `SimpleTimer` metric

The following example will demonstrate how to use the `@Counted` annotation to track the number of times
the `/cards` endpoint is called.
Expand Down Expand Up @@ -312,8 +344,13 @@ You must use `absolute=false` for class-level annotations.

==== Additional method-level metrics

The `@Timed` and `@Metered` annotations can also be used with a method. For the following example. you can just annotate the same method with these metrics.
When using multiple annoations on a method, you *must* give the metrics different names as shown below.
The `@Timed`, `@Metered`, and `@SimplyTimed` annotations can also be used with a method. For the following example.
you can just annotate the same method with `@Metered` and `@Timed`. These metrics collect significant
information about the measured methods, but at a cost of some overhead and more complicated output.
Use `@SimplyTimed` in cases where capturing the invocation count and the total elapsed time
spent in a block of code is sufficient.

Note that when using multiple annotations on a method, you *must* give the metrics different names as shown below.

[source,java]
.Update the `GreetingCards` class with the following code:
Expand Down
80 changes: 80 additions & 0 deletions docs/se/guides/05_metrics.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,8 @@ curl -H "Accept: application/json" http://localhost:8080/metrics/application

==== Timer metric

(See also <<#simple_timer_metric,Simple timer metric>>.)

The `Timer` metric aggregates durations, provides timing statistics, and includes throughput statistics
using an internal `Meter` metric. The `Timer` measures duration in nanoseconds. In the following example,
a `Timer` metric is used to measure the duration of a method's execution. Whenever the REST `/cards`
Expand Down Expand Up @@ -714,6 +716,84 @@ curl -H "Accept: application/json" http://localhost:8080/metrics/application
----
<1> The current temperature is returned. Invoke the `/metrics/application` endpoint again and you should get a different value.

[[simple_timer_metric]]
==== Simple timer metric

The `SimpleTimer` metric counts invocations and accumulates duration (in seconds). In the following example,
a `SimpleTimer` metric is used to count and measure the duration of a method's execution. Whenever the REST `/cards`
endpoint is called, the `SimpleTimer` updates its count and total elapsed time.

[source,java]
.Update the `GreetingCards` class with the following code:
----
package io.helidon.examples.quickstart.se;

import io.helidon.metrics.RegistryFactory;
import io.helidon.webserver.Routing;
import io.helidon.webserver.ServerRequest;
import io.helidon.webserver.ServerResponse;
import io.helidon.webserver.Service;
import java.util.Collections;
import javax.json.Json;
import javax.json.JsonBuilderFactory;
import javax.json.JsonObject;
import org.eclipse.microprofile.metrics.MetricRegistry; // <1>
import org.eclipse.microprofile.metrics.SimpleTimer;

public class GreetingCards implements Service {

private static final JsonBuilderFactory JSON = Json.createBuilderFactory(Collections.emptyMap());
private final SimpleTimer cardTimer; // <2>

GreetingCards() {
RegistryFactory metricsRegistry = RegistryFactory.getInstance();
MetricRegistry appRegistry = metricsRegistry.getRegistry(MetricRegistry.Type.APPLICATION);
cardTimer = appRegistry.simpleTimer("cardSimpleTimer"); // <3>
}

@Override
public void update(Routing.Rules rules) {
rules.get("/", this::getDefaultMessageHandler);
}

private void getDefaultMessageHandler(ServerRequest request, ServerResponse response) {
cardTimer.time(() -> sendResponse(response, "Here are some cards ...")); // <4>
}

private void sendResponse(ServerResponse response, String msg) {
JsonObject returnObject = JSON.createObjectBuilder().add("message", msg).build();
response.send(returnObject);
}
}
----
<1> Import metrics classes, particularly the `SimpleTimer` interface for this example.
<2> Declare a `SimpleTimer` member variable.
<3> Create and register the `SimpleTimer` metric in the `MetricRegistry`.
<4> Wrap the business logic in the simple timer's `time` method which updates the count and the total elapsed time.


[source,bash]
.Build and run the application, then invoke the endpoints below:
----
curl http://localhost:8080/cards
curl -H "Accept: application/json" http://localhost:8080/metrics/application
----


[source,json]
.JSON response:
----
{
"cardSimpleTimer":
{
"count":1, <1>
"elapsedTime":0.034274025 <2>
}
}
----
<1> How many times the `getDefaultMessageHandler` method ran.
<2> Cumulative time spent in the `getDefaultMessageHandler` method during its executions.


=== Integration with Kubernetes and Prometheus

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2020 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.
Expand All @@ -18,3 +18,6 @@ app.name=Hello World Application
app.uri=https://www.example.com

my.property=propertyValue

# Enable the optional MicroProfile Metrics REST.request metrics
metrics.rest-request.enabled=true
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2020 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.
Expand All @@ -22,3 +22,5 @@ app.ints=12,12,32,12,44

server.port=7001

# Enable the optional MicroProfile Metrics REST.request metrics
metrics.rest-request.enabled=true
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2018, 2020 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.
Expand All @@ -20,3 +20,6 @@ app.greeting=Hello
# Microprofile server properties
server.port=8080
server.host=0.0.0.0

# Enable the optional MicroProfile Metrics REST.request metrics
metrics.rest-request.enabled=true
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ app.greeting=Hello
# Microprofile server properties
server.port=8080
server.host=0.0.0.0

# Enable the optional MicroProfile Metrics REST.request metrics
metrics.rest-request.enabled=true
Loading