= Métricas com MicroProfile `@Counted` (Contado)
:index-group: MicroProfile
:jbake-type: page
:jbake-status: published

Este é um exemplo sobre como utilizar as métricas de MicroProfile no Tomee. O projeto inclui um perfil de Docker que se pode usar para criar uma imagem de Docker.

== Executando a aplicação:

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

NOTE: Como alternativa, compile e execute o aplicativo através do Docker
(observe o uso do perfil docker):

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

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

Dentro do aplicativo, há um endpoint que fornecerá o estado do tempo para o dia e a semana.

== Veja o clima da semana:

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

IMPORTANTE: Se você executar usando o Docker, porque o aplicativo está instalado
como o aplicativo ROOT, remova o nome do aplicativo do URL:

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

== Resposta:

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

== Usando `@Counted`

As métricas do MicroProfile têm uma função que pode ser usada para contar requisições para um serviço.

Para usar esta função, você deve anotar os métodos dos recursos JAX-RS com `@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!";
    }
...
}
----

Existem algumas configurações, como parte do `@Counted`, que você precisa saber:

*String name* Opcional. Define o nome da métrica. Se não for fornecido
explicitamente, o nome do objeto anotado é usado.

*boolean absolute* Se verdadeiro, use o nome fornecido como o nome absoluto da métrica. 
Se falso, coloque o nome do pacote e o nome da classe antes do nome fornecido. O valor padrão é falso.

*String displayName* Opcional. Um nome de exibição legível para
metadados.

*String description* Opcional. Uma descrição da métrica.

*String[] tags* Opcional. Matriz de cadeia no formato = para fornecer
etiquetas especiais para uma métrica.

*boolean reusable* Indica se uma métrica com um determinado nome pode ser
registrado em mais de um local. Não se aplica a `@Gauges` (metros).

== Dados Métricos

Verifique a métrica do contador, fazendo uma solicitação _GET_:

=== Formato Prometheus:

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

=== Resposta Prometheus:

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

=== Formato JSON:

Para o formato json, adicione o cabeçalho `Accept:application/json` à requisição HTTP.

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

=== Resposta JSON:

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

== Metadatos Métrica

Uma métrica terá metadados para que você possa saber mais sobre ela, como `displayName`,`descrição`, `tags` etc.

Verifique os metadados da métrica fazendo uma requisição HTTP _OPTIONS_:

=== Requisição HTTP _OPTIONS_

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

=== Resposta:

[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": ""
    }
}
----

Você também pode testá-lo usando WeatherServiceTest.java disponível no projeto.
