[comment]: # translation:outdated

[comment]: # ({75dc9168-75dc9168})
# 10 Notas sobre la selección de procesos en las métricas proc.mem y proc.num

[comment]: # ({/75dc9168-75dc9168})

[comment]: # ({93778d6f-93778d6f})
#### Procesos modificando su línea de comando

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

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

El comando `ps` muestra procesos de interés como

    $ ps -fu zabbix
    UID PID PPID C TIEMPO TTY TIEMPO 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 los procesos por nombre y usuario hace el trabajo:

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

Ahora cambiemos el nombre del ejecutable `zabbix_agentd` a `zabbix_agentd_30` y
reiniciémoslo.

`ps` ahora muestra

    $ ps -fu zabbix
    UID PID PPID C TIEMPO TTY TIEMPO 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 los 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 un nombre más largo conduce a un
resultado bastante diferente?

El agente Zabbix comienza verificando el nombre del proceso. `/proc/<pid>/estado`
Se abre el archivo y se comprueba la línea "Name". En nuestro caso las 
líneas de `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.

Se puede ver un resultado similar con el comando `ps`:

    $ ps -u zabbix
      PID TTY TIEMPO 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 de nuestro   parámetro `name`
`zabbix_agentd_30` de `proc.num[]`. Al no haber podido coincidir con el nombre del proceso del
archivo `status` que el agente Zabbix convierte en el archivo `/proc/<pid>/cmdline`.

La forma en que el agente ve el archivo "cmdline" se puede ilustrar ejecutando el
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 lenguaje *C*. Los bytes nulos
se muestran como "<NUL>" en este ejemplo.

El agente de Zabbix comprueba "cmdline" para el proceso principal y toma
`zabbix_agentd_30`, que coincide con el valor de nuestro parámetro `name`
`zabbix_agentd_30`. Entonces, el proceso principal se cuenta para 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 cumple con nuestro parámetro `name` `zabbix_agentd_30`. Entonces, sólo el
proceso principal que no modifica su línea de comando se cuenta. Los otros
procesos del agente modifican su línea de comando y son ignorados.

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

El uso del 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 utilizar las métricas `proc.mem[]` y `proc.num[]` para monitorear
programas que modifican sus líneas de comando.

Antes de poner los parámetros `name` y `cmdline` en las métricas `proc.mem[]` y
`proc.num[]`, es posible que desee verificar los parámetros utilizando
la métrica `proc.num[]` y el comando `ps`.

[comment]: # ({/93778d6f-93778d6f})

[comment]: # ({0ff11097-0ff11097})
#### Hilos del kernel de Linux

[comment]: # ({/0ff11097-0ff11097})

[comment]: # ({3588d8df-3588d8df})
##### Los subprocesos no se pueden seleccionar con el parámetro `cmdline` en las métricas `proc.mem[]` y `proc.num[]`

Tomemos como ejemplo uno de los subprocesos 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
    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 lo aplica al contenido del proceso
`/proc/<pid>/cmdline`. Para los subprocesos del kernel, sus archivos `/proc/<pid>/cmdline`
están vacíos. Entonces, el parámetro `cmdline` nunca coincide.

[comment]: # ({/3588d8df-3588d8df})

[comment]: # ({8d1ef0a6-8d1ef0a6})
##### Recuento de subprocesos en las métricas `proc.mem[]` y `proc.num[]`

Los subprocesos del kernel de Linux se cuentan por la métrica `proc.num[]` pero no se informa
la 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: No se puede obtener la cantidad de memoria "VmSize".

Pero, ¿qué sucede si hay un proceso de usuario con el mismo nombre que un
hilo del núcleo? 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 núcleo como el proceso del usuario.
`proc.mem[]` informa memoria solo para el proceso del usuario y cuenta la
memoria del hilo del kernel como si fuera 0. Esto es diferente del caso de
arriba cuando se informó ZBX\_NOTSUPPORTED.

Tenga cuidado al utilizar las métricas `proc.mem[]` y `proc.num[]` si 
el nombre del programa coincide con uno de los hilos.

Antes de poner parámetros en las métricas `proc.mem[]` y `proc.num[]`,
es posible que desee verificar los parámetros utilizando la métrica `proc.num[]` y el comando `ps`.

[comment]: # ({/8d1ef0a6-8d1ef0a6})
