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 | Sí | 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 | Sí | 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.