Se encuentra viendo la documentación de la versión en desarrollo, puede estar incompleta.
Esta página fue traducida automáticamente. Si detectas un error, selecciónalo y presiona Ctrl+Enter para informarlo a los editores.

8 Notas sobre la selección de procesos en las métricas proc.mem y proc.num

Procesos que modifican su línea de comandos

Algunos programas utilizan la modificación de su línea de comandos como un método para mostrar su actividad actual. Un usuario puede ver la actividad ejecutando los comandos ps y top. Ejemplos de tales programas incluyen PostgreSQL, Sendmail, Zabbix.

Veamos un ejemplo en Linux. Supongamos que queremos monitorizar un número de procesos del agente de Zabbix.

El comando ps muestra los procesos de interés como

$ ps -fu zabbix
       UID        PID  PPID  C STIME TTY          TIME CMD
       ...
       zabbix    6318     1  0 12:01 ?        00:00:00 sbin/zabbix_agentd -c /home/zabbix/ZBXNEXT-1078/zabbix_agentd.conf
       zabbix    6319  6318  0 12:01 ?        00:00:01 sbin/zabbix_agentd: collector [idle 1 sec]                          
       zabbix    6320  6318  0 12:01 ?        00:00:00 sbin/zabbix_agentd: listener #1 [waiting for connection]            
       zabbix    6321  6318  0 12:01 ?        00:00:00 sbin/zabbix_agentd: listener #2 [waiting for connection]            
       zabbix    6322  6318  0 12:01 ?        00:00:00 sbin/zabbix_agentd: listener #3 [waiting for connection]            
       zabbix    6323  6318  0 12:01 ?        00:00:00 sbin/zabbix_agentd: active checks #1 [idle 1 sec]                   
       ...

Seleccionar procesos por nombre y usuario hace el trabajo:

$ zabbix_get -s localhost -k 'proc.num[zabbix_agentd,zabbix]'
       6

Ahora renombremos el ejecutable zabbix_agentd a zabbix_agentd_30 y reiniciémoslo.

ps ahora muestra

$ ps -fu zabbix
       UID        PID  PPID  C STIME TTY          TIME CMD
       ...
       zabbix    6715     1  0 12:53 ?        00:00:00 sbin/zabbix_agentd_30 -c /home/zabbix/ZBXNEXT-1078/zabbix_agentd.conf
       zabbix    6716  6715  0 12:53 ?        00:00:00 sbin/zabbix_agentd_30: collector [idle 1 sec]                          
       zabbix    6717  6715  0 12:53 ?        00:00:00 sbin/zabbix_agentd_30: listener #1 [waiting for connection]            
       zabbix    6718  6715  0 12:53 ?        00:00:00 sbin/zabbix_agentd_30: listener #2 [waiting for connection]            
       zabbix    6719  6715  0 12:53 ?        00:00:00 sbin/zabbix_agentd_30: listener #3 [waiting for connection]            
       zabbix    6720  6715  0 12:53 ?        00:00:00 sbin/zabbix_agentd_30: active checks #1 [idle 1 sec]                   
       ...

Ahora, seleccionar procesos por nombre y usuario produce un resultado incorrecto:

$ zabbix_get -s localhost -k 'proc.num[zabbix_agentd_30,zabbix]'
       1

¿Por qué un simple cambio de nombre del ejecutable a uno más largo conduce a un resultado tan diferente?

El agente de Zabbix comienza comprobando el nombre del proceso. Se abre el archivo /proc/<pid>/status y se verifica la línea Name. En nuestro caso, las líneas Name son:

$ grep Name /proc/{6715,6716,6717,6718,6719,6720}/status
       /proc/6715/status:Name:   zabbix_agentd_3
       /proc/6716/status:Name:   zabbix_agentd_3
       /proc/6717/status:Name:   zabbix_agentd_3
       /proc/6718/status:Name:   zabbix_agentd_3
       /proc/6719/status:Name:   zabbix_agentd_3
       /proc/6720/status:Name:   zabbix_agentd_3

El nombre del proceso en el archivo status se trunca a 15 caracteres.

Un resultado similar se puede ver con el comando ps:

$ ps -u zabbix
         PID TTY          TIME CMD
       ...
        6715 ?        00:00:00 zabbix_agentd_3
        6716 ?        00:00:01 zabbix_agentd_3
        6717 ?        00:00:00 zabbix_agentd_3
        6718 ?        00:00:00 zabbix_agentd_3
        6719 ?        00:00:00 zabbix_agentd_3
        6720 ?        00:00:00 zabbix_agentd_3
        ...

Obviamente, eso no es igual al valor del parámetro name de nuestro proc.num[] zabbix_agentd_30. Al no poder coincidir el nombre del proceso del archivo status, el agente de Zabbix recurre al archivo /proc/<pid>/cmdline.

Cómo ve el agente el archivo "cmdline" se puede ilustrar ejecutando un comando

