<a id="http-metric"></a>

# Metric

El módulo `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.

<a id="configuration-example-30"></a>

## Ejemplo de Configuración

Conteo de solicitudes de API:

```nginx
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:

```console
$ curl 127.0.0.1/api/ --user-agent "Firefox"
```

La métrica `api_requests` se actualiza en tiempo real:

```json
{
    "http": {
       "metric_zones": {
           "api_requests": {
               "discarded": 0,
               "metrics": {
                   "Firefox": 1
               }
           }
       }
    }
}
```

<a id="directives-31"></a>

## Directivas

<a id="index-0"></a>

<a id="metric-zone"></a>

### metric_zone

| [Sintaxis](https://es.angie.software//angie/docs/configuration/configfile.md#configfile)   | `metric_zone` nombre:tamaño [`expire`=`on`| `off`] [`discard_key`=`nombre`] modo [parámetros];   |
|--------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|
| Por defecto                                                                                | —                                                                                                |
| [Contexto](https://es.angie.software//angie/docs/configuration/configfile.md#configfile)   | 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/`.

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](#metric-modes));
- parámetros — configuraciones adicionales para el modo seleccionado
  : (por ejemplo, `factor` para `average exp`).

Ejemplo de uso:

```nginx
metric_zone request_time:1m max;
```

En el árbol de API, la plantilla de zona de memoria compartida se ve de la siguiente manera:

```json
{
    "discarded": 0,
    "metrics": {
        "key1": 123,
        "key2": 10.5,
    }
}
```

| `discarded`   | Número; el recuento de métricas descartadas en la zona de memoria compartida   |
|---------------|--------------------------------------------------------------------------------|
| `metrics`     | Objeto; sus miembros son métricas con claves definidas y valores calculados    |

#### NOTE
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.

<a id="index-1"></a>

<a id="metric-complex-zone"></a>

### metric_complex_zone

| [Sintaxis](https://es.angie.software//angie/docs/configuration/configfile.md#configfile)   | `metric_complex_zone` nombre:tamaño [`expire`=`on`| `off`] [`discard_key`=`nombre`] { ... }   |
|--------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------|
| Por defecto                                                                                | —                                                                                             |
| [Contexto](https://es.angie.software//angie/docs/configuration/configfile.md#configfile)   | 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:

```nginx
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:

```json
{
    "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
        }
    }
}
```

| `discarded`   | Número; el recuento de métricas descartadas en la zona de memoria compartida                                                                     |
|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------|
| `metrics`     | Objeto; sus miembros son métricas complejas con claves establecidas. Son objetos que contienen un conjunto de submétricas con valores calculados |

<a id="index-2"></a>

<a id="id3"></a>

### metric

| [Sintaxis](https://es.angie.software//angie/docs/configuration/configfile.md#configfile)   | `metric` nombre clave=valor [`on`=`request`| `response`| `end`];   |
|--------------------------------------------------------------------------------------------|--------------------------------------------------------------------|
| Por defecto                                                                                | —                                                                  |
| [Contexto](https://es.angie.software//angie/docs/configuration/configfile.md#configfile)   | 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. Si la clave es más larga, se truncará
    a 255 bytes y se agregará con puntos suspensivos `...`;
- 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 es `1`;
- `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.

#### NOTE
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`.

Ejemplo de uso:

```nginx
metric requests $http_user_agent=$request_time;
```

#### NOTE
Las métricas con una clave vacía o un par `clave=valor` inválido se ignoran.
Un valor omitido se trata como `0`:

```nginx
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.

#### NOTE
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).

<a id="metric-modes"></a>

## 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ámetro `factor`);
* `average mean` — promedio sobre una ventana (parámetros `window` y `count`);
* `histogram` — distribución en "cubos" (una lista de valores umbral).

<a id="count"></a>

### count

El contador aumenta su valor en `1` con cada actualización de métrica.

Valor por defecto — `0`.

#### NOTE
Cualquier actualización de métrica (con cualquier valor) aumenta monótonamente el contador en `1`.

Ejemplos:

```nginx
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/;
    }
}
```

Actualizando la métrica:

```console
$ 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
```

Valor esperado de la métrica en la API:

```json
{
    "KEY": 4
}
```

<a id="gauge"></a>

### gauge

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 `0` no cambia el contador.

Valor predeterminado — `0`.

Ejemplos:

```nginx
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/;
    }
}
```

Actualización de la métrica:

```console
$ curl 127.0.0.1/metric/
```

Valor esperado de la métrica en la API:

```json
{
    "KEY": 0
}
```

Actualizaciones adicionales:

```console
$ curl 127.0.0.1/metric/set/5
$ curl 127.0.0.1/metric/set/-5
$ curl 127.0.0.1/metric/set/8
```

Valor esperado de la métrica en la API:

```json
{
    "KEY": 8
}
```

<a id="last"></a>

### last

Almacena el último valor recibido sin ninguna agregación. Si se omite value,
se utiliza `0`.

Ejemplos:

```nginx
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/;
    }
}
```

Actualización de la métrica:

```console
$ curl 127.0.0.1/metric/
```

Valor esperado de la métrica en la API:

```json
{
    "KEY": 0
}
```

Actualizaciones adicionales:

```console
$ 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
```

Valor esperado de la métrica en la API:

```json
{
   "KEY": -3.5
}
```

<a id="min"></a>

### min

Guarda el mínimo de dos valores — el valor almacenado actualmente y el nuevo.

Ejemplos:

```nginx
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/;
    }
}
```

Actualización de la métrica:

```console
$ 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/
```

Valor esperado de la métrica en la API:

```json
{
    "KEY": -512
}
```

<a id="max"></a>

### max

Guarda el máximo de dos valores — el valor almacenado actualmente y el nuevo.

Ejemplos:

```nginx
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/;
    }
}
```

Actualización de la métrica:

```console
$ 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/
```

Valor esperado de la métrica en la API:

```json
{
    "KEY": 42.999
}
```

<a id="average-exp"></a>

### average exp

Calcula el valor promedio utilizando el algoritmo de
[suavizado exponencial](https://en.wikipedia.org/wiki/Exponential_smoothing).

Acepta un parámetro opcional `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`.

Cuanto mayor sea el coeficiente, más peso tendrán los nuevos valores. Si especifica
`90`, el resultado será `90%` del nuevo valor y `10%`
del promedio anterior.

Ejemplos:

```nginx
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/;
    }
}
```

Actualización de la métrica:

```console
$ 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
```

Valor esperado de la métrica en la API:

```json
{
    "KEY": 30.16
}
```

<a id="average-mean"></a>

### average mean

Calcula la media aritmética. Acepta parámetros opcionales
`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`.

#### NOTE
Por ejemplo, `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.

Ejemplos:

```nginx
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/;
    }
}
```

Actualización de la métrica:

```console
$ 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
```

Valor esperado de la métrica en la API:

```json
{
    "KEY": 2.1
}
```

Si espera 5 segundos desde la última actualización, el valor esperado será:

```json
{
    "KEY": 0
}
```

<a id="histogram"></a>

### histogram

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.

#### NOTE
El valor de bucket `inf` o `+Inf` puede utilizarse para capturar todos
los valores que excedan el bucket más alto especificado.

Ejemplos:

```nginx
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/;
    }
}
```

Actualización de la métrica:

```console
$ curl 127.0.0.1/metric/set/0.25
```

Valor esperado de la métrica en la API:

```json
{
    "KEY": {
        "0.1": 0,
        "0.2": 0,
        "0.5": 1,
        "1": 1,
        "2": 1,
        "inf": 1
    }
}
```

Actualizaciones adicionales:

```console
$ curl 127.0.0.1/metric/set/2
```

Valor esperado de la métrica en la API:

```json
{
    "KEY": {
        "0.1": 0,
        "0.2": 0,
        "0.5": 1,
        "1": 1,
        "2": 2,
        "inf": 2
    }
}
```

Actualización adicional:

```console
$ curl 127.0.0.1/metric/set/1000
```

Valor esperado de la métrica en la API:

```json
{
    "KEY": {
       "0.1": 0,
       "0.2": 0,
       "0.5": 1,
       "1": 1,
       "2": 2,
       "inf": 3
    }
}
```

<a id="built-in-variables-5"></a>

## 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>`

