[comment]: # translation:outdated

[comment]: # ({75dc9168-75dc9168})
# 9 Observações sobre seleção de processos nos itens proc.mem e proc.num

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

[comment]: # ({93778d6f-93778d6f})
#### Processos modificando sua linha de comando

Alguns programas usam a modificação de sua linha de comando como um método para exibir
sua atividade atual. Um usuário pode ver a atividade executando `ps` e
comandos `top`. Exemplos de tais programas incluem *PostgreSQL*,
*Sendmail*, *Zabbix*.

Vamos ver um exemplo do Linux. Vamos supor que queremos monitorar um
número de processos do agente Zabbix.

O comando `ps` mostra os processos de interesse 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: coletor [inativo 1 segundo]
    zabbix 6320 6318 0 12:01 ? 00:00:00 sbin/zabbix_agentd: listener #1 [aguardando conexão]
    zabbix 6321 6318 0 12:01 ? 00:00:00 sbin/zabbix_agentd: listener #2 [aguardando conexão]
    zabbix 6322 6318 0 12:01 ? 00:00:00 sbin/zabbix_agentd: listener #3 [aguardando conexão]
    zabbix 6323 6318 0 12:01 ? 00:00:00 sbin/zabbix_agentd: verificações ativas #1 [ocioso 1 segundo]
    ...

Selecionar processos por nome e usuário faz o trabalho:

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

Agora vamos renomear o executável `zabbix_agentd` para `zabbix_agentd_30` e
reinicie-o.

`ps` agora mostra

    $ 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: coletor [inativo 1 segundo]
    zabbix 6717 6715 0 12:53 ? 00:00:00 sbin/zabbix_agentd_30: ouvinte #1 [aguardando conexão]
    zabbix 6718 6715 0 12:53 ? 00:00:00 sbin/zabbix_agentd_30: ouvinte #2 [aguardando conexão]
    zabbix 6719 6715 0 12:53 ? 00:00:00 sbin/zabbix_agentd_30: ouvinte #3 [aguardando conexão]
    zabbix 6720 6715 0 12:53 ? 00:00:00 sbin/zabbix_agentd_30: verificações ativas #1 [ocioso 1 segundo]
    ...

Agora, selecionar processos por nome e usuário produz um resultado incorreto:

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

Por que uma simples renomeação de executável para um nome mais longo leva a
resultado diferente?

O agente Zabbix começa verificando o nome do processo. `/proc/<pid>/status`
arquivo é aberto e a linha `Name` é marcada. No nosso caso, o `Nome`
linhas são:

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

O nome do processo no arquivo `status` é truncado para 15 caracteres.

Um resultado semelhante pode ser visto com o 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, isso não é igual ao valor do nosso parâmetro `proc.num[]` `name`
`zabbix_agentd_30`. Não ter correspondido ao nome do processo de
arquivo `status` o agente Zabbix transforma em arquivo `/proc/<pid>/cmdline`.

Como o agente vê o arquivo "cmdline" pode ser ilustrado executando um
comando

    $ para i em 6715 6716 6717 6718 6719 6720; do gato /proc/$i/cmdline | awk '{gsub(/\x0/,"<NUL>"); imprimir};'; feito
    sbin/zabbix_agentd_30<NUL>-c<NUL>/home/zabbix/ZBXNEXT-1078/zabbix_agentd.conf<NUL>
    sbin/zabbix_agentd_30: coletor [inativo 1 seg]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>. ..
    sbin/zabbix_agentd_30: ouvinte #1 [aguardando conexão]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>...
    sbin/zabbix_agentd_30: ouvinte #2 [aguardando conexão]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>...
    sbin/zabbix_agentd_30: ouvinte #3 [aguardando conexão]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>...
    sbin/zabbix_agentd_30: verificações ativas #1 [ocioso 1 seg]<NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL><NUL>. ..

Os arquivos `/proc/<pid>/cmdline` em nosso caso contêm arquivos invisíveis, não imprimíveis
bytes nulos, usados para encerrar strings na linguagem *C*. Os bytes nulos
são mostrados como "<NUL>" neste exemplo.

O agente Zabbix verifica "cmdline" para o processo principal e leva um
`zabbix_agentd_30`, que corresponde ao nosso valor de parâmetro `name`
`zabbix_agentd_30`. Assim, o processo principal é contado por item
`proc.num[zabbix_agentd_30,zabbix]`.

Ao verificar o próximo processo, o agente leva
`zabbix_agentd_30: collector [idle 1 sec]` do arquivo `cmdline` e
ele não atende ao nosso parâmetro `name` `zabbix_agentd_30`. Então, apenas o
processo principal que não modifica sua linha de comando, é contado. De outros
os processos do agente modificam sua linha de comando e são ignorados.

Este exemplo mostra que o parâmetro `name` não pode ser usado em
`proc.mem[]` e `proc.num[]` para selecionar processos neste caso.

Usar o parâmetro `cmdline` com uma expressão regular adequada produz um
resultado correto:

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

Tenha cuidado ao usar os itens `proc.mem[]` e `proc.num[]` para monitoramento
programas que modificam suas linhas de comando.

Antes de colocar os parâmetros `name` e `cmdline` em `proc.mem[]` e
itens `proc.num[]`, você pode querer testar os parâmetros usando
item `proc.num[]` e comando `ps`.

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

[comment]: # ({0ff11097-0ff11097})
#### Threads do kernel Linux

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

[comment]: # ({3588d8df-3588d8df})
##### Threads não podem ser selecionadas com o parâmetro `cmdline` nos itens `proc.mem[]` e `proc.num[]`

Vamos ver um exemplo das threads do kernel:

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

Ela pode ser selecionada através do parâmetro `name`:

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

Mas selecionado pelo parâmetro `cmdline` não irá funcionar:

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

A razão disso é que o agente utiliza a expressão regular definida no
parametro `cmdline` e aplica seu conteúdo ao conteúdo do processo
`/proc/<pid>/cmdline`. Mas para as threads do kernel os arquivos
`/proc/<pid>/cmdline` estarão vazios. Logo, o parâmetro `cmdline` nunca
irá funcionar para elas.

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

[comment]: # ({8d1ef0a6-8d1ef0a6})
##### Contagem de threads em itens `proc.mem[]` e `proc.num[]`

threads do kernel Linux são contados pelo item `proc.num[]`, mas não relatam
memória no item `proc.mem[]`. Por exemplo:

    $ ps -ef | grep kthreadd
    raiz 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: Não é possível obter a quantidade de memória "VmSize".

Mas o que acontece se houver um processo de usuário com o mesmo nome de um
thread do núcleo? Então poderia ficar assim:

    $ ps -ef | grep kthreadd
    raiz 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[]` contou tanto a thread do kernel quanto o processo do usuário.
`proc.mem[]` reporta a memória apenas para o processo do usuário e conta o
memória de thread do kernel como se fosse 0. Isso é diferente do caso
acima quando ZBX\_NOTSUPPORTED foi relatado.

Tenha cuidado ao usar os itens `proc.mem[]` e `proc.num[]` se o programa
name acontece para corresponder a um dos threads.

Antes de colocar parâmetros nos itens `proc.mem[]` e `proc.num[]`, você
pode querer testar os parâmetros usando o item `proc.num[]` e `ps`
comando.

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