vmstatとか、iostatの出力に時刻を付けたい

やりたいこと

表題の通りなんだが、solaris10環境でちょっと自作の小道具を動かすために、時刻が欲しくなった。例えば、sar とかだと、左端に時刻がつく。こんな感じ


bash-3.00$ sar -q 1 3

SunOS XXXXXX 5.10 Generic_xxxxxxx-xx i86pc 01/25/2009

20:36:33 runq-sz %runocc swpq-sz %swpocc
20:36:34 0.0 0 0.0 0
20:36:35 0.0 0 0.0 0
20:36:36 0.0 0 0.0 0

Average 0.0 0 0.0 0

で、vmstatの出力はこういう感じで時刻情報が無い。

bash-3.00$ vmstat 1 3
kthr memory page disk faults cpu
r b w swap free re mf pi po fr de sr cd f0 s0 -- in sy cs us sy id
0 0 0 1336696 388520 7 27 9 0 0 0 12 1 -0 4 0 297 245 198 1 2 98
0 0 0 1333680 385856 12 27 4 0 0 0 0 0 0 0 0 350 135 162 1 2 97
0 0 0 1333680 385868 6 6 0 0 0 0 0 0 0 0 0 335 189 144 0 2 98
で、付ける方法を考えた。つまり、この色の部分を付けて表示する。

20:41:39 kthr memory page disk faults cpu
20:41:39 r b w swap free re mf pi po fr de sr cd f0 s0 -- in sy cs us sy id
20:41:39 0 0 0 1336668 388496 7 27 9 0 0 0 11 1 -0 4 0 297 244 197 1 2 98
20:41:40 0 0 0 1332888 384280 249 554 0 0 0 0 0 0 0 0 0 359 641 181 2 4 94
20:41:41 0 0 0 1332888 384292 6 6 0 0 0 0 0 0 0 0 0 325 114 122 0 1 99
言語を、awk,perl,python,rubyで、それぞれ、mac,solaris,linuxで動かしてみた。vmware-fusion万歳。

awkの場合(gnu版に限る)

最初に、awkのstrftime関数が使えないか、と、思った。が、今回動かしたい、solaris10に付属のawkではstrftimeが上手く使えない、macでもダメだった(どうやら、gnu版のawkなら使える模様だが、デフォルトの環境に対しての対処策を知りたいので却下)
でも、多分、Linuxとかだとこういう感じになるだろう。試しに手元のScientific Linux(以下、Linux(SL)と記載)で打ってみると上手くいく。

vmstat 1 3 | awk '{print strftime("%H:%M:%S"), $0}'

perlの場合

perlからも、strftimeが呼べるのでこういうファイル(datein.pl)を作って実行する

#!/usr/bin/env perl
#

use POSIX 'strftime';

while(<>){
  # 年月日も出す場合
  #print strftime('%Y/%m/%d %H:%M:%S',localtime) , $_ , "\n";
  # 時分秒のみを出す場合
  print strftime('%H:%M:%S',localtime) , $_ ;
}

実行する

vmstat 1 3 | perl ./datein.pl

で、これだと、solaris10でも、mac(Leoperd)でも、Linux(SL)でも使える。

pythonの場合

こういうファイルで試してみたが、実行後の時刻がまとめて表示される。全て同じ時刻が書かれる。ダメだ。

#!/usr/bin/env python
# coding: UTF-8

import fileinput, time

for line in fileinput.input():
  print time.strftime("%H:%M:%S",time.localtime()) + line.rstrip("\n")

しばらく悩んだんだが、ここをみてこう書けば良いことがわかった。

#!/usr/bin/env python
# coding: UTF-8

import sys, time

line = sys.stdin.readline()
while line:
  print time.strftime("%H:%M:%S ",time.localtime()) + line,
  line = sys.stdin.readline()

printの後ろのカンマ(,)を付けることで改行を取っている。これを、datein.pyと名前をつけて保存して

vmstat 1 3 | python datein.py

で、これも、solaris10でも、mac(Leoperd)でも、Linux(SL)でも使える。

rubyの場合

な、んと。solaris10ではrubyは標準で入らない(コンパニオンCDにはあるらしい)今回は標準状態での動作を知りたいためsolaris10は除外。
これを、datein.rbとして保存。

#!/usr/bin/env ruby
$KCODE="UTF-8"

while line = gets
  print Time.now.strftime("%H:%M:%S") + line
end

この記述量の少なさは癖になる。イイ。こう実行。

vmstat 1 3 | ruby datein.rb

macと、Linux(SL)では問題ない。

まとめ

上記のスクリプトをまとめるとこういう感じ。

- mac(leopard) solaris10 Linux
awk(gnu) × ×
perl
python
ruby ×

Scientific Linux release 5.1はほぼ、RHEL 5と同等と考えてよいと思う。なんというか、Linuxの便利というか何でもありな感じが垣間見えて微笑ましい。
solaris10x86版で試したが、solaris使いを自称したいなら、rubyなんかよりもpythonperlが使えた方が便利な局面が多そうだ。