Preloader image

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:

$ mvn clean install tomee:run
Alternatively, build and run the application via Docker (note the use of the docker profile):
$ mvn -Pdocker docker:build
$ 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:

$ curl -X GET http://localhost:8080/mp-metrics-counted/weather/week/status
If running via Docker, because the application is installed as the ROOT application, remove the application name from the URL:
$ curl -X GET http://localhost:8080/weather/week/status

Response:

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.

@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:

$ curl -X GET http://localhost:8080/mp-metrics-counted/metrics/application/weather_day_status

Prometheus Response:

# 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.

$ curl -X GET -H "Accept: application/json" http://localhost:8080/mp-metrics-counted/metrics/application/weather_day_status

JSON Response:

{
    "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

$ curl -X OPTIONS http://localhost:8080/mp-metrics-counted/metrics/application/weather_day_status

Response:

{
    "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.