<a id="v-metric-zone"></a>

### `$metric_<nombre>`

Similar a la directiva [metric](#id3), la variable setter `$metric_<nombre>`
puede utilizarse para actualizar una métrica. El cálculo se produce durante la
fase [Rewrite](https://angie.software/angie/docs/configuration/modules/http/http_rewrite/),
permitiendo el procesamiento de métricas desde el módulo [njs](https://angie.software/angie/docs/configuration/modules/http/http_js/), por ejemplo.

El valor utilizado para establecer la variable debe seguir la estructura `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`.

Ejemplo de uso:

```nginx
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/;
        }
    }
}
```

Cálculo de métricas utilizando el módulo
[njs](https://angie.software/angie/docs/configuration/modules/http/http_js/):

```nginx
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/;
    }
}
```

Archivo `metrics.js`:

```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};
```

Después de varias peticiones a `location /metric/`, los valores podrían verse así:

```json
{
    "discarded": 0,
    "metrics": {
        "google": {
            "min_time": 70,
            "max_time": 432,
            "total": 6
        }
    }
}
```

#### NOTE
Después de establecer la variable, puede recuperar su valor; será igual
al par `clave=valor` especificado.

Además, el valor almacenado en la variable `$metric_<nombre>_key`
cambiará a la clave especificada.

<a id="v-metric-zone-key"></a>

<a id="v-metric-zone-value"></a>

### `$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.

#### NOTE
Para métricas complejas, los valores de las submétricas en la variable `$metric_<nombre>_value`
se unen utilizando un separador `", "`.

Ejemplo de uso:

```nginx
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";
        }
    }
}
```

Con esta configuración, una petición a `/gauge/` produce:

```console
$ curl 127.0.0.1/gauge/
Actualizado con 'foo=1'
Valor='1'
```

Para `/complex/`:

```console
$ curl 127.0.0.1/complex/
Actualizado con 'foo=3'
Valor='0 0 1, 3'
```

#### NOTE
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>` se vuelve igual
al nuevo par `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`.

<a id="v-metric-zone-value-metric"></a>

### `$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:

```nginx
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";
        }
    }
}
```

Con esta configuración, una petición a `/foo/` produce:

```console
$ curl 127.0.0.1/foo/
Actualizado con 'bar=9'
Valores='1, 9, 9'
Contador='1'
```

<a id="additional-examples"></a>

## Ejemplos Adicionales

<a id="monitoring-http-methods"></a>

### Monitorización de Métodos HTTP

```nginx
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:

```json
{
    "GET": 65,
    "POST": 20,
    "PUT": 10,
    "DELETE": 5
}
```

<a id="upstream-response-time-distribution"></a>

### Distribución del Tiempo de Respuesta del Upstream

```nginx
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:

```json
{
    "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
        }
    }
}
```

<a id="active-connections"></a>

### Conexiones Activas

```nginx
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:

```json
{
    "site1": 42,
    "site2": 17
}
```

<a id="prometheus-support"></a>

## Soporte de Prometheus

Angie incluye un [módulo integrado](https://es.angie.software//angie/docs/configuration/modules/http/http_prometheus.md#http-prometheus) para mostrar
métricas en
[formato Prometheus](https://prometheus.io/docs/instrumenting/exposition_formats/),
que admite métricas personalizadas.

Como ejemplo de integración, considere la siguiente configuración:

```nginx
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/...`:

```console
$ 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:

```json
{
    "stats": {
        "64": 1,
        "256": 1,
        "1024": 1,
        "4096": 3,
        "16384": 4,
        "+Inf": 5
    },

    "sum": 82952,
    "count": 5,
    "avg_size": 1077.9376
}
```

En [formato Prometheus](https://prometheus.io/docs/instrumenting/exposition_formats/),
la métrica está disponible en `/prometheus/upload_metric/`:

```text
# 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
```
