Zabbixはメモリ監視がMuninより苦手です。デフォルトのLinuxテンプレートはあまり役に立ちません。ここはひとつ気合いである程度まで再現してみましょう。
お手本となるMuninのMemoryグラフ
まずはMuninのグラフを確認します。
この中でも重要と思われるapps ~ swap(塗りつぶしグラフ)をZabbixで再現します。というかZabbix2.Xは塗りつぶしグラフと線グラフの共存ができません。
これらの値は、基本的に/proc/meminfoの値を参照すれば取得できるのですが「apps」と「swap」は自分で計算する必要があります。そうなると/etc/zabbix/zabbix_agentd.confにUserParameterを1行追加するだけでは実現できませんので、スクリプトを作成する必要が出てきました。
Memory取得スクリプトを作成する
appsとswapはmuninグラフの読み方と意味 | シーズクリエイターズブログによると以下のの計算式で求められるとのことです。
「apps」 = MemTotal - MemFree - Buffers - Cached - Slab - PageTables - SwapCached 「swap」 = cache - (SwapCache + buffers)
※参考 muninmuninグラフの読み方と意味 | シーズクリエイターズブログ
https://www.seeds-std.co.jp/seedsblog/488.html
まずは確実に動作するスクリプトとしてこんなものを作ってみます。
# vi /etc/zabbix/zabbix.memory.sh
#!/bin/sh
## /proc/meminfoから計算に必要な値を取り出す
MemTotal=$(cat /proc/meminfo |grep MemTotal| awk '{print $2}')
MemFree=$(cat /proc/meminfo |grep MemFree| awk '{print $2}')
Buffers=$(cat /proc/meminfo |grep Buffers| awk '{print $2}')
Cached=$(cat /proc/meminfo |grep Cached| awk '{print $2}' |head -n1)
Slab=$(cat /proc/meminfo |grep Slab| awk '{print $2}')
PageTables=$(cat /proc/meminfo |grep PageTables| awk '{print $2}')
SwapCached=$(cat /proc/meminfo |grep SwapCached| awk '{print $2}')
SwapTotal=$(cat /proc/meminfo |grep SwapTotal| awk '{print $2}')
SwapFree=$(cat /proc/meminfo |grep SwapFree| awk '{print $2}')
## meminfoの単位がKBなので、1024をかけてB表記にする。
## appsとswapは値を計算する
apps=$(expr \( $MemTotal - $MemFree - $Buffers - $Cached - $Slab - $PageTables - $SwapCached \) \* 1024)
page_tables=$( expr $PageTables \* 1024)
swap_cache=$( expr $SwapCached \* 1024)
slab_cache=$( expr $Slab \* 1024)
cache=$( expr $Cached \* 1024)
buffers=$( expr $Buffers \* 1024)
unused=$( expr $MemFree \* 1024)
swap=$( expr \( $SwapTotal - $SwapFree \) \* 1024)
## 判別しやすいようにヘッダを付けて計算結果を出力する
echo apps. $apps
echo page_tables. $page_tables
echo swap_cache. $swap_cache
echo slab_cache. $slab_cache
echo cached. $cache
echo buffers. $buffers
echo unused. $unused
echo swapd. $swap
exit
このスクリプトに実行権を付与して処理を行ってみます。
# chmod 755 /etc/zabbix/zabbix.memory.sh # ll /etc/zabbix/zabbix.memory.sh -rwxr-xr-x 1 root root 1148 7月 31 19:46 2016 /etc/zabbix/zabbix.memory.sh # /etc/zabbix/zabbix.memory.sh apps. 514482176 page_tables. 33808384 swap_cache. 165908480 slab_cache. 65183744 cached. 970907648 buffers. 120242176 unused. 97595392 swapd. 758263808
とりあえずこれで必要な値を出力できるようになりましたがこのスクリプトは2つ問題があります。
1つは/proc/meminfoを9発も打っているので無駄な処理が多く遅いこと、もう1つは1発1発毎に/proc/meminfoの結果が異なるので厳密には正確な値でないこと。この二つを解決できる方法を思いついたので修正してみました。
Memory取得スクリプトを改良する
/proc/meminfoの実行を1回で済ますことができれば、2つの問題は解決します。
まずは/proc/meminfoから処理に必要な行をgrepの|(または)を使って取り出します。
# cat /proc/meminfo |grep "\(MemTotal:\|MemFree:\|Buffers:\|Cached:\|Slab:\|PageTables:\|SwapCached:\|SwapTotal:\|SwapFree:\)" MemTotal: 1922000 kB MemFree: 96736 kB Buffers: 117672 kB Cached: 948532 kB SwapCached: 162020 kB SwapTotal: 4128764 kB SwapFree: 3388272 kB Slab: 63604 kB PageTables: 32724 kB
次に「awk ‘{print $2}’」を使って2列目だけを取り出し、「tr ‘\n’ ‘,’」で改行を区切り文字「,」に置換します。
# cat /proc/meminfo |grep "\(MemTotal:\|MemFree:\|Buffers:\|Cached:\|Slab:\|PageTables:\|SwapCached:\|SwapTotal:\|SwapFree:\)" | awk '{print $2}'|tr '\n' ',' 1922000,93316,117964,950812,162020,4128764,3388272,63880,32848,
この出力結果を変数「TEXT」に格納、「IFS=’,’」で区切り文字「,」を指定し、「set — $TEXT」でTEXTの文字列を配列に配置します。
# TEXT=$(cat /proc/meminfo |grep "\(MemTotal:\|MemFree:\|Buffers:\|Cached:\|Slab:\|PageTables:\|SwapCached:\|SwapTotal:\|SwapFree:\)" | awk '{print $2}'|tr '\n' ',') # IFS=',' # set -- $TEXT # echo $1 $2 $3 $4 $5 $6 $7 $8 $9 1922000 93316 117964 950812 162020 4128764 3388272 63880 32848
$1 ~ $9の結果を変数に代入する
# MemTotal=$1 # MemFree=$2 # Buffers=$3 # Cached=$4 # Slab=$8 # PageTables=$9 # SwapCached=$5 # SwapTotal=$6 # SwapFree=$7
この後の処理は改良前と同じですので、結果的にこうなります。
# /etc/zabbix/zabbix.memory2.sh
#!/bin/sh
TEXT=$(cat /proc/meminfo |grep "\(MemTotal:\|MemFree:\|Buffers:\|Cached:\|Slab:\|PageTables:\|SwapCached:\|SwapTotal:\|SwapFree:\)" | awk '{print $2}'|tr '\n' ',')
IFS=','
set -- $TEXT
MemTotal=$1
MemFree=$2
Buffers=$3
Cached=$4
Slab=$8
PageTables=$9
SwapCached=$5
SwapTotal=$6
SwapFree=$7
apps=$(expr \( $MemTotal - $MemFree - $Buffers - $Cached - $Slab - $PageTables - $SwapCached \) \* 1024)
page_tables=$( expr $PageTables \* 1024)
swap_cache=$( expr $SwapCached \* 1024)
slab_cache=$( expr $Slab \* 1024)
cache=$( expr $Cached \* 1024)
buffers=$( expr $Buffers \* 1024)
unused=$( expr $MemFree \* 1024)
swap=$( expr \( $SwapTotal - $SwapFree \) \* 1024)
echo apps. $apps
echo page_tables. $page_tables
echo swap_cache. $swap_cache
echo slab_cache. $slab_cache
echo cached. $cache
echo buffers. $buffers
echo unused. $unused
echo swapd. $swap
exit
改良版の処理時間をtimeで計ってみると2倍に高速化できていました。
# time /etc/zabbix/zabbix.memory.sh ~ real 0m0.024s user 0m0.001s sys 0m0.004s # time /etc/zabbix/zabbix.memory2.sh ~ real 0m0.011s user 0m0.001s sys 0m0.003s
zabbix-agentにUserParameterを追加する
ここまで来たらあとは簡単。/etc/zabbix/zabbix_agentd.confにUserParameterを追加するだけです。
# vi /etc/zabbix/zabbix_agentd.conf
+ UserParameter=vm.memory.size.m[*],/etc/zabbix/zabbix.memory.sh|grep "$1"| awk '{print $$2}'
# service zabbix-agent restart
# service zabbix-agent restart
Shutting down Zabbix agent: [ OK ]
Starting Zabbix agent: [ OK ]
Zabbixサーバからzabbix_getコマンドで値を取得可能か確認します。
# zabbix_get -s 192.0.2.86 -k vm.memory.size.m[apps] 515538944
Zabbixにアイテムを登録する
UserParameterに追加したキー+[]の中に関ししたい項目を指定してアイテムを作成します。
必要な分のアイテムを作成し、Zabbix上で各々のデータ取得ができることを確認したら、最後にグラフを作成します。グラフの色はMuninと同じものにしてみました。
メモリのグラフができた!
これで欲しい情報が入ったメモリのグラフを作成できました。
やっぱりZabbixのカスタマイズ性は抜群だと思います。Muninの自作プラグイン作成だったらこんなに簡単にはいきません。
コメント
/proc/meminfo の計算でとても助かりましたありがとうございます
apps=MemTotal-MemFree-Buffers-Cached-Slab-PageTables-SwapCached
この計算式はすばらしい