Metric#
Added in version 1.11.0.
Permite crear métricas arbitrarias calculadas
en tiempo real. Estos valores de métricas se almacenan en memoria compartida y se muestran
en tiempo real dentro de la rama de API /status/http/metric_zones/.
Se admiten varios tipos de agregación de datos (contadores, histogramas, promedios móviles, etc.)
con agrupación por claves arbitrarias.
Para el esquema de la respuesta, consulte la referencia de la API de zonas de métricas HTTP.
Cuando se compila desde el código fuente, este módulo
se compila por defecto; puede deshabilitarse con la opción de
compilación --without-http_metric_module.
En paquetes e imágenes de nuestros repositorios, el módulo está incluido en la compilación.
Nota
Al recargar la configuración, una zona creada por metric_zone o
metric_complex_zone conserva sus valores acumulados solo mientras
su disposición de almacenamiento no cambie. La zona comienza vacía si el
tamaño de la zona, el número de métricas o un modo difieren de la
configuración anterior, si cambia el count de average mean,
si el window de average mean se cambia a off o
desde off, o si cambia el número de cubos de histogram; el
motivo se registra entonces en el registro de errores con
nivel info. Otros parámetros, como el factor de
average exp, el intervalo window de average mean o
los límites de los cubos de histogram, pueden cambiarse sin perder
los valores acumulados.
Guías relacionadas
Métricas personalizadas: paso a paso: zona, actualización y API.
Ejemplo de configuración#
Conteo de solicitudes de API:
http {
metric_zone api_requests:1m count;
server {
listen 80;
location /api/ {
allow 127.0.0.1;
deny all;
api /status/;
metric api_requests $http_user_agent on=request;
}
}
}
Si se realiza una solicitud a /api/ con esta configuración:
$ curl 127.0.0.1/api/ --user-agent "Firefox"
La métrica api_requests se actualiza en tiempo real:
{
"http": {
"metric_zones": {
"api_requests": {
"discarded": 0,
"metrics": {
"Firefox": 1
}
}
}
}
}
Directivas#
metric#
| |
Por defecto | — |
http, server, location |
Calcula el valor de la métrica para la zona de memoria compartida nombre especificada.
Parámetros:
clave — una cadena arbitraria (a menudo una variable) utilizada para agrupar valores. La longitud máxima es de 255 bytes; las claves más largas se truncan. En la salida de la API, Angie añade
...a toda clave de 255 bytes, incluida una cuya longitud original era exactamente de 255 bytes. Si la propia clave contiene uno o más caracteres=, solo la subcadena posterior al último=se trata como valor; todo lo anterior pasa a formar parte de la clave;valor — un número (puede ser una variable) procesado por el modo seleccionado. Si se omite, el valor predeterminado es
0. Si el parámetro no puede convertirse a un número, el valor predeterminado es1;on— un parámetro opcional que especifica cuándo se calcula la métrica:Si es
on=request, el cálculo ocurre cuando se recibe la solicitud;Si es
on=response, el cálculo ocurre durante la preparación de la respuesta;Si es
on=end(por defecto), el cálculo ocurre después de que se envía la respuesta.
Nota
En el caso de redirección interna, las métricas en la etapa on=request
se calculan en el location original. Sin embargo,
las métricas on=response y on=end se calcularán
en el nuevo location.
Se pueden especificar varias directivas metric en el mismo nivel de
configuración. Estas directivas se heredan del nivel de configuración anterior
si y solo si no hay directivas metric definidas en el nivel actual.
Por lo tanto, un único metric en un bloque location cancela todas
las reglas heredadas de server o http, en las tres etapas on y no solo
en la suya.
Ejemplo de uso:
metric requests $http_user_agent=$request_time;
Nota
Las métricas con una clave vacía o un par clave=valor inválido se ignoran.
Un valor omitido se trata como 0:
metric foo $bar; # Equivalente a $bar=0
Esto es útil, por ejemplo, para el modo count, que ignora
los valores numéricos y simplemente reacciona al hecho de que se actualizó una métrica.
Nota
Recuerde que las variables se evalúan en diferentes fases. Por ejemplo,
es imposible usar $bytes_sent (bytes enviados al cliente)
con on=request (cuando se recibe la solicitud).
metric_complex_zone#
| |
Por defecto | — |
http |
Define una métrica compleja — un conjunto de métricas con modos independientes. Cada línea en el cuerpo del bloque define un nombre de submétrica, un modo y parámetros opcionales del modo. El tamaño de la zona debe ser de al menos ocho páginas de memoria del sistema: 32K si el tamaño de página es de 4K.
Ejemplo de uso:
metric_complex_zone requests:1m expire=on discard_key="old" {
# nombre submétrica modo parámetros
min_time min;
avg_time average exp factor=60;
max_time max;
total count;
}
En el árbol de API, tal métrica compleja se ve de la siguiente manera:
{
"discarded": 3,
"metrics": {
"key1": {
"min_time": 20,
"avg_time": 50,
"max_time": 80,
"total": 2
},
"old": {
"min_time": 3,
"avg_time": 40,
"max_time": 152,
"total": 80
}
}
}
metric_zone#
| |
Por defecto | — |
http |
Crea una zona de memoria compartida del tamaño especificado con el nombre dado
para almacenar métricas. El nombre de la zona sirve como nodo en la
rama /status/http/metric_zones/.
El tamaño de la zona debe ser de al menos ocho páginas de memoria del
sistema: 32K si el tamaño de página es de 4K.
Parámetros:
expire=<on|off>— comportamiento cuando la zona está llena:Si es
on, las métricas más antiguas (por tiempo de actualización) se descartan para liberar memoria para las nuevas;Si es
off(por defecto) — las nuevas métricas entrantes se descartan, preservando las entradas existentes.
discard_key=<nombre>— define una métrica con la clave nombre donde se acumulan los valores de las métricas descartadas. Por defecto, no se crea tal métrica. La clave reservada no puede actualizarse manualmente.modo — algoritmo de procesamiento de datos (ver la sección Modos de Operación);
parámetros — configuraciones adicionales para el modo seleccionado (por ejemplo,
factorparaaverage exp).
Ejemplo de uso:
metric_zone request_time:1m max;
En el árbol de API, la plantilla de zona de memoria compartida se ve de la siguiente manera:
{
"discarded": 0,
"metrics": {
"key1": 123,
"key2": 10.5
}
}
Nota
En una zona de 1 MB, con un tamaño de clave de 39 bytes y un modo de métrica única, se pueden almacenar aproximadamente 8.000 entradas de claves únicas.
Modos de operación#
Lista de modos de operación de métricas disponibles:
count— contador;gauge— medidor (incremento/decremento);last— el último valor recibido;min— valor mínimo;max— valor máximo;average exp— promedio móvil exponencial (EMA) (parámetrofactor);average mean— promedio sobre una ventana (parámetroswindowycount);histogram— distribución en "cubos" (una lista de valores umbral).
Cada ejemplo siguiente amplía el
ejemplo de configuración: coloque su
directiva de zona en el bloque Cada actualización de métrica incrementa el contador en Valor por defecto — Ejemplos: Actualizando la métrica: Valor esperado de la métrica en la API: El gauge aumenta o disminuye su valor dependiendo del signo del
número pasado. Un valor positivo aumenta el contador, mientras que un valor
negativo lo disminuye. Un valor de Valor predeterminado — Ejemplos: Actualización de la métrica: Valor esperado de la métrica en la API: Actualizaciones adicionales: Valor esperado de la métrica en la API: Almacena el último valor recibido sin ninguna agregación. Si se omite value,
se utiliza Ejemplos: Actualización de la métrica: Valor esperado de la métrica en la API: Actualizaciones adicionales: Valor esperado de la métrica en la API: Guarda el mínimo de dos valores — el valor almacenado actualmente y el nuevo. Ejemplos: Actualización de la métrica: Valor esperado de la métrica en la API: Guarda el máximo de dos valores — el valor almacenado actualmente y el nuevo. Ejemplos: Actualización de la métrica: Valor esperado de la métrica en la API: Calcula el valor promedio utilizando el algoritmo de
suavizado exponencial. Acepta un parámetro opcional Cuanto mayor sea el coeficiente, más peso tendrán los nuevos valores. Si especifica
Ejemplos: Actualización de la métrica: Valor esperado de la métrica en la API: Calcula la media aritmética. Acepta parámetros opcionales
Nota Por ejemplo, Ejemplos: Actualización de la métrica: Valor esperado de la métrica en la API: Si espera 5 segundos desde la última actualización, el valor esperado será: Crea un conjunto de "buckets", incrementando el contador correspondiente si el nuevo
valor no excede el umbral del bucket. Los parámetros se proporcionan como
una lista de umbrales numéricos. Útil para analizar distribuciones,
como tiempos de respuesta. Los parámetros obligatorios son números — los valores de umbral de los buckets,
normalmente listados en orden ascendente. Nota El valor de bucket Ejemplos: Actualización de la métrica: Valor esperado de la métrica en la API: Actualizaciones adicionales: Valor esperado de la métrica en la API: Actualización adicional: Valor esperado de la métrica en la API:http y sus ubicaciones en el bloque
server, junto a la ubicación /api/. Cada resultado está
disponible en /api/http/metric_zones/<zone>/metrics/.count#
1, sea cual sea
el valor suministrado.0.metric_zone count:1m count;
# Como parte de una métrica compleja:
#
# metric_complex_zone count:1m {
# some_metric_name count;
# }
location /metric/ {
metric count KEY;
}
location ~ ^/metric/set/(.+)$ {
metric count KEY=$1;
}
$ curl 127.0.0.1/metric/
$ curl 127.0.0.1/metric/set/1
$ curl 127.0.0.1/metric/set/23
$ curl 127.0.0.1/metric/set/-32
{
"KEY": 4
}
gauge#
0 no cambia el contador.0.metric_zone gauge:1m gauge;
# Como parte de una métrica compleja:
#
# metric_complex_zone gauge:1m {
# some_metric_name gauge;
# }
location /metric/ {
metric gauge KEY;
}
location ~ ^/metric/set/(.+)$ {
metric gauge KEY=$1;
}
$ curl 127.0.0.1/metric/
{
"KEY": 0
}
$ curl 127.0.0.1/metric/set/5
$ curl 127.0.0.1/metric/set/-5
$ curl 127.0.0.1/metric/set/8
{
"KEY": 8
}
last#
0.metric_zone last:1m last;
# Como parte de una métrica compleja:
#
# metric_complex_zone last:1m {
# some_metric_name last;
# }
location /metric/ {
metric last KEY;
}
location ~ ^/metric/set/(.+)$ {
metric last KEY=$1;
}
$ curl 127.0.0.1/metric/
{
"KEY": 0
}
$ curl 127.0.0.1/metric/set/8000
$ curl 127.0.0.1/metric/set/37
$ curl 127.0.0.1/metric/set/-3.5
{
"KEY": -3.5
}
min#
metric_zone min:1m min;
# Como parte de una métrica compleja:
#
# metric_complex_zone min:1m {
# some_metric_name min;
# }
location /metric/ {
metric min KEY;
}
location ~ ^/metric/set/(.+)$ {
metric min KEY=$1;
}
$ curl 127.0.0.1/metric/set/42.999
$ curl 127.0.0.1/metric/set/-512
$ curl 127.0.0.1/metric/set/1
$ curl 127.0.0.1/metric/
{
"KEY": -512
}
max#
metric_zone max:1m max;
# Como parte de una métrica compleja:
#
# metric_complex_zone max:1m {
# some_metric_name max;
# }
location /metric/ {
metric max KEY;
}
location ~ ^/metric/set/(.+)$ {
metric max KEY=$1;
}
$ curl 127.0.0.1/metric/set/42.999
$ curl 127.0.0.1/metric/set/-512
$ curl 127.0.0.1/metric/set/1
$ curl 127.0.0.1/metric/
{
"KEY": 42.999
}
average exp#
factor=<número> — un coeficiente que determina
cuánto influye el nuevo valor en el promedio. Se permiten valores enteros de 0 a
99. El valor predeterminado es 90.90, el resultado será 90% del nuevo valor y 10%
del promedio anterior.metric_zone avg_exp:1m average exp factor=60;
# Como parte de una métrica compleja:
#
# metric_complex_zone avg_exp:1m {
# some_metric_name average exp factor=60;
# }
location ~ ^/metric/set/(.+)$ {
metric avg_exp KEY=$1;
}
$ curl 127.0.0.1/metric/set/100
$ curl 127.0.0.1/metric/set/200
$ curl 127.0.0.1/metric/set/0
$ curl 127.0.0.1/metric/set/8
$ curl 127.0.0.1/metric/set/30
{
"KEY": 30.16
}
average mean#
window=<off|tiempo> y count=<número>, que definen el
intervalo de tiempo y el tamaño de la muestra para el promedio, respectivamente.
Valores predeterminados: window=off (se utiliza toda la muestra) y count=10.window=5s solo considerará eventos de los últimos 5 segundos.
El parámetro window no puede ser 0. El parámetro count=número
controla el tamaño de la muestra (valores en caché) para un cálculo de media más suave.metric_zone avg_mean:1m average mean window=5s count=8;
# Como parte de una métrica compleja:
#
# metric_complex_zone avg_mean:1m {
# some_metric_name average mean window=5s count=8;
# }
location ~ ^/metric/set/(.+)$ {
metric avg_mean KEY=$1;
}
$ curl 127.0.0.1/metric/set/0.1
$ curl 127.0.0.1/metric/set/0.1
$ curl 127.0.0.1/metric/set/0.4
$ curl 127.0.0.1/metric/set/10
$ curl 127.0.0.1/metric/set/1
$ curl 127.0.0.1/metric/set/1
{
"KEY": 2.1
}
{
"KEY": 0
}
histogram#
inf o +Inf puede utilizarse para capturar todos
los valores que excedan el bucket más alto especificado.metric_zone hist:1m histogram 0.1 0.2 0.5 1 2 inf;
# Como parte de una métrica compleja:
#
# metric_complex_zone hist:1m {
# some_metric_name histogram 0.1 0.2 0.5 1 2 inf;
# }
location ~ ^/metric/set/(.+)$ {
metric hist KEY=$1;
}
$ curl 127.0.0.1/metric/set/0.25
{
"KEY": {
"0.1": 0,
"0.2": 0,
"0.5": 1,
"1": 1,
"2": 1,
"inf": 1
}
}
$ curl 127.0.0.1/metric/set/2
{
"KEY": {
"0.1": 0,
"0.2": 0,
"0.5": 1,
"1": 1,
"2": 2,
"inf": 2
}
}
$ curl 127.0.0.1/metric/set/1000
{
"KEY": {
"0.1": 0,
"0.2": 0,
"0.5": 1,
"1": 1,
"2": 2,
"inf": 3
}
}
Variables integradas#
Se crean variables para cada métrica:
$metric_<nombre>$metric_<nombre>_key$metric_<nombre>_value
Para métricas complejas, se añade una variable adicional:
$metric_<nombre>_value_<métrica>
$metric_<nombre>#
Similar a la directiva metric, la variable setter $metric_<nombre>
puede utilizarse para actualizar una métrica. El cálculo se produce durante la
fase Rewrite,
permitiendo el procesamiento de métricas desde el módulo njs, por ejemplo.
El establecedor acepta una clave con un sufijo opcional =valor. Sin el
sufijo, el valor es 0. La clave y el valor pueden contener texto,
variables o combinaciones de ambos.
Ejemplo de uso:
http {
metric_zone counter:1m count;
# En este punto, se añade la variable $metric_counter
server {
listen 80;
location /metric/ {
set $metric_counter $http_user_agent; # Equivalente a $http_user_agent=0
}
location /api/ {
allow 127.0.0.1;
deny all;
api /status/http/metric_zones/counter/;
}
}
}
El siguiente ejemplo calcula métricas en el módulo NJS;
cargue antes el módulo. El manejador mide el
tiempo de dos solicitudes ngx.fetch a sitios externos, por lo que Angie
necesita acceso a Internet; sustituya la dirección de resolver y la ruta
de js_fetch_trusted_certificate por las de su servidor DNS y su paquete
de CA:
http {
js_import metrics.js;
resolver 127.0.0.53;
metric_complex_zone requests:1m {
min_time min;
max_time max;
total count;
}
server {
listen 80;
location /metric/ {
js_content metrics.js_request;
js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
}
location /api/ {
allow 127.0.0.1;
deny all;
api /status/http/metric_zones/requests/;
}
}
}
Archivo metrics.js:
async function js_request(r) {
let start_time = Date.now();
let results = await Promise.all([ngx.fetch('https://google.com/'),
ngx.fetch('https://google.ru/')]);
// Usando la variable setter $metric_requests
r.variables.metric_requests = `google=${Date.now() - start_time}`;
r.return(200);
}
export default {js_request};
Después de varias solicitudes a location /metric/, los valores podrían verse así:
{
"discarded": 0,
"metrics": {
"google": {
"min_time": 70,
"max_time": 432,
"total": 6
}
}
}
Nota
Tras establecer la variable, puede recuperar su valor; será igual a la
clave junto con el nuevo valor calculado de la métrica, en el formato
clave=valor, y no la cadena literal que se asignó.
Además, el valor almacenado en la variable $metric_<nombre>_key
cambiará a la clave especificada.
$metric_<nombre>_key y $metric_<nombre>_value#
Las variables $metric_<nombre>_key y $metric_<nombre>_value
definen la clave y el valor respectivamente. La actualización de la métrica se produce cuando
se establece $metric_<nombre>_value, siempre que la clave en
$metric_<nombre>_key ya haya sido definida.
Nota
Para métricas complejas, los valores de las submétricas en la variable $metric_<nombre>_value
se unen utilizando un separador ", ".
Ejemplo de uso:
http {
metric_zone gauge:1m gauge;
# Aquí se añaden las variables $metric_gauge, $metric_gauge_key y $metric_gauge_value.
metric_complex_zone complex:1m {
hist histogram 1 2 3;
avg average exp;
}
# Aquí se añaden $metric_complex, $metric_complex_key y $metric_complex_value.
server {
listen 80;
location /gauge/ {
set $metric_gauge_key "foo";
set $metric_gauge_value 1;
# O: set $metric_gauge foo=1;
return 200 "Updated with '$metric_gauge'\nValue='$metric_gauge_value'\n";
}
location /complex/ {
set $metric_complex_key "foo";
set $metric_complex_value 3;
# O: set $metric_complex foo=3;
return 200 "Updated with '$metric_complex'\nValue='$metric_complex_value'\n";
}
}
}
Con esta configuración, una solicitud a /gauge/ produce:
$ curl 127.0.0.1/gauge/
Updated with 'foo=1'
Value='1'
Para /complex/:
$ curl 127.0.0.1/complex/
Updated with 'foo=0 0 1, 3'
Value='0 0 1, 3'
Nota
Si se asigna una cadena vacía a $metric_<nombre>_value, el valor se
reconoce como 0. Si la cadena consiste en caracteres que no pueden
convertirse en un número, se reconoce como 1.
El cálculo se produce solo después de que tanto $metric_<nombre>_key como
$metric_<nombre>_value hayan sido establecidos.
En este caso, el valor almacenado en $metric_<nombre> pasa a ser igual
a la clave junto con el nuevo valor calculado de la métrica, en el formato
clave=valor.
El valor en $metric_<nombre>_key representa la última clave especificada
mediante variables.
El valor en $metric_<nombre>_value representa el último valor calculado
para la clave establecida en $metric_<nombre>_key.
$metric_<nombre>_value_<métrica>#
Para métricas complejas, el valor de una submétrica específica puede recuperarse
utilizando la variable $metric_<nombre>_value_<métrica>, donde
<métrica> es el nombre de la submétrica.
Ejemplo de uso:
http {
metric_complex_zone foo:1m {
count count;
min min;
avg average exp;
}
# Añade $metric_foo, $metric_foo_key, $metric_foo_value,
# y $metric_foo_value_count, $metric_foo_value_min, $metric_foo_value_avg.
server {
listen 80;
location /foo/ {
set $metric_foo_key bar;
set $metric_foo_value 9;
# O: set $metric_foo bar=9;
return 200 "Updated with '$metric_foo'\nValues='$metric_foo_value'\nCount='$metric_foo_value_count'\n";
}
}
}
Con esta configuración, una solicitud a /foo/ produce:
$ curl 127.0.0.1/foo/
Updated with 'bar=1, 9, 9'
Values='1, 9, 9'
Count='1'
Ejemplos adicionales#
Monitorización de métodos HTTP#
metric_zone http_methods:1m count;
server {
listen 80;
location / {
metric http_methods $request_method;
}
location /metrics/ {
allow 127.0.0.1;
deny all;
api /status/http/metric_zones/http_methods/metrics/;
}
}
Respuesta:
{
"GET": 65,
"POST": 20,
"PUT": 10,
"DELETE": 5
}
Distribución del tiempo de respuesta del upstream#
metric_zone upstream_time:10m expire=on histogram
0.05 0.1 0.3 0.5 1 2 5 10 inf;
server {
listen 80;
location /backend/ {
proxy_pass http://backend;
metric upstream_time $upstream_addr=$upstream_response_time on=end;
}
location /metrics/ {
allow 127.0.0.1;
deny all;
api /status/http/metric_zones/upstream_time/;
}
}
Respuesta:
{
"discarded": 0,
"metrics": {
"backend1:8080": {
"0.05": 12,
"0.1": 28,
"0.3": 56,
"0.5": 78,
"1": 92,
"2": 97,
"5": 99,
"10": 100,
"inf": 100
}
}
}
Conexiones activas#
metric_zone active_connections:2m gauge;
server {
listen 80;
server_name site1.com;
location / {
# Incrementamos al conectar
metric active_connections site1=1 on=request;
# Decrementamos al finalizar
metric active_connections site1=-1 on=end;
}
}
server {
listen 80;
server_name site2.com;
location / {
metric active_connections site2=1 on=request;
metric active_connections site2=-1 on=end;
}
}
server {
listen 8080;
location /connections/ {
allow 127.0.0.1;
deny all;
api /status/http/metric_zones/active_connections/metrics;
}
}
Respuesta:
{
"site1": 42,
"site2": 17
}
Soporte de Prometheus#
Angie incluye un módulo Prometheus integrado para mostrar métricas en formato Prometheus, que admite métricas personalizadas.
Como ejemplo de integración, considere la siguiente configuración:
http {
# Creando la métrica "upload"
metric_complex_zone upload:1m discard_key="other" {
stats histogram 64 256 1024 4096 16384 +Inf;
sum gauge;
count count;
avg_size average exp;
}
# Describiendo la plantilla Prometheus para la métrica "upload"
prometheus_template upload_metric {
'stats{le="$1"}' $p8s_value
path=~^/http/metric_zones/upload/metrics/angie/stats/(.+)$
type=histogram;
'stats_sum' $p8s_value
path=/http/metric_zones/upload/metrics/angie/sum;
'stats_count' $p8s_value
path=/http/metric_zones/upload/metrics/angie/count;
'avg_size' $p8s_value
path=/http/metric_zones/upload/metrics/angie/avg_size;
}
server {
listen 80;
# Actualizando la métrica
location ~ ^/upload/(.*)$ {
api /status/http/metric_zones/upload/metrics/angie/;
metric upload angie=$1 on=request;
}
# Destino para la recopilación de métricas
location /prometheus/upload_metric/ {
prometheus upload_metric;
}
}
}
Después de varias solicitudes a /upload/...:
$ curl 127.0.0.1/upload/16384
$ curl 127.0.0.1/upload/64448
$ curl 127.0.0.1/upload/64
$ curl 127.0.0.1/upload/1028
$ curl 127.0.0.1/upload/1028
Los valores de la métrica serán:
{
"stats": {
"64": 1,
"256": 1,
"1024": 1,
"4096": 3,
"16384": 4,
"+Inf": 5
},
"sum": 82952,
"count": 5,
"avg_size": 1077.9376
}
En formato Prometheus,
la métrica está disponible en /prometheus/upload_metric/:
# Angie Prometheus template "upload_metric"
# TYPE stats histogram
stats{le="64"} 1
stats{le="256"} 1
stats{le="1024"} 1
stats{le="4096"} 3
stats{le="16384"} 4
stats{le="+Inf"} 5
stats_sum 82952
stats_count 5
avg_size 1077.9376