= MicroProfile Metrics Counted
:index-group: MicroProfile
:jbake-type: page
:jbake-status: published

This is an example of how to use microprofile metrics in TomEE.  The project
includes a docker profile which can be used to create a Docker image.

== Run the application:

[source,bash]
----
$ mvn clean install tomee:run
----

NOTE: Alternatively, build and run the application via Docker (note the use of the docker profile):

[source,bash]
----
$ mvn -Pdocker docker:build
----

[source,bash]
----
$ docker run -it --rm -p 8080:8080 --name=tomee-mp-metrics-counted tomee/mp-metrics-counted
----

Within the application, there is an endpoint that will give you weather
status for the day and week.

== Get the weather for the week:

[source,bash]
----
$ curl -X GET http://localhost:8080/mp-metrics-counted/weather/week/status
----

IMPORTANT: If running via Docker, because the application is installed as the ROOT application, remove the application name from the URL:

[source,bash]
----
$ curl -X GET http://localhost:8080/weather/week/status
----

== Response:

[source,text]
----
Hi, today is a sunny day!
----

== Counted Feature

MicroProfile metrics has a feature that can be used to count requests to
a service.

To use this feature you need to annotate the JAX-RS resource method with
`@Counted`.

[source,java]
----
@Path("/weather")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ApplicationScoped
public class WeatherService {

    @Path("/day/status")
    @Counted(monotonic = true, name = "weather_day_status", absolute = true)
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String dayStatus() {
        return "Hi, today is a sunny day!";
    }
...
}
----

There are some configurations, as part of `@Counted`, that you need to know:

*String name* Optional. Sets the name of the metric. If not explicitly given
the name of the annotated object is used.

*boolean absolute* If true, uses the given name as the absolute name of the
metric. If false, prepends the package name and class name before the given
name. Default value is false.

*String displayName* Optional. A human-readable display name for metadata.

*String description* Optional. A description of the metric.

*String[] tags* Optional. Array of Strings in the = format to supply special
tags to a metric.

*boolean reusable* Denotes if a metric with a certain name can be registered in
more than one place. Does not apply to `@Gauge`.

== Metric data

Check the counter metric doing a _GET_ request:

=== Prometheus format:

[source,bash]
----
$ curl -X GET http://localhost:8080/mp-metrics-counted/metrics/application/weather_day_status
----

=== Prometheus Response:

[source,text]
----
# TYPE application:weather_day_status counter
application:weather_day_status 1.0
----

=== JSON Format:

For json format add the header `Accept: application/json` to the HTTP request.

[source,bash]
----
$ curl -X GET -H "Accept: application/json" http://localhost:8080/mp-metrics-counted/metrics/application/weather_day_status
----

=== JSON Response:

[source,javascript]
----
{
    "weather_day_status": {
        "delegate": {},
        "unit": "none",
        "count": 1
    }
}
----

== Metric metadata

A metric will have metadata so you can know more information about it,
like `displayName`, `description`, `tags`, etc.

Check the metric metadata doing a _OPTIONS_ HTTP request:

=== _OPTIONS_ HTTP Request

[source,bash]
----
$ curl -X OPTIONS http://localhost:8080/mp-metrics-counted/metrics/application/weather_day_status
----

=== Response:

[source,javascript]
----
{
    "weather_day_status": {
        "unit": "none",
        "displayName": "Weather Day Status",
        "name": "weather_day_status",
        "typeRaw": "COUNTER",
        "description": "This metric shows the weather status of the day.",
        "type": "counter",
        "value": {
            "unit": "none",
            "displayName": "Weather Day Status",
            "name": "weather_day_status",
            "tagsAsString": "",
            "typeRaw": "COUNTER",
            "description": "This metric shows the weather status of the day.",
            "type": "counter",
            "reusable": false,
            "tags": {}
        },
        "reusable": false,
        "tags": ""
    }
}
----

You can also try it out using the WeatherServiceTest.java available in the
project.
