Sommige programma's gebruiken het wijzigen van hun opdrachtregel als een methode om hun huidige activiteit weer te geven. Een gebruiker kan de activiteit zien door de commando's ps
en top
uit te voeren. Voorbeelden van dergelijke programma's zijn PostgreSQL, Sendmail en Zabbix.
Laten we een voorbeeld bekijken vanuit Linux. Laten we aannemen dat we een aantal Zabbix-agentprocessen willen monitoren.
Het ps
-commando toont de relevante processen als volgt:
$ 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]
...
Het selecteren van processen op naam en gebruiker werkt:
Laten we nu de uitvoerbare naam zabbix_agentd
hernoemen naar zabbix_agentd_30
en deze opnieuw starten.
ps
toont nu:
$ 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]
...
Nu levert het selecteren van processen op naam en gebruiker een onjuist resultaat op:
Waarom leidde een eenvoudige hernoeming van de uitvoerbare naam naar een langere naam tot een heel ander resultaat?
De Zabbix-agent begint met het controleren van de procesnaam. Het bestand /proc/<pid>/status
wordt geopend en de regel Name
wordt gecontroleerd. In ons geval zijn de Name
-regels:
$ 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
De procesnaam in het status
-bestand is afgekapt tot 15 tekens.
Een vergelijkbaar resultaat kan worden gezien met het ps
-commando:
$ 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
...
Duidelijk is dat dit niet gelijk is aan onze proc.num[]
name
-parameterwaarde zabbix_agentd_30
. Omdat de Zabbix-agent de procesnaam in het status
-bestand niet kon vinden, kijkt hij naar het bestand /proc/<pid>/cmdline
.
Hoe de agent het "cmdline"-bestand ziet, kan worden geïllustreerd door een commando uit te voeren:
$ 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>...
De /proc/<pid>/cmdline
-bestanden bevatten in ons geval onzichtbare, niet-afdrukbare nulbytes die worden gebruikt om strings in de C-taal te beëindigen. De nulbytes worden in dit voorbeeld weergegeven als "<NUL>".
De Zabbix-agent controleert "cmdline" voor het hoofdproces en neemt een zabbix_agentd_30
, die overeenkomt met onze name
-parameterwaarde zabbix_agentd_30
. Dus, het hoofdproces wordt geteld door het item proc.num[zabbix_agentd_30,zabbix]
.
Bij het controleren van het volgende proces neemt de agent zabbix_agentd_30: collector [idle 1 sec]
uit het cmdline
-bestand en dit komt niet overeen met onze name
-parameter zabbix_agentd_30
. Daarom wordt alleen het hoofdproces dat zijn opdrachtregel niet wijzigt, geteld. Andere agentprocessen wijzigen hun opdrachtregel en worden genegeerd.
Dit voorbeeld laat zien dat de name
-parameter niet kan worden gebruikt in proc.mem[]
en proc.num[]
om processen in dit geval te selecteren.
Voor het proc.get[]
-item zal de Zabbix-agent bij het controleren van "cmdline" voor de procesnaam alleen een deel van de naam gebruiken dat begint vanaf de laatste schuine streep en tot aan het eerste spatie- of kolontecken. De procesnaam die is ontvangen uit het cmdline-bestand wordt alleen gebruikt als het begin volledig overeenkomt met de verkorte procesnaam in het status
-bestand. Het algoritme is hetzelfde voor zowel de procesnaam in het filter als in de JSON-uitvoer.
Het gebruik van de cmdline
-parameter met een juiste reguliere expressie levert een correct resultaat op:
Wees voorzichtig bij het gebruik van proc.get[]
, proc.mem[]
en proc.num[]
-items voor het monitoren van programma's die hun opdrachtregels wijzigen.
Voordat je de name
- en cmdline
-parameters in proc.get[]
, proc.mem[]
en proc.num[]
-items plaatst, wil je wellicht de parameters testen met behulp van het proc.num[]
-item en het ps
-commando.
cmdline
-parameter in proc.get[]
, proc.mem[]
en proc.num[]
-itemsLaten we als voorbeeld een van de kernelthreads nemen:
Het kan worden geselecteerd met de proces name
-parameter:
Maar selectie op basis van de proces cmdline
-parameter werkt niet:
De reden hiervoor is dat de Zabbix-agent de reguliere expressie neemt die is opgegeven in de cmdline
-parameter en deze toepast op de inhoud van het proces /proc/<pid>/cmdline
. Voor kernelthreads zijn hun /proc/<pid>/cmdline
-bestanden leeg. Dus, de cmdline
-parameter komt nooit overeen.
proc.mem[]
en proc.num[]
itemsLinux-kernelthreads worden geteld door het item proc.num[]
maar rapporteren niet geheugen in proc.mem[]
item. Bijvoorbeeld:
$ ps -ef | grep kthreadd
wortel 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: Kan de hoeveelheid "VmSize"-geheugen niet ophalen.
Maar wat gebeurt er als er een gebruikersproces is met dezelfde naam als a kern draad? Dan zou het er zo uit kunnen zien:
$ ps -ef | grep kthreadd
wortel 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[]
telde zowel de kernelthread als het gebruikersproces. proc.mem[]
rapporteert alleen geheugen voor het gebruikersproces en telt de kernelthread-geheugen alsof het 0 is. Dit is anders dan het geval hierboven wanneer ZBX_NOTSUPPORTED werd gerapporteerd.
Wees voorzichtig bij het gebruik van proc.mem[]
en proc.num[]
items als het programma naam komt toevallig overeen met een van de threads.
Voordat u parameters in de items proc.mem[]
en proc.num[]
plaatst, moet u wil misschien de parameters testen met behulp van proc.num[]
item en ps
opdracht.