$ for i in 6715 6716 6717 6718 6719 6720; do cat /proc/$i/cmdline | awk '{gsub(/\x0/,"<NUL>"); print};'; done
       sbin/zabbix_agentd_30<NUL>-c<NUL>/home/zabbix/ZBXNEXT-1078/zabbix_agentd.conf<NUL>
       sbin/zabbix_agentd_30: collector [idle 1 sec]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>...
       sbin/zabbix_agentd_30: listener #1 [waiting for connection]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>...
       sbin/zabbix_agentd_30: listener #2 [waiting for connection]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>...
       sbin/zabbix_agentd_30: listener #3 [waiting for connection]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>...
       sbin/zabbix_agentd_30: active checks #1 [idle 1 sec]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>...

Los archivos /proc/<pid>/cmdline en nuestro caso contienen bytes nulos invisibles y no imprimibles, utilizados para terminar cadenas en el lenguaje C. Los bytes nulos se muestran como "<NUL>" en este ejemplo.

El agente de Zabbix comprueba "cmdline" para el proceso principal y toma un zabbix_agentd_30, que coincide con el valor de nuestro parámetro name zabbix_agentd_30. Por lo tanto, el proceso principal es contado por la métrica proc.num[zabbix_agentd_30,zabbix].

Al comprobar el siguiente proceso, el agente toma zabbix_agentd_30: collector [idle 1 sec] del archivo cmdline y no coincide con nuestro parámetro name zabbix_agentd_30. Por lo tanto, solo el proceso principal que no modifica su línea de comandos es contado. Otros procesos del agente modifican su línea de comandos y son ignorados.

Este ejemplo muestra que el parámetro name no puede usarse en proc.mem[] y proc.num[] para seleccionar procesos en este caso.

Para la métrica proc.get[], cuando el agente de Zabbix comprueba "cmdline" para el nombre del proceso, solo usará parte del nombre comenzando desde la última barra y hasta el primer espacio o signo de dos puntos. El nombre del proceso recibido del archivo cmdline solo se usará si su inicio coincide completamente con el nombre de proceso acortado en el archivo status. El algoritmo es el mismo tanto para el nombre del proceso en el filtro como en la salida JSON.

Usar el parámetro cmdline con una expresión regular adecuada produce un resultado correcto:

$ zabbix_get -s localhost -k 'proc.num[,zabbix,,zabbix_agentd_30[ :]]'
       6

Tenga cuidado al usar las métricas proc.get[], proc.mem[] y proc.num[] para monitorizar programas que modifican sus líneas de comandos.

Antes de poner los parámetros name y cmdline en las métricas proc.get[], proc.mem[] y proc.num[], puede que desee probar los parámetros usando la métrica proc.num[] y el comando ps.

Hilos del kernel de Linux

Los hilos no se pueden seleccionar con el parámetro cmdline en las métricas proc.get[], proc.mem[] y proc.num[]

Tomemos como ejemplo uno de los hilos del kernel:

$ ps -ef| grep kthreadd
       root         2     0  0 09:33 ?        00:00:00 [kthreadd]

Se puede seleccionar con el parámetro name del proceso:

$ zabbix_get -s localhost -k 'proc.num[kthreadd,root]'
       1

Pero la selección por el parámetro cmdline del proceso no funciona:

$ zabbix_get -s localhost -k 'proc.num[,root,,kthreadd]'
       0

La razón es que el agente Zabbix toma la expresión regular especificada en el parámetro cmdline y la aplica al contenido del archivo /proc/<pid>/cmdline del proceso. Para los hilos del kernel, sus archivos /proc/<pid>/cmdline están vacíos. Por lo tanto, el parámetro cmdline nunca coincide.

Conteo de hilos en las métricas proc.mem[] y proc.num[]

Los hilos del kernel de Linux son contados por la métrica proc.num[] pero no informan memoria en la métrica proc.mem[]. Por ejemplo:

$ ps -ef | grep kthreadd
       root         2     0  0 09:51 ?        00:00:00 [kthreadd]
       
       $ zabbix_get -s localhost -k 'proc.num[kthreadd]'
       1
       
       $ zabbix_get -s localhost -k 'proc.mem[kthreadd]'
       ZBX_NOTSUPPORTED: Cannot get amount of "VmSize" memory.

Pero, ¿qué sucede si hay un proceso de usuario con el mismo nombre que un hilo del kernel? Entonces podría verse así:

$ ps -ef | grep kthreadd
       root         2     0  0 09:51 ?        00:00:00 [kthreadd]
       zabbix    9611  6133  0 17:58 pts/1    00:00:00 ./kthreadd
       
       $ zabbix_get -s localhost -k 'proc.num[kthreadd]'
       2
       
       $ zabbix_get -s localhost -k 'proc.mem[kthreadd]'
       4157440

proc.num[] contó tanto el hilo del kernel como el proceso de usuario. proc.mem[] informa la memoria solo para el proceso de usuario y cuenta la memoria del hilo del kernel como si fuera 0. Esto es diferente del caso anterior cuando se informó ZBX_NOTSUPPORTED.

Tenga cuidado al usar las métricas proc.mem[] y proc.num[] si el nombre del programa coincide con el de algún hilo.

Antes de poner parámetros en las métricas proc.mem[] y proc.num[], puede probar los parámetros usando la métrica proc.num[] y el comando ps.