Pyon's Diary
2003-09-30 舊 平成拾伍年長月伍日 (晴) [更]
拾貳國記 風の萬里 黎明の空(上)/拾貳國記 風の萬里 黎明の空(下)/拾貳國記 圖南の翼/拾貳國記 黄昏の岸 暁の天(上)/拾貳國記 黄昏の岸 暁の天(下)
を讀んだ。
何だかんだ言つて讀んでゐるなあ。
追記: 續きが出無い。(2007-09-30)
仲々續きが出無い。
此乃人も田中芳樹と同じか。
つて云ふか田中芳樹も「野望圓舞曲」を書いてゐる暇が有るなら、「アルスラーン」、「タイタニア」と「自轉地球儀」の續きを早く書け。
もう何年*1待つてゐると思つてゐるんだ。
今既刊リスト觀たらパッケージ變はつてゐるし。
*1 少なく共拾年近く待つてる筈。
2006-09-30 舊 平成拾捌年葉月玖日 (土・晴) [更]
emerge に要した時間を調べる。
Gentoo/tips -- Gentooメモみたいなページに依ると二つのコマンドが在るらしい。
- app-portage/splat
- app-portage/genlop
into the Linux world -- 非力マシン対決(笑)に依ると、genlop の方が簡単に使用出来るらしいので、此方を入れた。
2007-09-30 舊 平成拾玖年丁亥葉月廿日丁卯 (日・雨) [更]
捏造された聖書。
捏造された聖書 を讀んだ。
原題は「MISQUOTING JESUS」自分の英語力では「イエスを誤引用する。」か。
其れは兎も角、面白かつたので一氣に讀んで仕舞つた。讀み終はつたら朝の八時だつた。
追記: 聖書のみ。(2007-10-01)
著者の「バート・D・アーマン」(Bart D. EHRMAN) は、Google で「捏造された聖書」を檢索すると「本文批評學」で有名な學者らしい。
「本文批評」とは Wikipedia に據ると、
本文批評 (ほんもんひひゃう、英: Textual citicism, 獨: Textkritik, 佛: Critique textuelle) とは、文獻學において、ある文書の現存する寫本から、可能な限り、その文書の元來の形を復元する作業を言ふ。本文批判、正文批判(批評)、テキスト批判(批評)とも呼ばれる。
[Wikipedia - 本文批評より引用]
との事。要するに「今は無き原本を復元する」と云ふ事らしいのだが、著者は「聖書の原本を復元する」専門家らしい。
何故「聖書の原本を復元する」事が重要かと云ふと、昔は活版印刷も無く書籍の配布は寫本に據るしか無かつた。寫本は人が手で一文字づゝ、一単語づゝ書き寫して行くので、其乃際に誤字・脱字等の寫し間違ひが有つたり、書き寫す人が「此は間違ひだろう」と判斷して(善意又は悪意の)改竄が爲される事が有る。其乃爲、寫本が行はれる度に原本から懸け離れて行く。
普通の文書なら「さう云ふ事も有るさ」で濟む事も有るかも知れ無いが、ものが聖書だと然うは行か無い。何故ならば、
聖書は無謬なる神の御言葉である
[捏造された聖書 P.11より引用]
だから。途中で人の手に據つて誤字・脱字・書換が行はれてゐると問題と成る。其乃割には米國での報道とかを見る限り一般の信者では餘り問題に成つてゐ無いみたいだが。
此乃本は、聖書の歴史、寫本の問題、聖書本文批評の歴史と其乃方法の歴史、が判り易く且つ讀み易く書いて在り、聖書に關して大した予備知識が無くても充分讀める。聖書に興味が或る人には御奨めの本だと思ふ。
2008-09-30 舊 平成廿年戊子長月貳日癸酉 (火・雨) [更]
KURO-BOX/PRO (No.42) RRDtoolで温度・其乃外を監視する。
先日S.M.A.R.T.でKURO-BOX/PROのHDDの温度を取得出來る樣に成つたので、序でにRRDtoolでグラフを描かせる事にした。
參考にした頁は以下の通り。
* {{tlink "http://agj.at/~fors/sysworks/data/rrdtool/rrdtool.txt", "rrdtool - ラウンドロビンデータベースツール"}}。({{tlink "http://s01.megalodon.jp/2008-0930-2301-25/agj.at/~fors/sysworks/data/rrdtool/rrdtool.txt", "ウェブ魚拓", "rrdtool - ラウンドロビンデータベースツール"}})
* {{tlink "http://agj.at/~fors/sysworks/data/rrdtool/rrdcreate.txt", "rrdtool create - 新しいラウンドロビンデータベースを作成します"}}。({{tlink "http://s03.megalodon.jp/2008-0930-2303-23/agj.at/~fors/sysworks/data/rrdtool/rrdcreate.txt", "ウェブ魚拓", "rrdtool create - 新しいラウンドロビンデータベースを作成します"}})
* {{tlink "http://agj.at/~fors/sysworks/data/rrdtool/rrdupdate.txt", "rrdtool update - 新しい値をRRDに格納します"}}。({{tlink "http://s01.megalodon.jp/2008-0930-2304-55/agj.at/~fors/sysworks/data/rrdtool/rrdupdate.txt", "ウェブ魚拓", "rrdtool update - 新しい値をRRDに格納します"}})
* {{tlink "http://agj.at/~fors/sysworks/data/rrdtool/rrdgraph.txt", "rrdtool graph - 1つもしくは複數のRRDを元にグラフを生成します"}}。({{tlink "http://s04.megalodon.jp/2008-0930-2306-49/agj.at/~fors/sysworks/data/rrdtool/rrdgraph.txt", "ウェブ魚拓", "rrdtool graph - 1つもしくは複數のRRDを元にグラフを生成します"}})
* {{tlink "http://agj.at/~fors/sysworks/data/rrdtool/rrdtune.txt", "rrdtune - ラウンドロビンデータベースのいくつかの基本的な屬性を變更します"}}。({{tlink "http://s01.megalodon.jp/2008-0930-2311-23/agj.at/~fors/sysworks/data/rrdtool/rrdtune.txt", "ウェブ魚拓", "rrdtune - ラウンドロビンデータベースのいくつかの基本的な屬性を變更します"}})
* {{tlink "http://agj.at/~fors/sysworks/data/rrdtool/rrdinfo.txt", "rrdinfo - RRDからヘッダ情報を抽出します"}}。({{tlink "http://s01.megalodon.jp/2008-0930-2317-00/agj.at/~fors/sysworks/data/rrdtool/rrdinfo.txt", "ウェブ魚拓", "rrdinfo - RRDからヘッダ情報を抽出します"}})
- [RRDtool チュートリアル (network traffic)] Debian Linux Server.
- About Rrdtool.
- rrdtool - かもめ日記。
- ディスクアクセスを確認する方法 - inutchの日記。
取敢へずRRDtoolを入れた。Debianなので簡單に入つた。
# /usr/bin/aptitude install rrdtool
Reading package lists... Done
Building dependency tree
Reading state information... Done
Reading extended state information
Initializing package states... Done
The following NEW packages will be installed:
defoma{a} fontconfig{a} fontconfig-config{a} libcairo2{a} libdatrie0{a} libfontconfig1{a}
libfontenc1{a} libfreetype6{a} libglib2.0-0{a} libglib2.0-data{a} libpango1.0-0{a}
libpango1.0-common{a} libpixman-1-0{a} libpng12-0{a} librrd4{a} libthai-data{a} libthai0{a}
libxcb-render-util0{a} libxcb-render0{a} libxfont1{a} libxft2{a} libxrender1{a} rrdtool
ttf-dejavu{a} ttf-dejavu-core{a} ttf-dejavu-extra{a} x-ttcidfont-conf{a} x11-common{a}
xfonts-encodings{a} xfonts-utils{a}
0 packages upgraded, 30 newly installed, 0 to remove and 21 not upgraded.
Need to get 10.5MB of archives. After unpacking 23.3MB will be used.
Do you want to continue? [Y/n/?]
(中略)
Reading extended state information
Initializing package states... Done
Writing extended state information... Done
矢鱈と澤山グラフィック關係のパッケージが入つた。
次にRRDファイルを作成した。温度なので手引きに書いて在る事を其乃儘利用した。但し今囘はmiconaplで取得出來る温度とsmartctlで取得出來る温度の二つを記録出來る樣にした。
#!/bin/sh rrdtool create \ /var/lib/rrdtool/temperature.rrd \ --step 300 \ DS:HDD:GAUGE:600:-273:5000 \ DS:BOX:GAUGE:600:-273:5000 \ RRA:AVERAGE:0.5:12:35064 \ RRA:MIN:0.5:12:35064 \ RRA:MAX:0.5:12:35064 \ RRA:LAST:0.5:1:420768
データソース「HDD」はsmartctlで取得出來るHDDの温度を、データソース「BOX」はmiconaplで取得出來る温度を格納する。
データ數は基本5分(300秒)に1個で4年分を貯める事にしたので「RRA:LAST」は
1440 / 5 * ( 4 * 365 + 1) = 420768
で420,768個。最小値(MIN)、最大値(MAX)、平均(AVERAGE)は1時間(5 * 12)内の最小、最大、平均を4年分格納するので、
420768 / 12 = 35064
で35,064個とした。
次にデータを取得してRRDを更新するスクリプトを作つた。其乃スクリプトではデータの更新を行つた後で序でにグラフ(畫像)も生成する事にした。
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Carp;
use Getopt::Long;
use IO::Pipe;
use Readonly;
Readonly::Scalar my $day_sec => 24 * 60 * 60;
Readonly::Scalar my $rrd => q{/var/lib/rrdtool/temperature.rrd};
Readonly::Array my @types => qw(day week month year);
Readonly::Hash my %span => {
'day' => -86400,
'week' => -86400 * 7,
'month' => -86400 * 31,
'year' => -86400 * 365,
};
Readonly::Hash my %fmrts => {
'pngfile' => q{/var/www/status/temperature.%s.png},
'updcmd' => q{/usr/bin/rrdtool update %s N:%d:%d},
'grpcmd' => <<'_GRAPH_CMD_', };
/usr/bin/rrdtool graph %s \
--start %s \
--width 480 \
--vertical-label "Temperature (C)" \
--title "HDD / Box Temperature (%s)" \
DEF:hdd=%s:HDD:LAST \
DEF:box=%s:BOX:LAST \
LINE2:hdd#ff0000:"HDD" \
GPRINT:hdd:LAST:"Cur. %%6.2lfC," \
GPRINT:hdd:MIN:"Min. %%6.2lfC," \
GPRINT:hdd:MAX:"Max. %%6.2lfC," \
GPRINT:hdd:AVERAGE:"Ave. %%6.2lfC\n" \
LINE2:box#ff8000:"BOX" \
GPRINT:box:LAST:"Cur. %%6.2lfC," \
GPRINT:box:MIN:"Min. %%6.2lfC," \
GPRINT:box:MAX:"Max. %%6.2lfC," \
GPRINT:box:AVERAGE:"Ave. %%6.2lfC\n" \
> /dev/null 2>&1
_GRAPH_CMD_
# ヘルプを表示する。
sub help {
print <<'_HELP_';
usage;
rrdupdate.temperature.pl [--help] [--only-fetch] [--only-graph]
--help : display help and exit.
--only-fetch : Only fetch data.
--only-graph : Only draw graph.
_HELP_
exit 0;
}
my %opts = (
'debug' => 0,
'help' => 0,
'fetch-data' => 1,
'draw-graph' => 1,
);
# コマンドライン・オプションを解析する。
{
GetOptions(
'debug' => \$opts{'debug'},
'help' => \$opts{'help'},
'only-fetch!' => \$opts{'draw-graph'},
'only-graph!' => \$opts{'fetch-data'},
) or exit 1;
$opts{'help'} and help;
}
# データを取得してRRDを更新する。
if ( $opts{'fetch-data'} ) {
my %temperature = ( 'hdd' => 0, 'box' => 0, );
# HDDの温度を取得する。
{
my $pipe = IO::Pipe->new;
$pipe->reader(qw(/usr/sbin/smartctl --attributes /dev/sda));
while (<$pipe>) {
m/\A194 Temperature_Celsius\s+/ or next;
$temperature{'hdd'} = ( split /\s+/, $_ )[9];
}
$temperature{'hdd'} or croak q{Can't get temperature of hdd.};
}
# 筐體の温度を取得する。
{
my $pipe = IO::Pipe->new;
$pipe->reader(qw(/usr/local/sbin/miconapl -a temp_get));
while (<$pipe>) {
m/\Atemp=/ or next;
$temperature{'box'} = ( split /=/, $_ )[1];
}
$temperature{'box'} or croak q{Can't get temperature of box.};
}
my $update = sprintf $fmrts{'updcmd'}, $rrd, $temperature{'hdd'},
$temperature{'box'};
$opts{'debug'} and carp Dumper( \$update );
system($update) == 0 or die "system $update failed: $?";
}
# グラフを描く。
if ( $opts{'draw-graph'} ) {
foreach my $type (@types) {
my $png = sprintf $fmrts{'pngfile'}, $type;
my $graph = sprintf $fmrts{'grpcmd'}, $png, $span{$type}, $type, $rrd,
$rrd;
$opts{'debug'} and carp Dumper( \$graph );
system($graph) == 0 or die "system $graph failed: $?";
}
}
此れをcronで5分に1囘實行する樣に設定した。
暫く回して得られたグラフが下の畫像。

普段は大體40度前後だがsmartctlでテストを實行すると途端に温度が上がつた。
追記: モジュール。
PerlからRRDを扱ふのに、
- RRDp - Attach rrdtool from within a perl script via a set of pipes. (librrdp-perl)
- RRDs - Access rrdtool as a shared module. (librrds-perl)
等のモジュールが在るみたいなので、上のスクリプトは其乃内書き直す事。
追記: RRDsを使つてみた。(2008-10-01)
RRDsはPerlから共有ライブラリ経由でRRDを扱ふ爲のモジュール。RRDの更新とグラフの描畫を此乃モジュールを使つて行ふ樣に直した。
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Carp;
use Data::Dumper;
use Getopt::Long;
use IO::Pipe;
use RRDs;
use Readonly;
Readonly::Scalar my $rrd => q{/var/lib/rrdtool/temperature.rrd};
Readonly::Array my @types => qw(day week month year);
Readonly::Hash my %span => {
'day' => -86400,
'week' => -86400 * 7,
'month' => -86400 * 31,
'year' => -86400 * 365,
};
Readonly::Hash my %fmrts =>
{ 'pngfile' => q{/var/www/status/temperature.%s.png}, };
# ヘルプを表示する。
sub help {
print <<'_HELP_';
usage;
rrdupdate.temperature.pl [--help] [--noupdating] [--nodrawing]
--help : display help and exit.
--noupdating : doesn't update rrd.
--nodrawing : doesn't draw graph.
_HELP_
exit 0;
}
my %opts = (
'debug' => 0,
'help' => 0,
'updating' => 1,
'drawing' => 1,
);
# コマンドライン・オプションを解析する。
{
GetOptions(
'debug' => \$opts{'debug'},
'help' => \$opts{'help'},
'updating!' => \$opts{'updating'},
'drawing!' => \$opts{'drawing'},
) or exit 1;
$opts{'help'} and help;
$opts{'debug'} and print Dumper( \%opts );
}
# データを取得してRRDを更新する。
if ( $opts{'updating'} ) {
# HDDの温度を取得する。
my $hddtemp;
{
my $pipe = IO::Pipe->new;
$pipe->reader(qw(/usr/sbin/smartctl --attributes /dev/sda));
while (<$pipe>) {
s/\A\s+//;
s/\s+\Z//;
m/\A194 Temperature_Celsius\s+/ or next;
$hddtemp = ( split /\s+/, $_ )[9];
last;
}
$hddtemp or croak q{Can't get temperature of hdd.};
}
# 筐體の温度を取得する。
my $boxtemp;
{
my $pipe = IO::Pipe->new;
$pipe->reader(qw(/usr/local/sbin/miconapl -a temp_get));
while (<$pipe>) {
s/\A\s+//;
s/\s+\Z//;
m/\Atemp=/ or next;
$boxtemp = ( split /=/, $_ )[1];
last;
}
$boxtemp or croak q{Can't get temperature of box.};
}
# RRDを更新する。
RRDs::update( $rrd, "N:$hddtemp:$boxtemp" );
if ( my $err = RRDs::error ) {
croak "ERROR while updating $rrd: $err";
}
}
# グラフを描く。
if ( $opts{'drawing'} ) {
foreach my $type (@types) {
my $png = sprintf $fmrts{'pngfile'}, $type;
my $span = $span{$type};
my ( $averages, $xsize, $ysize ) = RRDs::graph(
$png,
'--start',
$span,
'--width',
'480',
'--vertical-label',
'Temperature (C)',
'--title',
"HDD / Box Temperature ($type)",
"DEF:hdd=$rrd:HDD:LAST",
"DEF:box=$rrd:BOX:LAST",
q{LINE2:hdd#ff0000:HDD},
q{GPRINT:hdd:LAST:Cur. %6.2lfC,},
q{GPRINT:hdd:MIN:Min. %6.2lfC,},
q{GPRINT:hdd:MAX:Max. %6.2lfC,},
q{GPRINT:hdd:AVERAGE:Ave. %6.2lfC\n},
q{LINE2:box#ff8000:BOX},
q{GPRINT:box:LAST:Cur. %6.2lfC,},
q{GPRINT:box:MIN:Min. %6.2lfC,},
q{GPRINT:box:MAX:Max. %6.2lfC,},
q{GPRINT:box:AVERAGE:Ave. %6.2lfC\n},
);
if ( my $err = RRDs::error ) {
croak "ERROR while drawing $png: $err";
}
if ( $opts{'debug'} ) {
print "Imagesize: ${xsize}x${ysize}\n";
print "Averages: ", ( join ", ", @{$averages} ), "\n";
}
}
}
追記: CPU利用率を監視する。(2008-10-01)
序でにCPU利用率も監視してグラフを生成させる事にした。CPU使用時間は/proc/statから得られた。
# /bin/cat /proc/stat cpu 3516697 2432459 1133790 17817467 158719 15583 67406 0 0 cpu0 3516697 2432459 1133790 17817467 158719 15583 67406 0 0 (省略)
九つの數字の意味は「man 5 proc」に書いて在つた。
- ユーザモードでの使用時間。
- 低優先度(nice)ユーザモードでの使用時間。
- システムモードでの使用時間。
- アイドル時間。
- I/O待ち時間。(2.5.41から)
- 割込みに(IRQ)取られた時間。(2.6.0-test4から)
- ソフトウェア割込み(?)に取られた時間。(2.6.0-test4から)
- 假想環境でのOSに取られた時間(?)。(2.6.11から)
- ゲストOSの假想CPUに取られた時間(?)。(2.6.24から)
最後の二つは餘り關係無さゝうだつたが一應取る事にした。以下の樣なシェルスクリプトでRRDを作成した。
#!/bin/sh for c in cpu cpu0 do rrdtool create \ /var/lib/rrdtool/$c.rrd \ --step 300 \ DS:USER:DERIVE:1200:U:U \ DS:NICE:DERIVE:1200:U:U \ DS:SYSTEM:DERIVE:1200:U:U \ DS:IDLE:DERIVE:1200:U:U \ DS:IOWAIT:DERIVE:1200:U:U \ DS:IRQ:DERIVE:1200:U:U \ DS:SOFTIRQ:DERIVE:1200:U:U \ DS:STEAL:DERIVE:1200:U:U \ DS:GUEST:DERIVE:1200:U:U \ RRA:AVERAGE:0.5:12:35064 \ RRA:MIN:0.5:12:35064 \ RRA:MAX:0.5:12:35064 \ RRA:LAST:0.5:1:420768 done
データを取得してグラフを生成するスクリプトは以下の樣にした。
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Carp;
use Getopt::Long;
use IO::File;
use RRDs;
use Readonly;
Readonly my $proc_file => q{/proc/stat};
Readonly my %span => {
'day' => 86400 * -1,
'week' => 86400 * -7,
'month' => 86400 * -31,
'year' => 86400 * -366,
};
Readonly my $rrddir => q{/var/lib/rrdtool};
Readonly my $pngdir => q{/var/www/status};
Readonly my %rrd => {
'cpu' => qq{$rrddir/cpu.rrd},
'cpu0' => qq{$rrddir/cpu0.rrd},
};
Readonly my %png => {
'cpu' => {
'day' => qq{$pngdir/cpu.day.png},
'week' => qq{$pngdir/cpu.week.png},
'month' => qq{$pngdir/cpu.month.png},
'year' => qq{$pngdir/cpu.year.png},
},
'cpu0' => {
'day' => qq{$pngdir/cpu0.day.png},
'week' => qq{$pngdir/cpu0.week.png},
'month' => qq{$pngdir/cpu0.month.png},
'year' => qq{$pngdir/cpu0.year.png},
},
};
# ヘルプを表示する。
sub help {
print <<'_HELP_';
usage;
rrdupdate.cpu.pl [--help] [--noupdating] [--nodrawing]
--help : display help and exit.
--noupdating : doesn't update rrd.
--nodrawing : doesn't draw graph.
_HELP_
exit 0;
}
my %opts = (
'debug' => 0,
'help' => 0,
'updating' => 1,
'drawing' => 1,
);
# コマンドライン・オプションを解析する。
{
GetOptions(
'debug' => \$opts{'debug'},
'help' => \$opts{'help'},
'updating!' => \$opts{'updating'},
'drawing!' => \$opts{'drawing'},
) or exit 1;
$opts{'help'} and help;
}
# データを取得してRRDを更新する。
if ( $opts{'updating'} ) {
my $fh = IO::File->new( $proc_file, 'r' ) or croak $!;
while (<$fh>) {
s/\A\s+//;
s/\s+\Z//;
m/\A(cpu0?)\s+/ or next;
my ( $cpu, @data ) = split /\s+/, $_;
# RRDを更新する。
RRDs::update( $rrd{$cpu}, join ':', 'N', @data );
if ( my $err = RRDs::error ) {
croak 'ERROR while updating ' . $rrd{$cpu} . ': ' . $err;
}
}
$fh->close;
}
# グラフを描く。
if ( $opts{'drawing'} ) {
foreach my $cpu ( keys %png ) {
foreach my $type ( keys %{ $png{$cpu} } ) {
my $rrd = $rrd{$cpu};
my $png = $png{$cpu}{$type};
my $start = $span{$type};
my ( $averages, $xsize, $ysize ) = RRDs::graph(
$png,
qq{--start=$start},
q{--width=480},
q{--vertical-label=ratio (%)},
qq{--title=$cpu usage ($type)},
qq{DEF:user=$rrd:USER:LAST},
qq{DEF:nice=$rrd:NICE:LAST},
qq{DEF:system=$rrd:SYSTEM:LAST},
qq{DEF:idle=$rrd:IDLE:LAST},
qq{DEF:iowait=$rrd:IOWAIT:LAST},
qq{DEF:irq=$rrd:IRQ:LAST},
qq{DEF:softirq=$rrd:SOFTIRQ:LAST},
qq{DEF:steal=$rrd:STEAL:LAST},
qq{DEF:guest=$rrd:GUEST:LAST},
q{AREA:user#ff0000:User },
q{GPRINT:user:LAST:Cur. %6.2lf%%,},
q{GPRINT:user:MIN:Min. %6.2lf%%,},
q{GPRINT:user:MAX:Max. %6.2lf%%,},
q{GPRINT:user:AVERAGE:Ave. %6.2lf%%\n},
q{STACK:nice#ff8000:Nice },
q{GPRINT:nice:LAST:Cur. %6.2lf%%,},
q{GPRINT:nice:MIN:Min. %6.2lf%%,},
q{GPRINT:nice:MAX:Max. %6.2lf%%,},
q{GPRINT:nice:AVERAGE:Ave. %6.2lf%%\n},
q{STACK:system#ffff00:System },
q{GPRINT:system:LAST:Cur. %6.2lf%%,},
q{GPRINT:system:MIN:Min. %6.2lf%%,},
q{GPRINT:system:MAX:Max. %6.2lf%%,},
q{GPRINT:system:AVERAGE:Ave. %6.2lf%%\n},
q{STACK:iowait#00ff00:I/O Wait},
q{GPRINT:iowait:LAST:Cur. %6.2lf%%,},
q{GPRINT:iowait:MIN:Min. %6.2lf%%,},
q{GPRINT:iowait:MAX:Max. %6.2lf%%,},
q{GPRINT:iowait:AVERAGE:Ave. %6.2lf%%\n},
q{STACK:irq#00ff80:IRQ },
q{GPRINT:irq:LAST:Cur. %6.2lf%%,},
q{GPRINT:irq:MIN:Min. %6.2lf%%,},
q{GPRINT:irq:MAX:Max. %6.2lf%%,},
q{GPRINT:irq:AVERAGE:Ave. %6.2lf%%\n},
q{STACK:softirq#00ffff:Soft IRQ},
q{GPRINT:softirq:LAST:Cur. %6.2lf%%,},
q{GPRINT:softirq:MIN:Min. %6.2lf%%,},
q{GPRINT:softirq:MAX:Max. %6.2lf%%,},
q{GPRINT:softirq:AVERAGE:Ave. %6.2lf%%\n},
q{STACK:steal#0080ff:Steal },
q{GPRINT:steal:LAST:Cur. %6.2lf%%,},
q{GPRINT:steal:MIN:Min. %6.2lf%%,},
q{GPRINT:steal:MAX:Max. %6.2lf%%,},
q{GPRINT:steal:AVERAGE:Ave. %6.2lf%%\n},
q{STACK:guest#0000ff:Guest },
q{GPRINT:guest:LAST:Cur. %6.2lf%%,},
q{GPRINT:guest:MIN:Min. %6.2lf%%,},
q{GPRINT:guest:MAX:Max. %6.2lf%%,},
q{GPRINT:guest:AVERAGE:Ave. %6.2lf%%\n},
q{STACK:idle#F0F0F0:Idle },
q{GPRINT:idle:LAST:Cur. %6.2lf%%,},
q{GPRINT:idle:MIN:Min. %6.2lf%%,},
q{GPRINT:idle:MAX:Max. %6.2lf%%,},
q{GPRINT:idle:AVERAGE:Ave. %6.2lf%%\n},
);
if ( my $err = RRDs::error ) {
croak q{ERROR while drawing } . $png . q{: } . $err;
}
if ( $opts{'debug'} ) {
print "Imagesize: ${xsize}x${ysize}\n";
print "Averages: ", ( join ", ", @{$averages} ), "\n";
}
}
}
}
此乃スクリプトを5分毎にcronで實行する樣に設定した。
暫く待つてから生成されたグラフは以下の通り。


CPU利用率、温度、ディスクI/O、ネットワーク・トラフィックのグラフを5分毎に生成させてゐるだけで恆に30%も消費してゐた。
困つた。
追記: データソースタイプを變更した。(2008-10-01)
CPU利用率のRRDはデータソースタイプを總て「DERIVE」にしてゐたのだが、實は其れは間違ひで「COUNTER」にしなければいけない事に氣が付いた。
其處でrrdinfoとrrdtuneとを使用してデータソースタイプを變更してみた。
# /usr/bin/rrdtool info /var/lib/rrdtool/cpu.rrd filename = "/var/lib/rrdtool/cpu.rrd" rrd_version = "0003" step = 300 last_update = 1222870322 ds[USER].type = "DERIVE" ds[USER].minimal_heartbeat = 1200 (省略)
で判る樣にデータソースタイプは「DERIVE」に成つてゐる。此れを變更した。
# /usr/bin/rrdtool tune /var/lib/rrdtool/cpu.rrd -d USER:COUNTER
を實行してデータソースタイプを變更してから再度確認した。
# /usr/bin/rrdtool info /var/lib/rrdtool/cpu.rrd filename = "/var/lib/rrdtool/cpu.rrd" rrd_version = "0003" step = 300 last_update = 1222870322 ds[USER].type = "COUNTER" ds[USER].minimal_heartbeat = 1200 (省略)
慥かに「DERIVE」から「COUNTER」に變更された。
追記: ネットワーク・トラフィックを監視する。(2008-10-02)
温度、CPUと來たので次はネットワーク・トラフィックを監視する事にした。ネットワーク・トラフィックは/proc/net/devから得られた。
# /bin/cat /proc/net/dev
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo: 4672 46 0 0 0 0 0 0 4672 46 0 0 0 0 0 0
eth0:4146163939 3220427 0 0 0 0 0 0 221565827 810949 0 0 0 0 0 0
此乃出力の意味はCPU利用率と同じく「man 5 proc」に書いて在つた。
必要なのは1番目と9番目の送受信バイト數、2番目と10番目の送受信パケット數なので、以下の樣なRRDにした。
#!/bin/sh
for i in lo eth0
do
rrdtool create \
/var/lib/rrdtool/net.${i}.rrd \
--step 300 \
DS:IN:COUNTER:600:U:U \
DS:OUT:COUNTER:600:U:U \
DS:IN_PACKET:COUNTER:600:U:U \
DS:OUT_PACKET:COUNTER:600:U:U \
RRA:AVERAGE:0.5:12:35064 \
RRA:MIN:0.5:12:35064 \
RRA:MAX:0.5:12:35064 \
RRA:LAST:0.5:1:420768
done
此乃RRDにデータを格納するスクリプトは以下の樣にした。
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Carp;
use Data::Dumper;
use Getopt::Long;
use IO::File;
use RRDs;
use Readonly;
Readonly my %span => {
'day' => 86400 * -1,
'week' => 86400 * -7,
'month' => 86400 * -31,
'year' => 86400 * -366,
};
Readonly my $rrddir => q{/var/lib/rrdtool};
Readonly my $pngdir => q{/var/www/status};
Readonly my %rrd => {
'lo' => qq{$rrddir/net.lo.rrd},
'eth0' => qq{$rrddir/net.eth0.rrd},
};
Readonly my %png => {
'lo' => {
'day' => qq{$pngdir/net.lo.day.png},
'week' => qq{$pngdir/net.lo.week.png},
'month' => qq{$pngdir/net.lo.month.png},
'year' => qq{$pngdir/net.lo.year.png},
},
'eth0' => {
'day' => qq{$pngdir/net.eth0.day.png},
'week' => qq{$pngdir/net.eth0.week.png},
'month' => qq{$pngdir/net.eth0.month.png},
'year' => qq{$pngdir/net.eth0.year.png},
},
};
sub help {
print <<'_HELP_';
usage;
rrdupdate.net.pl [--help] [--noupdating] [--nodrawing]
--help : display help and exit.
--noupdating : doesn't update rrd.
--nodrawing : doesn't draw graph.
_HELP_
exit 0;
}
my %opts = (
'debug' => 0,
'help' => 0,
'updating' => 1,
'drawing' => 1,
);
# コマンドライン・オプションを解析する。
{
GetOptions(
'debug' => \$opts{'debug'},
'help' => \$opts{'help'},
'updating!' => \$opts{'updating'},
'drawing!' => \$opts{'drawing'},
) or exit 1;
$opts{'help'} and help;
}
# データを取得してRRDを更新する。
if ( $opts{'updating'} ) {
# 送受信データ量とパケット數を取得し、
# RRDを更新する。
my $fh = IO::File->new( '/proc/net/dev', 'r' ) or croak $!;
while (<$fh>) {
s/\A\s+//;
s/\s+\Z//;
m/\A(lo|eth0):/ or next;
my ( $if, @data ) = split /[:\s]+/, $_;
RRDs::update( $rrd{$if}, join( ':', q{N}, @data[ 0, 8, 1, 9 ] ) );
if ( my $err = RRDs::error ) {
croak q{ERROR while updating } . $rrd{$if} . q{: } . $err;
}
}
}
# 日・週・月・年のグラフを描く。
if ( $opts{'drawing'} ) {
foreach my $interface ( keys %png ) {
foreach my $type ( keys %{ $png{$interface} } ) {
my $start = $span{$type};
my $rrd = $rrd{$interface};
my $png = $png{$interface}{$type};
my ( $averages, $xsize, $ysize ) = RRDs::graph(
$png,
qq{--start=$start},
q{--width=480},
q{--vertical-label=Traffic / Packets},
qq{--title=Traffic / Packets ($interface, $type)},
qq{DEF:in=$rrd:IN:LAST},
qq{DEF:out=$rrd:OUT:LAST},
qq{DEF:in_packet=$rrd:IN_PACKET:LAST},
qq{DEF:out_packet=$rrd:OUT_PACKET:LAST},
q{CDEF:in_c=in},
q{CDEF:out_c=out,-1,*},
q{CDEF:in_packet_c=in_packet},
q{CDEF:out_packet_c=out_packet,-1,*},
q{AREA:in_c#ff0000:In },
q{GPRINT:in_c:LAST:Cur. %+.2le,},
q{GPRINT:in_c:MIN:Min. %+.2le,},
q{GPRINT:in_c:MAX:Max. %+.2le,},
q{GPRINT:in_c:AVERAGE:Ave. %+.2le\n},
q{LINE2:in_packet_c#ffa0a0:P\:In },
q{GPRINT:in_packet_c:LAST:Cur. %+.2le,},
q{GPRINT:in_packet_c:MIN:Min. %+.2le,},
q{GPRINT:in_packet_c:MAX:Max. %+.2le,},
q{GPRINT:in_packet_c:AVERAGE:Ave. %+.2le\n},
q{AREA:out_c#0000ff:Out },
q{GPRINT:out_c:LAST:Cur. %+.2le,},
q{GPRINT:out_c:MIN:Min. %+.2le,},
q{GPRINT:out_c:MAX:Max. %+.2le,},
q{GPRINT:out_c:AVERAGE:Ave. %+.2le\n},
q{LINE2:out_packet_c#a0a0ff:P\:Out},
q{GPRINT:out_packet_c:LAST:Cur. %+.2le,},
q{GPRINT:out_packet_c:MIN:Min. %+.2le,},
q{GPRINT:out_packet_c:MAX:Max. %+.2le,},
q{GPRINT:out_packet_c:AVERAGE:Ave. %+.2le\n},
);
if ( my $err = RRDs::error ) {
croak "ERROR while drawing $png: $err";
}
if ( $opts{'debug'} ) {
print "Imagesize: ${xsize}x${ysize}\n";
print "Averages: ", ( join ", ", @{$averages} ), "\n";
}
}
}
}
此乃スクリプトを5分毎にcronで實行する樣に設定して、暫く待つと以下の樣なグラフが得られた。


餘りトラフィックは無かつた。もう少しKURO-BOX/PROの活用方法を考へた方が良いかも知れない。