Saltar a contenido

graphite: Un módulo de NGINX para recopilar estadísticas en Graphite

Instalación

Puedes instalar este módulo en cualquier distribución basada en RHEL, incluyendo, pero no limitado a:

  • RedHat Enterprise Linux 7, 8, 9 y 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 y Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-graphite
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-graphite

Habilita el módulo añadiendo lo siguiente en la parte superior de /etc/nginx/nginx.conf:

load_module modules/ngx_http_graphite_module.so;

Este documento describe nginx-module-graphite v4.3 lanzado el 20 de enero de 2023.


Un módulo de nginx para recopilar estadísticas de ubicación en Graphite.

Características

  • Agregación de métricas de ubicación, servidor o http
  • Cálculo de percentiles
  • Envío de datos a Graphite a través de UDP o TCP de manera no bloqueante
  • Envío de métricas personalizadas desde lua

Sinopsis

http {
    graphite_config prefix=playground server=127.0.0.1;
    server {
        location /foo/ {
            graphite_data nginx.foo;
        }
    }
}

Descripción

Este módulo utiliza un segmento de memoria compartida para recopilar estadísticas agregadas de todos los trabajadores y enviar los valores calculados del último minuto a Graphite cada 60s (por defecto) a través de UDP o TCP de manera no bloqueante. La agregación de estadísticas se realiza sobre la marcha en un búfer de tamaño fijo asignado al inicio del servidor y no afecta el rendimiento del servidor.

Este módulo se utiliza activamente en Mail.Ru Sites (uno de los mayores servicios web en Rusia) desde hace aproximadamente un año y se considera estable y bien probado.

Para recopilar métricas de los módulos centrales de nginx (ssl, gzip, upstream) se debe aplicar un pequeño parche en el árbol fuente de nginx. Consulta las instrucciones de instalación. Puedes compilar este módulo como uno dinámico, pero entonces no podrás recopilar métricas de los módulos centrales de nginx (ssl, gzip, upstream) y funciones lua.

Directivas

graphite_config

sintaxis: graphite_config key1=<value1> key2=<value2> ... keyN=<valueN>

contexto: http

Especifica configuraciones globales para toda la instancia del servidor.

Parámetro Requerido Predeterminado Descripción
prefix prefijo de ruta para todos los gráficos
host gethostname() nombre del host para todos los gráficos
server dirección IP del servidor carbon-cache
protocol udp protocolo del servidor carbon-cache (udp o tcp)
port 2003 puerto del servidor carbon-cache
frequency 60 cada cuánto enviar valores a Graphite (segundos)
intervals 1m intervalos de agregación, lista de intervalos de tiempo, separador de barra vertical (m - minutos)
params * limitar la lista de métricas a rastrear, separador de barra vertical
shared 2m tamaño de la memoria compartida, aumentar en caso de error memoria compartida demasiado pequeña
buffer 64k tamaño del búfer de red, aumentar en caso de error tamaño de búfer demasiado pequeño
package 1400 tamaño máximo del paquete UDP
template plantilla para el nombre del gráfico (el predeterminado es $prefix.$host.$split.$param_$interval)
error_log sufijo de ruta para gráficos de registros de errores (*)

(*): funciona solo cuando se aplica nginx_error_log_limiting*.patch al código fuente de nginx

Ejemplo (estándar):

http {
    graphite_config prefix=playground server=127.0.0.1;
}

Ejemplo (personalizado):

http {
    graphite_config prefix=playground server=127.0.0.1 intervals=1m|5m|15m params=rps|request_time|upstream_time template=$prefix.$host.$split.$param_$interval;
}

Ejemplo (error_log):

http {
    graphite_config prefix=playground server=127.0.0.1 error_log=log;
}

graphite_default_data

sintaxis: graphite_default_data <prefijo de ruta> [params=<params>] [if=<condición>]

contexto: http, server

