![[17.0.0.3 and later]](../ng_v17003plus.gif)
API de instrumentación de métricas de MicroProfile
Puede utilizar la API de métricas de MicroProfile para añadir métricas a las aplicaciones. La API de métricas de MicroProfile es similar a la API de métricas de Dropwizard.
Arquitectura de métricas de MicroProfile
- Base
- El registro base se utiliza para métricas del servidor como sea necesario desde la especificación de métricas de MicroProfile.
- Proveedor
- El registro de proveedor se utiliza para las métricas añadidas por el proveedor de producto, en este caso Liberty.
- Aplicación
- El registro de aplicación se utiliza para las métricas añadidas por las aplicaciones. El registro de aplicación es el MetricRegistry predeterminado.
Las característica mpMetrics-1.0 y mpMetrics-1.1 también incluyen un punto final /metrics, que proporciona la interfaz HTTP con la que deben interactuar los navegadores y las herramientas de supervisión.
Comprobación de valores de métricas
Las métricas MicroProfile proporcionan un punto final /metrics al que puede acceder utilizando HTTP. Después de que el servidor de Liberty se haya iniciado con la configuración adecuada, puede ver las métricas desde cualquier navegador.
https://localhost:9443/metrics
En general, los equipos de operaciones configuran herramientas para supervisar y registrar los valores de métrica a lo largo del tiempo.
Adición de métricas a las aplicaciones
- Utilizando MetricRegistry directamente. Utilizando este método, el código de aplicación crea explícitamente las métricas y las registra.
- Utilizando CDI para inyectar métricas. Utilizando este método, CDI crea implícitamente las métricas y éstas se registran en el MetricRegistry de aplicación.
- Utilizando anotaciones de métricas. Utilizando este método, CDI crea implícitamente las métricas y éstas se registran en el MetricRegistry de aplicación.
Administración directa de MetricRegistry
MetricRegistry almacena todas las métricas y sus metadatos respectivos. Las métricas y los metadatos se pueden registrar y recuperar mediante el uso de los métodos que se proporcionan. De forma predeterminada, todas las métricas relacionadas con la aplicación se añaden a MetricRegistry con el ámbito de una sola aplicación.
@Inject
MetricRegistry registry;
Registro de métricas
La clase MetricRegistry tiene métodos que pueden recuperar o crear contadores, medidores, histogramas y temporizadores.
Metadata counterMetadata = new Metadata(…);
…
// Crear o recuperar la métrica por Metadata.getName()
Counter counterMetric = registry.counter(counterMetadata);
Timer timerMetric = registry.timer(timerMetadata);
Histogram histogramMetric = registry.histogram(histogramMetadata);
Meter meterMetric = registry.meter(meterMetadata);
// Registrar una métrica de indicador por Metadata.getName()
registry.register("gaugeMetric", gaugeMetric, gaugeMetadata);
Descripción de métricas con metadatos
Los metadatos son un conjunto de datos que describen y resumen información sobre las métricas y pueden facilitar la búsqueda y el trabajo con diferentes tipos de métricas. Los metadatos pueden ser suficientemente granulares para definir información a nivel de atributo.
Los metadatos de métrica constan de los atributos siguientes:
- Unidad
- Un conjunto fijo de unidades de serie.
- Tipo
- Indicador, contador, medidor, histograma o temporizador.
- Descripción
- Una descripción legible por usuario de la métrica.
- Nombre de visualización
- Un nombre legible por personas de la métrica a efectos de visualización si el nombre de métrica no es legible por las personas, por ejemplo, cuando el nombre de métrica es un UUID.
- Etiquetas
- Una lista de pares de clave y valor (clave=valor), que están separados por comas.
Reutilizable
En MicroProfile Metrics versión 1.1 y superior, reutilizable es un booleano para indicar que se puede reutilizar el nombre de métrica. Por ejemplo, si desea reutilizar una única métrica mientras anota varios métodos.
export MP_METRICS_TAGS=app=shop,node=2932
También puede utilizar MicroProfile Config para configurar
MP_METRICS_TAGS. Para obtener más información sobre cómo configurar
MP_METRICS_TAGS, consulte
Ubicaciones de valor de configuración válida en el tiempo de ejecución de Liberty.
Contadores
Los contadores son una métrica que se utiliza para mantener un recuento incremental o de reducción. El valor inicial del contador se establece en 0 y se puede incrementar utilizando inc() o inc(long n) y reducir utilizando dec() o dec(long n).
Puede utilizar un contador para contar el número total de solicitudes que se reciben o el número total de sesiones HTTP activas simultáneamente.
Metadata statsHitsCounterMetadata = new Metadata(
"statsHits", // nombre
"Stats Hits", // nombre de visualización
"Number of hits on the /stats endpoint", // descripción
MetricType.COUNTER, // tipo
MetricUnits.NONE); // unidades
Counter statsHitsCounter = registry.counter(statsHitsCounterMetadata);
@GET
@Path("/donations")
public String getTotalDonations() {
statsHitsCounter.inc();
return "$" + donationManager.getTotalDonations();
}
curl -k -u user:password https://localhost:9443/metrics/application/statsHits
# TYPE application:stats_hits counter
# HELP application:stats_hits Number of hits on the /stats endpoint
application:stats_hits 213
curl -k -u user:password -H “Accept: application/json” https://localhost:9443/metrics/application/statsHits
{"statsHits":213}
Indicadores
Los indicadores representan métricas que son muestras para obtener su valor.
Un indicador es una interfaz que el desarrollador necesita implementar. Dado que no se ha definido la implementación de un indicador, se deben registrar manualmente con MetricRegistry utilizando el método de MetricRegistry .register(). Asegúrese de que register() sólo se utiliza una vez por métrica. No puede registrar dos métricas con el mismo nombre. Utilizará un indicador para medir la temperatura de CPU o para medir el uso de disco.
Gauge<Double> progressGauge = new Gauge<Double>() {
public Double getValue() {
return (double) getTotalDonations()
/ (double) getGoal() * 100.0;
}
};
// Indicador
Metadata progressMetadata = new Metadata(
"progress", // nombre
"Donation Progress", // nombre de visualización
"The percentage of the goal achieved so far", // descripción
MetricType.GAUGE, // tipo
MetricUnits.PERCENT); // unidades
registry.register(progressMetadata.getName(), progressGauge, progressMetadata);
curl -k -u user:password https://localhost:9443/metrics/application/progress
# TYPE application:progress_percent gauge
# HELP application:progress_percent The percentage of the goal achieved so far
application:progress_percent 4.472
curl -k -u user:password -H "Accept: application/json" https://localhost:9443/metrics/application/progress
{"progress":4.472}
Medidores
Los medidores se utilizan para realizar el seguimiento del rendimiento.
- Promedio de rendimiento
- Media móvil ponderada exponencialmente de rendimiento de uno/cinco/quince minutos.
- Un recuento del número de mediciones.
Pude utilizar un medidor para calcular la tasa de transacciones procesadas por una aplicación.
Metadata getProgressMeterMetadata = new Metadata(
"getProgressMeter", // nombre
"getProgress Call Rate", // nombre de visualización
"The rate of getProgress calls", // descripción
MetricType.METERED, // tipo
MetricUnits.SECONDS); // unidades
Meter getProgressMeter = registry.meter(getProgressMeterMetadata);
public Double getProgress() {
getProgressMeter.mark();
return (double) getTotalDonations()/(double) getGoal() * 100.0;
}
curl -k -u user:password https://localhost:9443/metrics/application/getProgressMeter1
# TYPE application:get_progress_meter_total counter
# HELP application:get_progress_meter_total The rate of getProgress calls
application:get_progress_meter_total 78
# TYPE application:get_progress_meter_rate_per_second gauge
application:get_progress_meter_rate_per_second 0.6584919803150174
# TYPE application:get_progress_meter_one_min_rate_per_second gauge
application:get_progress_meter_one_min_rate_per_second 0.5851884005757912
# TYPE application:get_progress_meter_five_min_rate_per_second gauge
application:get_progress_meter_five_min_rate_per_second 1.4218610926179416
# TYPE application:get_progress_meter_fifteen_min_rate_per_second gauge
application:get_progress_meter_fifteen_min_rate_per_second 1.6627979138032118
curl -k -u user:password -H "Accept: application/json" https://localhost:9443/metrics/application/getProgressMeter
{
"getProgressMeter": {
"count": 78,
"fifteenMinRate": 1.6627979138032118,
"fiveMinRate": 1.4218610926179416,
"meanRate": 0.6584919803150174,
"oneMinRate": 0.5851884005757912
}
}
Histogramas
Los histogramas se utilizan para almacenar la distribución de valores.
Para registrar un valor en el histograma, debe llamar a histogram.update(long value) con el valor que desea registrar. El estado actual (o instantánea) del histograma puede recuperarse utilizando getSnapshot(). Los histogramas de métricas de MicroProfile sólo soportan valores enteros o largos.
- Valores mínimo, máximo, medio
- El valor en los percentiles 50, 75, 95, 98, 99, 99,9
- Un recuento del número de valores
Los ejemplos de histogramas incluyen la distribución de tamaños de carga útil que se recuperan o para una encuesta de incorporación que recopila la distribución de los ingresos familiares.
Metadata donationDistributionMetadata = new Metadata(
"donationDistribution", // nombre
"Donation Distribution", // nombre de visualización
"The distribution of the donation amounts ", // descripción
MetricType.HISTOGRAM, // tipo
“dollars”); // unidades
Histogram donationDistribution = registry.histogram(donationDistributionMetadata);
public void addDonation(Long amount) {
totalDonations += amount;
donations.add(amount);
donationDistribution.update(amount);
}
curl -k -u user:password https://localhost:9443/metrics/application/com.example.samples.donationapp.DonationManager.donationDistribution
# TYPE application:com_example_samples_donationapp_donation_manager_donation_distribution_mean_dollars gauge
application:com_example_samples_donationapp_donation_manager_donation_distribution_mean_dollars 19.300015535407777
# TYPE application:com_example_samples_donationapp_donation_manager_donation_distribution_max_dollars gauge
application:com_example_samples_donationapp_donation_manager_donation_distribution_max_dollars 102.0
# TYPE application:com_example_samples_donationapp_donation_manager_donation_distribution_min_dollars gauge
application:com_example_samples_donationapp_donation_manager_donation_distribution_min_dollars 3.0
# TYPE application:com_example_samples_donationapp_donation_manager_donation_distribution_stddev_dollars gauge
application:com_example_samples_donationapp_donation_manager_donation_distribution_stddev_dollars 26.35464238355834
# TYPE application:com_example_samples_donationapp_donation_manager_donation_distribution_dollars summary
# HELP application:com_example_samples_donationapp_donation_manager_donation_distribution_dollars The distribution of the donation amounts
application:com_example_samples_donationapp_donation_manager_donation_distribution_dollars_count 203
application:com_example_samples_donationapp_donation_manager_donation_distribution_dollars{quantile="0.5"} 5.0
application:com_example_samples_donationapp_donation_manager_donation_distribution_dollars{quantile="0.75"} 24.0
application:com_example_samples_donationapp_donation_manager_donation_distribution_dollars{quantile="0.95"} 83.0
application:com_example_samples_donationapp_donation_manager_donation_distribution_dollars{quantile="0.98"} 93.0
application:com_example_samples_donationapp_donation_manager_donation_distribution_dollars{quantile="0.99"} 101.0
application:com_example_samples_donationapp_donation_manager_donation_distribution_dollars{quantile="0.999"} 102.0
curl -k -u user:password -H "Accept: application/json" https://localhost:9443/metrics/application/com.example.samples.donationapp.DonationManager.donationDistribution
{
"com.example.samples.donationapp.DonationManager.donationDistribution": {
"count": 203,
"max": 102,
"mean": 19.300015535407777,
"min": 3,
"p50": 5.0,
"p75": 24.0,
"p95": 83.0,
"p98": 93.0,
"p99": 101.0,
"p999": 102.0,
"stddev": 26.35464238355834
}
}
Temporizadores
Los temporizadores se utilizan para agregar duraciones de temporización, en nanosegundos, y proporcionar estadísticas duración y rendimiento.
Para medir una parte del código, puede llamar a timer.time(), que devuelve un objeto timer.context. Este contexto se utiliza para detener el temporizador llamando a context.close(). La información que se recupera del temporizador es una combinación de un medidor y un histograma de duraciones temporizadas.
- Tiempos máximo, mínimo y medio.
- El valor de tiempo en el percentil 50, 75, 95, 98, 99, 99,9.
- Promedio de rendimiento
- Media móvil ponderada exponencialmente de rendimiento de uno/cinco/quince minutos.
- Un recuento del número de sucesos temporizados.
Ejemplos de lo que puede utilizar un temporizador para incluir los tiempos de respuesta de medición y el tiempo de proceso de medición para la lógica compleja.
Metadata topDonationCalcTimerMetadata = new Metadata(
"topDonationCalcTimer", // nombre
"Top Donation Calculation Time", // nombre de visualización
"Processing time to find the top donation", // descripción
MetricType.TIMER, // tipo
MetricUnits.NANOSECONDS); // unidades
Timer topDonationCalcTimer = registry.timer(topDonationCalcTimerMetadata);
public Long getTopDonation() {
// Iniciar temporización aquí
Timer.Context context = topDonationCalcTimer.time();
Long max = 0L;
for (Long amount : donationManager.getDonationsList()) {
max = amount > max ? amount : max;
}
// Detener temporización
context.close();
return max;
}
curl -k -u user:password https://localhost:9443/metrics/application/topDonationCalcTimer
# TYPE application:top_donation_calc_timer_rate_per_second gauge
application:top_donation_calc_timer_rate_per_second 0.19107302754898328
# TYPE application:top_donation_calc_timer_one_min_rate_per_second gauge
application:top_donation_calc_timer_one_min_rate_per_second 0.013233974568205872
# TYPE application:top_donation_calc_timer_five_min_rate_per_second gauge
application:top_donation_calc_timer_five_min_rate_per_second 0.4845914744130395
# TYPE application:top_donation_calc_timer_fifteen_min_rate_per_second gauge
application:top_donation_calc_timer_fifteen_min_rate_per_second 0.8866728789348088
# TYPE application:top_donation_calc_timer_mean_seconds gauge
application:top_donation_calc_timer_mean_seconds 9.37780684853573E-5
# TYPE application:top_donation_calc_timer_max_seconds gauge
application:top_donation_calc_timer_max_seconds 1.97197E-4
# TYPE application:top_donation_calc_timer_min_seconds gauge
application:top_donation_calc_timer_min_seconds 4.9630000000000004E-5
# TYPE application:top_donation_calc_timer_stddev_seconds gauge
application:top_donation_calc_timer_stddev_seconds 3.082659934664267E-5
# TYPE application:top_donation_calc_timer_seconds summary
# HELP application:top_donation_calc_timer_seconds Processing time to find the top donation
application:top_donation_calc_timer_seconds_count 63
application:top_donation_calc_timer_seconds{quantile="0.5"} 8.6069E-5
application:top_donation_calc_timer_seconds{quantile="0.75"} 1.0372E-4
application:top_donation_calc_timer_seconds{quantile="0.95"} 1.53694E-4
application:top_donation_calc_timer_seconds{quantile="0.98"} 1.96615E-4
application:top_donation_calc_timer_seconds{quantile="0.99"} 1.97197E-4
application:top_donation_calc_timer_seconds{quantile="0.999"} 1.97197E-4
curl -k -u user:password -H "Accept: application/json" https://localhost:9443/metrics/application/topDonationCalcTimer
{
"topDonationCalcTimer": {
"count": 63,
"fifteenMinRate": 0.8866728789348088,
"fiveMinRate": 0.4845914744130395,
"max": 197197,
"mean": 93778.06848535729,
"meanRate": 0.19107302754898328,
"min": 49630,
"oneMinRate": 0.013233974568205872,
"p50": 86069.0,
"p75": 103720.0,
"p95": 153694.0,
"p98": 196615.0,
"p99": 197197.0,
"p999": 197197.0,
"stddev": 30826.599346642666
}
}
Inyección de métricas utilizando CDI
- @Metric: Una anotación que describe la métrica que se inyecta. Esta anotación se puede utilizar en los campos de tipo de Medidor, Temporizador, Contador e Histograma.
- Parámetros de @Metric: name, displayname, units, tags, description, absolute.
Los parámetros para la anotación @Metric son similares al campo de metadatos correspondiente con las siguientes diferencias.El servidor crea y registra un contador en el MetricRegistry y lo proporciona para que la aplicación lo utilice. El ejemplo de contador es equivalente al ejemplo statsHitsCounter. absolute=true significa que el nombre proporcionado se utiliza tal cual. El parámetro units no se utiliza y toma MetricUnits.NONE de forma predeterminada.
- tags: Una matriz de series de etiqueta clave=valor
- absolute: Si es verdadero, establezca el nombre de métrica en el nombre exacto que se especifica en el parámetro de nombre. Si es falso, utilice el nombre completo añadiendo un prefijo a la clase de paquete y nombre.
@Inject @Metric(name="statsHits", displayName="Stats Hits", description="Number of hits on the /stats endpoint", absolute=true) Counter statsHitsCounter;
@Inject @Metric(name= "topDonationCalcTimer", unit = MetricUnits.NANOSECONDS, description="Processing time to find the top donation") Timer topDonationCalcTimer; @Inject @Metric(absolute = true, tags=["appName=DonationApp"]) Counter counted;
Anotaciones de métricas
Las métricas de MicroProfile también tienen varios interceptores para manejar las anotaciones @Counted, @Timed, @Metered y @Gauge.
- @Counted
- Una anotación para marcar un método, constructor o tipo como contador. Junto con los campos
de metadatos, el contador también tiene un campo monotónico adicional. Si monotonic se
establece en false, el contador se incrementa cuando se llama al método anotado y disminuye cuando
se devuelve el método anotado, contando las invocaciones actuales del método anotado. Si monotonic
se establece en true, el contador aumenta de forma monotónico, contando las invocaciones totales
del método anotado.Nota: De forma predeterminada, monotonic se establece en false.
@GET @Path("/no") @Counted(name="no", displayName="No donation count", description="Number of people that declined to donate.", monotonic=true) public String noDonation() { return "Maybe next time!"; }
- @Timed
- Una anotación para marcar un constructor o método de un objeto anotado como temporizado. La
métrica de temporizador realiza el seguimiento de la frecuencia con la que se inicia el objeto anotado
y realiza el seguimiento del tiempo que tardan las invocaciones en completarse.
@POST @Path("/creditcard") @Timed( name="donateAmountViaCreditCard.timer", displayName="Donations Via Credit Cards", description = "Donations that were made using a credit card") public String donateAmountViaCreditCard(@FormParam("amount") Long amount, @FormParam("card") String card) { if (processCard(card, amount)) return "Thanks for donating!"; return "Sorry, please try again."; }
- @Metered
- Una anotación para marcar un constructor o método como medido. El medidor cuenta las invocaciones
del constructor o método y realiza el seguimiento de la frecuencia con la que se llaman.
@Metered(displayName="Rate of donations", description="Rate of incoming donations (the instances not the amount)") public void addDonation(Long amount) { totalDonations += amount; donations.add(amount); donationDistribution.update(amount); }
- @Gauge
- Una anotación para marcar un método como un indicador.
@Gauge( name="donations", displayName="Total Donations", description="Total amount of money raised for charity!", unit = "dollars", absolute=true) public Long getTotalDonations(){ return totalDonations; }
![[18.0.0.1 and later]](../ng_v18001plus.gif)
- Reutilización de métricas
- Cuando utiliza MicroProfile Metrics versión 1.1 y superior, puede reutilizar las métricas. Las
anotaciones @Counted, @Metered y @Timed tienen
un distintivo para indicar que la métrica puede ser reutilizada por otras anotaciones. Por ejemplo,
la aplicación puede tener varios puntos finales para diferentes métodos de pago. Para realizar el seguimiento
del número de pagos en todos los métodos de pago, puede utilizar el mismo nombre de métrica estableciendo
reusable=true. Los ejemplos siguientes ilustran el uso de muestra.
@POST @Path("/creditcard") @Counted( name="donation.counter", displayName="Number of donations", description = "Donations that were made using any method", monotonic=true, reusable=true) public String donateAmountViaCreditCard(@FormParam("amount") Long amount, @FormParam("card") String card) { if (processCard(card, amount)) return "Thanks for donating!"; return "Sorry, please try again."; }
@POST @Path("/debitcard") @Counted( name="donations.counter", displayName="Number of donations", description = "Donations that were made using any method", monotonic=true, reusable=true) public String donateAmountViaDebitCard(@FormParam("amount") Long amount, @FormParam("card") String card) { if (processDebitCard(card, amount)) return "Thanks for donating!"; return "Sorry, please try again."; }
Sugerencias de CDI
La característica mpMetrics-1.0 se basa en CDI. La inyección CDI se utiliza siempre que se desea inyectar un MetricRegistry o inyectar uno de los tipos de métrica en un campo. Los interceptores de CDI se utilizan para aplicar las métricas @Timed, @Counted, @Metered y @Gauge alrededor de los tipos, constructores o métodos.
- Utilización de archivos de beans explícitos
- Para que el inicio de aplicación sea eficiente, asegúrese de que los archivos de bean tienen un archivo beans.xml. Si está creando una aplicación web, el archivo beans.xml debe estar en el directorio WEB-INF. Si está creando un módulo EJB o un archivo JAR, el archivo beans.xml debe estar en el directorio META-INF. Si elude la capacidad de archivado de bean implícito de CDI en las aplicaciones, puede ajustar el servidor de Liberty para evitar explorar los archivados de bean en el inicio.
- Limitaciones para los interceptores @Timed, @Counted, @Metered, @Gauge
- CDI se basa en interceptores Java para las anotaciones de métricas que se implementan en Liberty como interceptores. Las anotaciones @Timed, @Counted, @Metered y @Gauge se implementan utilizando interceptores. Los interceptores se basan en poder crear un proxy que pueda iniciarse en la vía de acceso de código antes de poder llamar a los constructores o métodos con anotaciones de interceptor. El código de interceptor es el lugar donde se actualizan las métricas. Existen límites en qué clase de código puede ser proxy y dónde se pueden utilizar las anotaciones de interceptor. Sólo los beans gestionados, definidos por CDI, que pueden ser proxy se pueden utilizar con interceptores. Los proxies se implementan como subclases del bean en el que actúan como proxy. Para garantizar que una clase pueda ser proxy, la clase no debe marcarse como final y debe ser un constructor sin argumentos no privado.
- Limitaciones para la inyección
- Para inyectar (@Inject) tipos como MetricRegistry en una clase, dicha clase debe
estar gestionada por CDI. El siguiente ejemplo de JAX-RS ilustra
someclass.setMetricsRegistry al que
CDI llama automáticamente.
La clase no se llama en el siguiente ejemplo:@Path("/myPath") public class MyService { // el ciclo de vida de Someclass estará gestionado por CDI @Inject Someclass someclass; ... } public class Someclass { // Someclass se ha inyectado y está gestionado por CDI y, por consiguiente, puede utilizar @Inject // Se llamará a setMetricRegistry antes de la primera llamada de método a Someclass @Inject public void setMetricRegistry(final MetricRegistry metrics) { } }
@Path("/myPath") public class MyService { // CDI no gestiona el ciclo de vida de Someclass Someclass someclass = new Someclass(); ... } public class Someclass { // CDI no llamará nunca este método porque Someclass no se ha creado con CDI @Inject public void setMetricRegistry(MetricRegistry metrics) { } }