Metric#
El módulo Conteo de solicitudes de API: Si se realiza una solicitud a La métrica 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 Parámetros: liberar memoria para las nuevas; preservando las entradas existentes. 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); (por ejemplo, Ejemplo de uso: En el árbol de API, la plantilla de zona de memoria compartida se ve de la siguiente manera: Número; el recuento de métricas descartadas en la zona de memoria compartida Objeto; sus miembros son métricas con claves definidas y valores calculados 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. 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. Ejemplo de uso: En el árbol de API, tal métrica compleja se ve de la siguiente manera: Número; el recuento de métricas descartadas en la zona de memoria compartida Objeto; sus miembros son métricas complejas con claves establecidas. Son objetos que contienen un conjunto de submétricas con valores calculados Por defecto — http, server, location Calcula el valor de la métrica para la zona de memoria compartida nombre especificada. Parámetros: La longitud máxima es de 255 bytes. Si la clave es más larga, se truncará
a 255 bytes y se agregará con puntos suspensivos Si se omite, el valor predeterminado es Si es Si es Si es Nota En el caso de redirección interna, las métricas en la etapa Ejemplo de uso: Nota Las métricas con una clave vacía o un par Esto es útil, por ejemplo, para el modo Nota Recuerde que las variables se evalúan en diferentes fases. Por ejemplo,
es imposible usar Lista de modos de operación de métricas disponibles: El contador aumenta su valor en Valor por defecto — Nota Cualquier actualización de métrica (con cualquier valor) aumenta monótonamente el contador en 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,
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: Se crean variables para cada métrica: Para métricas complejas, se añade una variable adicional: Similar a la directiva metric, la variable setter El valor utilizado para establecer la variable debe seguir la estructura Ejemplo de uso: Cálculo de métricas utilizando el módulo
njs: Archivo Después de varias peticiones a Nota Después de establecer la variable, puede recuperar su valor; será igual
al par Además, el valor almacenado en la variable Las variables Nota Para métricas complejas, los valores de las submétricas en la variable Ejemplo de uso: Con esta configuración, una petición a Para Nota Si se asigna una cadena vacía a El cálculo se produce solo después de que tanto En este caso, el valor almacenado en El valor en El valor en Para métricas complejas, el valor de una submétrica específica puede recuperarse
utilizando la variable Ejemplo de uso: Con esta configuración, una petición a Respuesta: Respuesta: Respuesta: Angie incluye un módulo integrado para mostrar
métricas en
formato Prometheus,
que admite métricas personalizadas. Como ejemplo de integración, considere la siguiente configuración: Después de varias solicitudes a Los valores de la métrica serán: En formato Prometheus,
la métrica está disponible en ngx_http_metric_module 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.Ejemplo de Configuración#
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;
}
}
}
/api/ con esta configuración:$ curl 127.0.0.1/api/ --user-agent "Firefox"
api_requests se actualiza en tiempo real:{
"http": {
"metric_zones": {
"api_requests": {
"discarded": 0,
"metrics": {
"Firefox": 1
}
}
}
}
}
Directivas#
metric_zone#
metric_zone nombre:tamaño [expire=on| off] [discard_key=nombre] modo [parámetros];/status/http/metric_zones/.expire=<on|off> — comportamiento cuando la zona está llena:on, las métricas más antiguas (por tiempo de actualización) se descartan paraoff (por defecto) — las nuevas métricas entrantes se descartan,discard_key=<nombre> — define una métrica con la clave nombrefactor para average exp).metric_zone request_time:1m max;
{
"discarded": 0,
"metrics": {
"key1": 123,
"key2": 10.5,
}
}
discardedmetricsmetric_complex_zone#
metric_complex_zone nombre:tamaño [expire=on| off] [discard_key=nombre] { ... }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;
}
{
"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
}
}
}
discardedmetricsmetric#
metric nombre clave=valor [on=request| response| end];...;0. Si el parámetro no puede
convertirse a un número, el valor predeterminado es 1;on — un parámetro opcional que especifica cuándo se calcula la métrica:on=request, el cálculo ocurre cuando se recibe la solicitud;on=response, el cálculo ocurre durante la preparación de la respuesta;on=end (por defecto), el cálculo ocurre después de que se envía la respuesta.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.metric requests $http_user_agent=$request_time;
clave=valor inválido se ignoran.
Un valor omitido se trata como 0:metric foo $bar; # Equivalente a $bar=0
count, que ignora
los valores numéricos y simplemente reacciona al hecho de que se actualizó una métrica.$bytes_sent (bytes enviados al cliente)
con on=request (cuando se recibe la solicitud).Modos de Operación#
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ámetro factor);average mean — promedio sobre una ventana (parámetros window y count);histogram — distribución en "cubos" (una lista de valores umbral).count#
1 con cada actualización de métrica.0.1.metric_zone count:1m count;
# Como parte de una métrica compleja:
#
# metric_complex_zone count:1m {
# some_metric_name count;
# }
server {
listen 80;
location /metric/ {
metric count KEY;
}
location ~ ^/metric/set/(.+)$ {
metric count KEY=$1;
}
location /api/ {
api /status/http/metric_zones/count/metrics/;
}
}
$ 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;
# }
server {
listen 80;
location /metric/ {
metric gauge KEY;
}
location ~ ^/metric/set/(.+)$ {
metric gauge KEY=$1;
}
location /api/ {
api /status/http/metric_zones/gauge/metrics/;
}
}
$ 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;
# }
server {
listen 80;
location /metric/ {
metric last KEY;
}
location ~ ^/metric/set/(.+)$ {
metric last KEY=$1;
}
location /api/ {
api /status/http/metric_zones/last/metrics/;
}
}
$ 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;
# }
server {
listen 80;
location /metric/ {
metric min KEY;
}
location ~ ^/metric/set/(.+)$ {
metric min KEY=$1;
}
location /api/ {
api /status/http/metric_zones/min/metrics/;
}
}
$ 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;
# }
server {
listen 80;
location /metric/ {
metric max KEY;
}
location ~ ^/metric/set/(.+)$ {
metric max KEY=$1;
}
location /api/ {
api /status/http/metric_zones/max/metrics/;
}
}
$ 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;
# }
server {
listen 80;
location ~ ^/metric/set/(.+)$ {
metric avg_exp KEY=$1;
}
location /api/ {
api /status/http/metric_zones/avg_exp/metrics/;
}
}
$ 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;
# }
server {
listen 80;
location ~ ^/metric/set/(.+)$ {
metric avg_mean KEY=$1;
}
location /api/ {
api /status/http/metric_zones/avg_mean/metrics/;
}
}
$ 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;
# }
server {
listen 80;
location ~ ^/metric/set/(.+)$ {
metric histogram KEY=$1;
}
location /api/ {
api /status/http/metric_zones/hist/metrics/;
}
}
$ 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#
$metric_<nombre>$metric_<nombre>_key$metric_<nombre>_value$metric_<nombre>_value_<métrica>$metric_<nombre>#$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.clave=valor.
Tanto la clave como el valor pueden consistir en texto, variables y combinaciones de ambos.
La clave es una cadena arbitraria para agrupar valores. El valor es un número
procesado por el modo seleccionado. Si se omite, el valor predeterminado es 0.
Si el parámetro no puede convertirse en un número, el valor predeterminado es 1.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/;
}
}
}
http {
js_import metrics.js;
resolver 127.0.0.53;
metric_complex_zone requests:1m {
min_time min;
max_time max;
total count;
}
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 /static/http/metric_zones/requests/;
}
}
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}`;
}
export default {js_request};
location /metric/, los valores podrían verse así:{
"discarded": 0,
"metrics": {
"google": {
"min_time": 70,
"max_time": 432,
"total": 6
}
}
}
clave=valor especificado.$metric_<nombre>_key
cambiará a la clave especificada.$metric_<nombre>_key y $metric_<nombre>_value#$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.$metric_<nombre>_value
se unen utilizando un separador ", ".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 "Actualizado con '$metric_gauge'\nValor='$metric_gauge_value'\n";
}
location /complex/ {
set $metric_complex_key "foo";
set $metric_complex_value 3;
# O: set $metric_complex foo=3;
return 200 "Actualizado con '$metric_complex'\nValor='$metric_complex_value'\n";
}
}
}
/gauge/ produce:$ curl 127.0.0.1/gauge/
Actualizado con 'foo=1'
Valor='1'
/complex/:$ curl 127.0.0.1/complex/
Actualizado con 'foo=3'
Valor='0 0 1, 3'
$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.$metric_<nombre>_key como
$metric_<nombre>_value hayan sido establecidos.$metric_<nombre> se vuelve igual
al nuevo par clave=valor.$metric_<nombre>_key representa la última clave especificada
mediante variables.$metric_<nombre>_value representa el último valor calculado
para la clave establecida en $metric_<nombre>_key.$metric_<nombre>_value_<métrica>#$metric_<nombre>_value_<métrica>, donde
<métrica> es el nombre de la submétrica.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 "Actualizado con '$metric_foo'\nValores='$metric_foo_value'\nContador='$metric_foo_value_count'\n";
}
}
}
/foo/ produce:$ curl 127.0.0.1/foo/
Actualizado con 'bar=9'
Valores='1, 9, 9'
Contador='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/;
}
}
{
"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/;
}
}
{
"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;
}
}
{
"site1": 42,
"site2": 17
}
Soporte de Prometheus#
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;
}
}
}
/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
{
"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