Crea un punto de medición en todas las ubicaciones anidadas. Puedes usar las variables "$location" o "$server" que representan el nombre de la ubicación actual y el nombre del servidor actual con todos los caracteres no alfanuméricos reemplazados por "_". Los "_" iniciales y finales se eliminan.

Ejemplo:

   graphite_default_data nginx.$location;

   location /foo/ {
   }

   location /bar/ {
   }

Los datos para /foo/ se enviarán a nginx.foo, los datos para /bar/ - a nginx.bar. El parámetro <params> (1.3.0) especifica la lista de parámetros que se recopilarán para todas las ubicaciones anidadas. Para agregar todos los parámetros predeterminados, usa *. El parámetro <if> (1.1.0) habilita el registro condicional. Una solicitud no se registrará si la condición evalúa a "0" o una cadena vacía.

Ejemplo (con $server):

    graphite_default_data nginx.$server.$location

    server {
        server_name foo_host;

        location /foo/ {
        }
    }

    server {
        server_name bar_host;

        location /bar/ {
        }
    }

Los datos para /foo/ se enviarán a nginx.foo_host.foo, los datos para /bar/ - a nginx.bar_host.bar.

graphite_data

sintaxis: graphite_data <prefijo de ruta> [params=<params>] [if=<condición>]

contexto: http, server, location, if

Crea un punto de medición en una ubicación específica.

Ejemplo:

    location /foo/ {
        graphite_data nginx.foo;
    }

El parámetro <params> (1.3.0) especifica la lista de parámetros que se recopilarán para esta ubicación. Para agregar todos los parámetros predeterminados, usa *. El parámetro <if> (1.1.0) habilita el registro condicional. Una solicitud no se registrará si la condición evalúa a "0" o una cadena vacía.

Ejemplo:

    map $scheme $is_http { http 1; }
    map $scheme $is_https { https 1; }

    ...

    location /bar/ {
        graphite_data nginx.all.bar;
        graphite_data nginx.http.bar if=$is_http;
        graphite_data nginx.https.bar if=$is_https;
        graphite_data nginx.arg params=rps|request_time;
        graphite_data nginx.ext params=*|rps|request_time;
    }

graphite_param

sintaxis: graphite_param name=<path> interval=<valor de tiempo> aggregate=<función>

contexto: location

Parámetro Requerido Descripción
name prefijo de ruta para todos los gráficos
interval Sí* intervalo de agregación, formato de valor de intervalo de tiempo (m - minutos)
aggregate Sí* función de agregación sobre los valores
percentile Sí* nivel de percentil

funciones de agregación

func Descripción
sum suma de valores por intervalo
persec suma de valores por segundo (sum dividido por segundos en interval)
avg valor promedio en el intervalo
gauge valor de medidor

Ejemplo: ver abajo.

Nginx API para Lua

sintaxis: ngx.graphite.param(<nombre>)

Obtén un enlace a un nombre de parámetro de graphite, para usarlo en lugar del nombre para las funciones a continuación. El enlace es válido hasta que se recargue nginx. Después de obtener el enlace de un parámetro, aún puedes pasar el nombre del parámetro a las funciones a continuación. Puedes obtener el enlace de un parámetro múltiples veces, siempre obtendrás el mismo objeto por el mismo nombre (un lightuserdata). La función devuelve false si el parámetro especificado por el nombre no existe. La función devuelve nil en errores al obtener el enlace. Las funciones acceden a la información de los parámetros por enlace más rápido que por nombre.

Disponible después de aplicar el parche al módulo lua-nginx. La característica está presente en el parche para el módulo lua v0.10.12. Consulta las instrucciones de instalación.

sintaxis: ngx.graphite(<nombre_o_enlace>,<valor>[,<config>])

Escribe el valor de la estadística en la función agregadora. Se aceptan números de punto flotante en valor.

Disponible después de aplicar el parche al módulo lua-nginx. Consulta las instrucciones de instalación.

