Metric#
Added in version 1.12.0.
El módulo ngx_stream_metric_module permite crear métricas
calculadas arbitrarias en tiempo real para tráfico stream (TCP y UDP).
Estos valores de métrica se almacenan en memoria compartida y se muestran
en tiempo real dentro de la rama de la API /status/stream/metric_zones/.
Se admiten varios tipos de agregación de datos (contadores, histogramas,
medias móviles, etc.) con agrupación por claves arbitrarias.
Para conocer el esquema de la respuesta, consulte la
referencia de la API de la zona de métricas stream. Contando conexiones por dirección de cliente: Si se establece una conexión al puerto La métrica Calcula el valor de la métrica para la zona de memoria compartida name especificada. Parámetros: La longitud máxima es de 255 bytes; las claves más largas se truncan. En la
salida de la API, Angie añade seleccionado. Si se omite, el valor predeterminado es Si Si Si Ejemplo de uso: Nota Se ignoran las métricas con una clave vacía o con un par Esto resulta útil, por ejemplo, para el modo Nota Recuerde que las variables se evalúan en distintas fases. Por ejemplo,
es imposible usar Predeterminado — stream 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 de modo opcionales.
El tamaño de la zona debe ser de al menos ocho páginas de memoria del
sistema. Ejemplo de uso: En el árbol de la API, una plantilla de este tipo de métrica compleja
se ve de la siguiente manera: Predeterminado — stream Crea una zona de memoria compartida del size especificado con el name
dado para almacenar métricas. El nombre de la zona sirve como nodo en la
rama Parámetros: última actualización) se descartan para liberar memoria para las
nuevas; descartan, conservando las entradas existentes. donde se acumulan los valores de las métricas descartadas. De forma
predeterminada, no se crea dicha métrica. La clave reservada no puede
actualizarse manualmente. (por ejemplo, Ejemplo de uso: En el árbol de la API, la plantilla de la zona de memoria compartida se
ve de la siguiente manera: Nota En una zona de 1 MB, con un tamaño de clave de 39 bytes y un único modo
de métrica, pueden almacenarse aproximadamente 8000 entradas de clave
únicas. Lista de los modos de funcionamiento de métricas disponibles: Los ejemplos siguientes usan el endpoint Cada actualización de la métrica incrementa el contador en Valor predeterminado — Ejemplos: Actualizando la métrica: Valor esperado de la métrica en la API: El medidor incrementa o disminuye su valor según el signo del número
proporcionado. Un valor positivo incrementa el contador, mientras que un
valor negativo lo disminuye. Un valor de Valor predeterminado — Ejemplos: Actualizando 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 ningún tipo de agregación. Si se
omite value, se usa Ejemplos: Actualizando 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 actualmente almacenado y el
nuevo. Ejemplos: Actualizando la métrica: Valor esperado de la métrica en la API: Guarda el máximo de dos valores — el valor actualmente almacenado y el
nuevo. Ejemplos: Actualizando la métrica: Valor esperado de la métrica en la API: Calcula el valor medio usando 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: Actualizando la métrica: Valor esperado de la métrica en la API: Calcula la media aritmética. Acepta los parámetros opcionales
Nota Por ejemplo, Ejemplos: Actualizando 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 supera el umbral del bucket. Los parámetros se
proporcionan como una lista de umbrales numéricos. Es útil para analizar
distribuciones, como la duración de las sesiones. Los parámetros obligatorios son numbers — los valores umbral de los
buckets, normalmente listados en orden ascendente. Nota El valor de bucket Ejemplos: Actualizando 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: Se crean variables para cada métrica: Para las métricas complejas, se añade una variable adicional: De forma similar a la directiva metric, el establecedor
de la variable El establecedor acepta una clave con un sufijo Ejemplo de uso: Tras tres conexiones al puerto Nota Al leer Además, el valor almacenado en la variable Las variables Nota Para las métricas complejas, los valores de las submétricas en la
variable Ejemplo de uso: Con esta configuración, una conexión al puerto Una conexión al puerto Nota Si se asigna una cadena vacía a El cálculo se produce solo después de que se hayan asignado tanto
En este caso, el valor almacenado en El valor en El valor en Para las métricas complejas, el valor de una submétrica específica puede
obtenerse mediante la variable Ejemplo de uso: Con esta configuración, una conexión al puerto Respuesta: Respuesta: Respuesta: Angie incluye un módulo integrado para mostrar
métricas en
formato de Prometheus,
que admite métricas personalizadas, incluidas las recopiladas en el lado
stream. Dado que la exposición de Prometheus es una funcionalidad exclusiva
de HTTP, las directivas
prometheus_template y prometheus
se configuran en un bloque Como ejemplo de integración, considere la siguiente configuración: Tras cinco conexiones al puerto Los valores de la métrica serán: En
formato de Prometheus,
la métrica está disponible en Ejemplo de configuración#
stream {
metric_zone connections:1m count;
server {
listen 12345;
metric connections $remote_addr on=connect;
}
}
http {
server {
listen 80;
location /status/ {
allow 127.0.0.1;
deny all;
api /status/;
}
}
}
12345:$ nc 127.0.0.1 12345 </dev/null
connections se actualiza en tiempo real:{
"stream": {
"metric_zones": {
"connections": {
"discarded": 0,
"metrics": {
"127.0.0.1": 1
}
}
}
}
}
Directivas#
metric#
... a toda clave de 255 bytes,
incluida aquella cuya longitud original era exactamente de 255 bytes. Una
clave puede contener a su vez caracteres = — solo el texto
posterior al último = se trata como el valor, de modo que todo
lo anterior (incluido cualquier = incrustado) pasa a formar
parte de la clave;0. Si el
parámetro no puede convertirse en un número, el valor predeterminado es
1;on — un parámetro opcional que especifica en qué punto del
procesamiento de la sesión se calcula la métrica:on=connect, el cálculo se realiza durante la fase
Pre-access, antes de leer cualquier dato del cliente;on=preread, el cálculo se realiza una vez por sesión, cuando
se envían al cliente los primeros datos procedentes del lado upstream
— recibidos del servidor al que se hizo proxy con
proxy_pass, o generados por
return —; en ese punto, módulos como
proxy_protocol, ssl_preread y
mqtt_preread ya han procesado los datos iniciales del cliente;on=end (predeterminado), el cálculo se realiza durante la
fase Log, cuando finaliza la sesión.metric sessions $remote_addr=$session_time on=end;
key=value
no válido. Un value omitido se trata como 0:metric foo $bar; # Equivalent to $bar=0
count, que ignora
los valores numéricos y simplemente reacciona al hecho de que una
métrica se actualizó.$upstream_bytes_sent (bytes enviados al
upstream) con on=connect (antes de que la conexión se haya
proxificado a algún destino).metric_complex_zone#
metric_complex_zone name:size [expire=on| off] [discard_key=name] { ... }metric_complex_zone sessions:1m expire=on discard_key="old" {
# submetric name mode parameters
min_time min;
avg_time average exp factor=60;
max_time max;
total count;
}
{
"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#
metric_zone name:size [expire=on| off] [discard_key=name] mode [parameters];/status/stream/metric_zones/.
El tamaño de la zona debe ser de al menos ocho páginas de memoria del
sistema.expire=<on|off> — comportamiento cuando la zona está llena:on, las métricas más antiguas (según el momento de laoff (predeterminado) — las métricas entrantes nuevas sediscard_key=<name> — define una métrica con la clave namefactor para average exp).metric_zone session_time:1m max;
{
"discarded": 0,
"metrics": {
"key1": 123,
"key2": 10.5
}
}
Modos de funcionamiento#
count — contador;gauge — medidor (incremento/decremento);last — el último valor recibido;min — valor mínimo;max — valor máximo;average exp — media móvil exponencial (EMA) (parámetro factor);average mean — media sobre una ventana (parámetros window y count);histogram — distribución en "buckets" (una lista de valores umbral)./status/ del
ejemplo de configuración. Cada resultado
está disponible bajo /status/stream/metric_zones/<zone>/metrics/.count#
1,
independientemente del valor proporcionado.0.metric_zone count:1m count;
# As part of a complex metric:
#
# metric_complex_zone count:1m {
# some_metric_name count;
# }
server {
listen 12345;
metric count KEY;
}
$ nc 127.0.0.1 12345 </dev/null
$ nc 127.0.0.1 12345 </dev/null
$ nc 127.0.0.1 12345 </dev/null
$ nc 127.0.0.1 12345 </dev/null
{
"KEY": 4
}
gauge#
0 no modifica el contador.0.metric_zone gauge:1m gauge;
# As part of a complex metric:
#
# metric_complex_zone gauge:1m {
# some_metric_name gauge;
# }
server {
listen 12351;
metric gauge KEY;
}
server {
listen 12352;
metric gauge KEY=5;
}
server {
listen 12353;
metric gauge KEY=-5;
}
server {
listen 12354;
metric gauge KEY=8;
}
$ nc 127.0.0.1 12351 </dev/null
{
"KEY": 0
}
$ nc 127.0.0.1 12352 </dev/null
$ nc 127.0.0.1 12353 </dev/null
$ nc 127.0.0.1 12354 </dev/null
{
"KEY": 8
}
last#
0.metric_zone last:1m last;
# As part of a complex metric:
#
# metric_complex_zone last:1m {
# some_metric_name last;
# }
server {
listen 12361;
metric last KEY;
}
server {
listen 12362;
metric last KEY=8000;
}
server {
listen 12363;
metric last KEY=37;
}
server {
listen 12364;
metric last KEY=-3.5;
}
$ nc 127.0.0.1 12361 </dev/null
{
"KEY": 0
}
$ nc 127.0.0.1 12362 </dev/null
$ nc 127.0.0.1 12363 </dev/null
$ nc 127.0.0.1 12364 </dev/null
{
"KEY": -3.5
}
min#
metric_zone min:1m min;
# As part of a complex metric:
#
# metric_complex_zone min:1m {
# some_metric_name min;
# }
server {
listen 12371;
metric min KEY=42.999;
}
server {
listen 12372;
metric min KEY=-512;
}
server {
listen 12373;
metric min KEY=1;
}
$ nc 127.0.0.1 12371 </dev/null
$ nc 127.0.0.1 12372 </dev/null
$ nc 127.0.0.1 12373 </dev/null
{
"KEY": -512
}
max#
metric_zone max:1m max;
# As part of a complex metric:
#
# metric_complex_zone max:1m {
# some_metric_name max;
# }
server {
listen 12381;
metric max KEY=42.999;
}
server {
listen 12382;
metric max KEY=-512;
}
server {
listen 12383;
metric max KEY=1;
}
$ nc 127.0.0.1 12381 </dev/null
$ nc 127.0.0.1 12382 </dev/null
$ nc 127.0.0.1 12383 </dev/null
{
"KEY": 42.999
}
average exp#
factor=<number> — un coeficiente que
determina cuánto influye el nuevo valor en la media. Se permiten valores
enteros de 0 a 99. El valor predeterminado es 90.90, el resultado será 90% del nuevo valor y
10% de la media anterior.metric_zone avg_exp:1m average exp factor=60;
# As part of a complex metric:
#
# metric_complex_zone avg_exp:1m {
# some_metric_name average exp factor=60;
# }
server {
listen 12391;
metric avg_exp KEY=100;
}
server {
listen 12392;
metric avg_exp KEY=200;
}
server {
listen 12393;
metric avg_exp KEY=0;
}
server {
listen 12394;
metric avg_exp KEY=8;
}
server {
listen 12395;
metric avg_exp KEY=30;
}
$ nc 127.0.0.1 12391 </dev/null
$ nc 127.0.0.1 12392 </dev/null
$ nc 127.0.0.1 12393 </dev/null
$ nc 127.0.0.1 12394 </dev/null
$ nc 127.0.0.1 12395 </dev/null
{
"KEY": 30.16
}
average mean#
window=<off|time> y count=<number>, que definen,
respectivamente, el intervalo de tiempo y el tamaño de la muestra para el
promediado. Valores predeterminados: window=off (se usa toda la
muestra) y count=10.window=5s solo tendrá en cuenta eventos de los
últimos 5 segundos. El parámetro window no puede ser 0.
El parámetro count=number controla el tamaño de la muestra
(valores en caché) para un cálculo de la media más suave.metric_zone avg_mean:1m average mean window=5s count=8;
# As part of a complex metric:
#
# metric_complex_zone avg_mean:1m {
# some_metric_name average mean window=5s count=8;
# }
server {
listen 12401;
metric avg_mean KEY=0.1;
}
server {
listen 12402;
metric avg_mean KEY=0.4;
}
server {
listen 12403;
metric avg_mean KEY=10;
}
server {
listen 12404;
metric avg_mean KEY=1;
}
$ nc 127.0.0.1 12401 </dev/null
$ nc 127.0.0.1 12401 </dev/null
$ nc 127.0.0.1 12402 </dev/null
$ nc 127.0.0.1 12403 </dev/null
$ nc 127.0.0.1 12404 </dev/null
$ nc 127.0.0.1 12404 </dev/null
{
"KEY": 2.1
}
{
"KEY": 0
}
histogram#
inf o +Inf puede usarse para capturar
todos los valores que superen el bucket más alto especificado.metric_zone hist:1m histogram 0.1 0.2 0.5 1 2 inf;
# As part of a complex metric:
#
# metric_complex_zone hist:1m {
# some_metric_name histogram 0.1 0.2 0.5 1 2 inf;
# }
server {
listen 12411;
metric hist KEY=0.25;
}
server {
listen 12412;
metric hist KEY=2;
}
server {
listen 12413;
metric hist KEY=1000;
}
$ nc 127.0.0.1 12411 </dev/null
{
"KEY": {
"0.1": 0,
"0.2": 0,
"0.5": 1,
"1": 1,
"2": 1,
"inf": 1
}
}
$ nc 127.0.0.1 12412 </dev/null
{
"KEY": {
"0.1": 0,
"0.2": 0,
"0.5": 1,
"1": 1,
"2": 2,
"inf": 2
}
}
$ nc 127.0.0.1 12413 </dev/null
{
"KEY": {
"0.1": 0,
"0.2": 0,
"0.5": 1,
"1": 1,
"2": 2,
"inf": 3
}
}
Variables integradas#
$metric_<name>$metric_<name>_key$metric_<name>_value$metric_<name>_value_<metric>$metric_<name>#$metric_<name> puede usarse para actualizar una
métrica. El cálculo se produce cuando se asigna la variable — por ejemplo,
mediante la directiva set, que se evalúa durante la
fase Pre-access (la misma etapa que
on=connect), o de forma programática desde el módulo
njs, por ejemplo en un controlador
js_access.=value opcional. El
último = separa la clave del valor; sin el sufijo, el valor es
0. La clave y el valor pueden contener texto, variables, o
combinaciones de ambos. Estas son las mismas reglas de análisis que para
metric.stream {
metric_zone hits:1m count;
# At this point, the $metric_hits variable is added
server {
listen 12345;
metric hits client=1 on=connect;
}
server {
listen 12346;
set $metric_hits client=1;
return "$metric_hits\n";
}
}
12345 y una conexión al puerto
12346:$ nc 127.0.0.1 12345 </dev/null
$ nc 127.0.0.1 12345 </dev/null
$ nc 127.0.0.1 12345 </dev/null
$ nc 127.0.0.1 12346 </dev/null
client=4
$metric_<name> se obtiene la clave junto con el valor
calculado actual de la métrica, en forma key=value — no la
cadena literal que se asignó. En el ejemplo anterior, la conexión asigna
el valor literal client=1, pero como el modo count
ignora el valor asignado y simplemente incrementa en cada actualización,
leer $metric_hits posteriormente devuelve client=4 — el
nuevo total del contador, que ya incluye las tres actualizaciones
anteriores desde el puerto 12345.$metric_<name>_key
cambia a la clave especificada.$metric_<name>_key and $metric_<name>_value#$metric_<name>_key y $metric_<name>_value
definen la clave y el valor respectivamente. La actualización de la
métrica se produce cuando se asigna $metric_<name>_value, siempre
que la clave en $metric_<name>_key ya se haya definido.$metric_<name>_value se unen usando un separador
", ".stream {
metric_zone level:1m gauge;
# The variables $metric_level, $metric_level_key, and $metric_level_value are added here.
metric_complex_zone stats:1m {
count count;
min min;
avg average exp;
}
# $metric_stats, $metric_stats_key, and $metric_stats_value are added here.
server {
listen 12345;
metric level sensor=10 on=connect;
}
server {
listen 12346;
set $metric_level_key "sensor";
set $metric_level_value 5;
# Or: set $metric_level sensor=5;
return "Updated with '$metric_level'\nValue='$metric_level_value'\n";
}
server {
listen 12347;
set $metric_stats_key bar;
set $metric_stats_value 9;
# Or: set $metric_stats bar=9;
return "Updated with '$metric_stats'\nValues='$metric_stats_value'\n";
}
}
12345 (que fija el
valor inicial del medidor en 10) seguida de una conexión al puerto
12346 produce:$ nc 127.0.0.1 12345 </dev/null
$ nc 127.0.0.1 12346 </dev/null
Updated with 'sensor=15'
Value='15'
12347 produce:$ nc 127.0.0.1 12347 </dev/null
Updated with 'bar=1, 9, 9'
Values='1, 9, 9'
$metric_<name>_value, el valor
se reconoce como 0. Si la cadena consta de caracteres que no
pueden convertirse en un número, se reconoce como 1.$metric_<name>_key como $metric_<name>_value.$metric_<name> pasa a ser
igual al nuevo par calculado key=value, no a los valores
literales recién asignados.$metric_<name>_key representa la última clave
especificada mediante variables.$metric_<name>_value representa el último valor
calculado para la clave establecida en $metric_<name>_key.$metric_<name>_value_<metric>#$metric_<name>_value_<metric>,
donde <metric> es el nombre de la submétrica.stream {
metric_complex_zone foo:1m {
count count;
min min;
avg average exp;
}
# Adds $metric_foo, $metric_foo_key, $metric_foo_value,
# and $metric_foo_value_count, $metric_foo_value_min, $metric_foo_value_avg.
server {
listen 12345;
set $metric_foo_key bar;
set $metric_foo_value 9;
# Or: set $metric_foo bar=9;
return "Updated with '$metric_foo'\nValues='$metric_foo_value'\nCount='$metric_foo_value_count'\n";
}
}
12345 produce:$ nc 127.0.0.1 12345 </dev/null
Updated with 'bar=1, 9, 9'
Values='1, 9, 9'
Count='1'
Ejemplos adicionales#
Supervisión de conexiones por protocolo#
metric_zone protocols:1m count;
server {
listen 12345;
listen 12346 udp;
metric protocols $protocol;
}
{
"TCP": 340,
"UDP": 58
}
Distribución del tiempo de sesión de upstream#
metric_zone upstream_time:10m expire=on histogram
0.05 0.1 0.3 0.5 1 2 5 10 inf;
server {
listen 12345;
proxy_pass backend;
metric upstream_time $upstream_addr=$upstream_session_time on=end;
}
{
"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#
stream {
metric_zone active_connections:2m gauge;
server {
listen 12345;
metric active_connections service_a=1 on=connect;
metric active_connections service_a=-1 on=end;
}
server {
listen 12346;
metric active_connections service_b=1 on=connect;
metric active_connections service_b=-1 on=end;
}
}
http {
server {
listen 8080;
location /connections/ {
allow 127.0.0.1;
deny all;
api /status/stream/metric_zones/active_connections/metrics/;
}
}
}
{
"service_a": 42,
"service_b": 17
}
Soporte de Prometheus#
http, haciendo referencia a la zona de
métricas stream a través del mismo árbol unificado de la API /status/.stream {
# Creating the "upload" metric
metric_complex_zone upload:1m discard_key="other" {
stats histogram 64 256 1024 4096 16384 +Inf;
sum gauge;
count count;
avg_size average exp;
}
upstream backend {
server 127.0.0.1:15001;
}
server {
listen 12345;
# Updating the metric at session end with the total
# number of bytes received from the client
proxy_pass backend;
metric upload angie=$bytes_received on=end;
}
}
http {
# Describing the Prometheus template for the "upload" metric
prometheus_template upload_metric {
'stats{le="$1"}' $p8s_value
path=~^/stream/metric_zones/upload/metrics/angie/stats/(.+)$
type=histogram;
'stats_sum' $p8s_value
path=/stream/metric_zones/upload/metrics/angie/sum;
'stats_count' $p8s_value
path=/stream/metric_zones/upload/metrics/angie/count;
'avg_size' $p8s_value
path=/stream/metric_zones/upload/metrics/angie/avg_size;
}
server {
listen 80;
# Target for metric scraping
location /prometheus/upload_metric/ {
prometheus upload_metric;
}
}
}
12345, enviando payloads de
16384, 64448, 64, 1028 y 1028
bytes:$ head -c 16384 /dev/urandom | nc 127.0.0.1 12345
$ head -c 64448 /dev/urandom | nc 127.0.0.1 12345
$ head -c 64 /dev/urandom | nc 127.0.0.1 12345
$ head -c 1028 /dev/urandom | nc 127.0.0.1 12345
$ head -c 1028 /dev/urandom | nc 127.0.0.1 12345
{
"stats": {
"64": 1,
"256": 1,
"1024": 1,
"4096": 3,
"16384": 4,
"+Inf": 5
},
"sum": 82952,
"count": 5,
"avg_size": 1077.9376
}
/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