2008年12月4日木曜日

vmstat の出力に日付と時刻を付与@sh

サーバの稼動状況モニタ、 vmstat の出力には時刻情報がない。
 

標準だとこんな感じ、日付情報を出力したい時もあるよね。
# vmstat 1 3
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 33420 41628 45528 92228 0 0 7 47 14 4 1 1 98 0 0
0 0 33420 41628 45528 92228 0 0 0 0 38 35 0 0 100 0 0
0 0 33420 41508 45528 92228 0 0 0 0 67 77 2 0 98 0 0

 

よい方法を探してみたら同じよう流れの記事を見つけた、やはり多くが思うことなんだろう。

vmstatに日時を付ける - いろいろつまみぐい


 

perl だ、 さらにたどれば rubyでの実装 もやってる、なるほど。
 
 

うーん、perlが入ってないlinuxサーバなんか見たこと無いが、ここはシェルでもやってみたい。
 

という事でスクリプトを作ったぞ。
[sourcecode language='sh']
#!/bin/sh

while read -e hoge ; do
echo `date +%Y%m%d' '%H':'%M':'%S` ${hoge}
done
[/sourcecode]
シェルの組み込みコマンド、read で入力を一行ずつ処理するのだ、これを"vmread.sh"とでもして保存。(追記:hoge を省略すると変数名はREPLYになる)
 
 


# vmstat 1 3 | ./vmread.sh

早速実行!
20081202 20:30:01 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------

よい感じで日付情報が付いている…
 

20081202 20:30:01 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
20081202 20:30:01 r b swpd free buff cache si so bi bo in cs us sy id wa st
20081202 20:30:01 1 0 33420 35248 46172 92228 0 0 7 47 14 4 1 1 98 0 0
20081202 20:30:02 1 0 33420 34768 46172 92228 0 0 0 0 173 555 6 8 86 0 0
20081202 20:30:03 0 0 33420 34324 46172 92240 0 0 0 0 132 399 2 10 88 0 0

Σ(-д-) ゲッー!左にずれたー
 

どうやら read が 行の内容を hoge に突っ込む時に連続したスペースを一つの区切り文字と認識、詰めちゃってるようだ。
2009/2/17追記:
${hoge} をダブルクォーテーションで囲めば区切られないのでOK

 
 

対策を考えないと、、bashのマニュアル みても有効そうな手立ては無し。
とりあえず最後の出力に対して、trコマンドで スペースをTABに変換 してみる。
# vmstat 1 3 | ./vmread.sh | tr " " "\t"

どうかな?
20081202 20:37:34 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
20081202 20:37:34 r b swpd free buff cache si so bi bo in cs us sy id wa st
20081202 20:37:34 1 0 33420 40280 46728 92260 0 0 7 47 14 4 1 1 98 0 0
20081202 20:37:35 0 0 33420 39980 46728 92260 0 0 0 0 53 76 1 1 98 0 0
20081202 20:37:36 0 0 33420 39980 46728 92260 0 0 0 0 49 67 0 1 99 0 0

(予想通り)右に伸びたー...
 
 

困った。
少し考えて、出力をいじるのが無理なので入力をいじってみることに。
 

vmstat の出力からスペースをカンマに変換してreadに渡すと?
# vmstat 1 3 | tr " " "," | ./vmread.sh
20081202 20:42:22 procs,-----------memory----------,---swap--,-----io----,--system--,-----cpu------
20081202 20:42:22 ,r,,b,,,swpd,,,free,,,buff,,cache,,,si,,,so,,,,bi,,,,bo,,,in,,,cs,us,sy,id,wa,st
20081202 20:42:22 ,1,,0,,33420,,39928,,47076,,92268,,,,0,,,,0,,,,,7,,,,47,,,14,,,,4,,1,,1,98,,0,,0
20081202 20:42:22 ,0,,0,,33420,,39928,,47076,,92272,,,,0,,,,0,,,,,0,,,,,0,,,35,,,36,,0,,0,100,,0,,0
20081202 20:42:22 ,0,,0,,33420,,39688,,47076,,92272,,,,0,,,,0,,,,,0,,,,,0,,,95,,146,,0,,1,99,,0,,0

おお。コレはいけるぞ。
 

それでは最後にもう一度 trコマンド を入れて、カンマからスペースに変換。
# vmstat 1 3 | tr " " "," | ./vmread.sh | tr "," " "
20081202 20:46:06 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
20081202 20:46:06 r b swpd free buff cache si so bi bo in cs us sy id wa st
20081202 20:46:06 1 0 33420 39488 47412 92280 0 0 7 47 14 4 1 1 98 0 0
20081202 20:46:06 0 0 33420 39248 47412 92280 0 0 0 0 109 155 0 0 100 0 0
20081202 20:46:06 0 0 33420 39248 47412 92280 0 0 0 0 67 96 1 0 99 0 0

よぅし、完璧だ! …と思う。
 
 
(追記)
vmread.sh の前に trコマンドをはさんでしまうと、出力を全部貰ってからになるので全部同じ時間がくっつくことが判明!
パイプの仕様からしてよく考えたらそうかも…もう一工夫がいるのか。
 
ちょっと保留だなぁ。左に詰められても一応使い物になるし。
※コメントにより解決済み