ngx.graphite(name, value, config)

Ejemplo:

location /foo/ {
    graphite_param name=lua.foo_sum aggregate=sum interval=1m;
    graphite_param name=lua.foo_rps aggregate=persec interval=1m;
    graphite_param name=lua.foo_avg aggregate=avg interval=1m;
    graphite_param name=lua.foo_gauge aggregate=gauge;

    content_by_lua '
        ngx.graphite("lua.foo_sum", 0.01)
        ngx.graphite("lua.foo_rps", 1)
        ngx.graphite("lua.foo_avg", ngx.var.request_uri:len())
        local foo_gauge_link = ngx.graphite.param("lua.foo_gauge")
        ngx.graphite(foo_gauge_link, 10)
        ngx.graphite(foo_gauge_link, -2)
        ngx.graphite("lua.auto_rps", 1, "aggregate=persec interval=1m percentile=50|90|99")
        ngx.say("hello")
    ';
}

Debes especificar el comando graphite_param o pasar el argumento config. Si eliges la segunda opción, los datos para este gráfico no se enviarán hasta la primera llamada a ngx.graphite.

Advertencia: Si no declaras el gráfico usando el comando graphite_param, entonces la memoria para el gráfico se asignará dinámicamente en la memoria compartida del módulo. Si la memoria compartida del módulo se agota mientras nginx está en ejecución, no se crearán nuevos gráficos y se registrará un mensaje de error.

sintaxis: ngx.graphite.get(<nombre_o_enlace>)

Obtén el valor del parámetro de medidor con el nombre_o_enlace especificado.

sintaxis: ngx.graphite.set(<nombre>,<valor>)

Establece el valor en el parámetro de medidor con el nombre_o_enlace especificado.

Parámetros

Parámetro Unidades Func Descripción
request_time ms avg tiempo total gastado en atender la solicitud
bytes_sent bytes avg longitud de la respuesta http
body_bytes_sent bytes avg longitud del cuerpo de la respuesta http
request_length bytes avg longitud de la solicitud http
ssl_handshake_time ms avg tiempo gastado en el apretón de manos ssl
ssl_cache_usage % last cuánto se utilizó la caché SSL
content_time ms avg tiempo gastado generando contenido dentro de nginx
gzip_time ms avg tiempo gastado comprimiendo contenido al vuelo
upstream_time ms avg tiempo gastado hablando con upstream
upstream_connect_time ms avg tiempo gastado en la conexión upstream (nginx >= 1.9.1)
upstream_header_time ms avg tiempo gastado en el encabezado upstream (nginx >= 1.9.1)
rps rps sum número total de solicitudes por segundo
keepalive_rps rps sum número de solicitudes enviadas a través de una conexión keepalive previamente abierta
response_2xx_rps rps sum número total de respuestas con código 2xx
response_3xx_rps rps sum número total de respuestas con código 3xx
response_4xx_rps rps sum número total de respuestas con código 4xx
response_5xx_rps rps sum número total de respuestas con código 5xx
response_[0-9]{3}_rps rps sum número total de respuestas con el código dado
upstream_cache_(miss|bypass|expired|stale|updating|revalidated|hit)_rps rps sum total de respuestas con un estado de caché upstream dado
lua_time ms avg tiempo gastado en código lua

Percentiles

Para calcular el valor del percentil para cualquier parámetro, establece el nivel de percentil a través de /. Por ejemplo, request_time/50|request_time/90|request_time/99.

parche para agregar API para enviar métricas desde código lua (opcional)

patch -p1 < /path/to/graphite-nginx-module/lua_module_v0_9_11.patch cd ..

wget 'http://nginx.org/download/nginx-1.9.2.tar.gz' tar -xzf nginx-1.9.2.tar.gz cd nginx-1.9.2/

GitHub

Puedes encontrar consejos de configuración adicionales y documentación para este módulo en el repositorio de GitHub para nginx-module-graphite.