アルパカDiary Pro

はてなブログProではありません

dstatをfluentd+growthforecastでグラフ化(前編)

とあるクラスタ(複数台あるサーバ)に対して性能評価しているときに
dstatでリアルタイムに数値見ながら評価したいんですが
さらにまとめてリアルタイムグラフ化出来たら嬉しいのではないかなーと。


お、これはfluentd+growthforecastの出番では…!
と思い早速試してみましたよっと。

全体像

  • ノードサーバ(監視される側)
    • 各サーバでdstatを収集/整形しログに出力
    • fluentdでgrowthforecastAPIを叩く
  • グラフ生成サーバ(growthforecast)
    • config生成plackアプリを起動(今回はログ収集サーバで実行しているが、本来はどこで起動してもよい)
    • growthforecastプラグインでグラフ化


※最初考えていた構成ではグラフ生成サーバでログを受け取ってから
growthforecastに流しこんでました。
ログファイル自体も収集したい時にはその構成もありでしょう。


ノードサーバの設定

dstatの整形

riywoさんのスクリプトをちょっとだけ手直ししたものです。
https://gist.github.com/2069383

use strict;
use warnings;
use POSIX qw/mkfifo/;
use File::Temp qw/tempfile/;
use Scalar::Util qw/looks_like_number/;
use IO::Handle;
my $log_file = '/tmp/dstat.log';

my (undef, $pipe) = tempfile("dstat_XXXX", DIR => '/tmp', SUFFIX => '.pipe');
unlink $pipe;
mkfifo($pipe, 0666);

my $pid = fork;
if ($pid) {
    open my $dstat, '<', $pipe or die;
    open my $log, '>', $log_file or die;
    $log->autoflush;
    my @columns = qw/
cpu-usr cpu-sys cpu-idl cpu-wai cpu-hiq cpu-siq
la-1m la-5m la-15m
mem-used mem-buff mem-cach mem-free
dsk-read dsk-writ
io-read io-writ
net-recv net-send
/; # for dstat -Tclmdrn
    print $log join("\t", ('epoch', @columns)) . "\n";

    while (my $line = <$dstat>) {
        chomp $line;
        my @data = split /,/, $line;
        next unless(looks_like_number $data[0]);

        @data = map { int($_) } @data;

        my $time = int(shift @data);
        print $log join("\t", ($time, @data)) . "\n";
    }
    close $dstat; close $log;
} else {
    system("dstat -Tclmdrn --output $pipe");
}
unlink $pipe;

スクリプト実行しておく。

perl dstat.pl
fluentd 設定

td_agent.conf

include http://growthforecast_server:5000/

ログ収集サーバ

config用plackアプリ
use strict;
use warnings;
use Data::Dumper;

my $app = sub {
    my $env = shift;
    my $api_url = 'http://growthforecast_server/api/';
    my $remote_addr = $env->{REMOTE_ADDR};
    $remote_addr =~ s/\./-/g;
    my $tag_prefix = "dstat.Tclmdrn";
    my $tag_name = "$tag_prefix.$remote_addr";

    my $body = <<"EOF";
<source>
  type tail
  format /^(?<date>[^\\t]+)\\t(?<cpu-usr>[^\\t]+)\\t(?<cpu-sys>[^\\t]+)\\t(?<cpu-idl>[^\\t]+)\\t(?<cpu-wai>[^\\t]+)\\t(?<cpu-hiq>[^\\t]+)\\t(?<cpu-siq>[^\\t]+)\\t(?<la-1m>[^\\t]+)\\t(?<la-5m>[^\\t]+)\\t(?<la-15m>[^\\t]+)\\t(?<mem-used>[^\\t]+)\\t(?<mem-buff>[^\\t]+)\\t(?<mem-cach>[^\\t]+)\\t(?<mem-free>[^\\t]+)\\t(?<dsk-read>[^\\t]+)\\t(?<dsk-writ>[^\\t]+)\\t(?<io-read>[^\\t]+)\\t(?<io-writ>[^\\t]+)\\t(?<net-recv>[^\\t]+)\\t(?<net-send>[^\\t]+)/
  path /tmp/dstat.log
  tag $tag_name
</source>

<match **>
  type          growthforecast
  gfapi_url     $api_url
  service       dstat
  tag_for       section
  remove_prefix $tag_prefix
  name_key_pattern .
</match>

EOF

    return [
        200,
        [ "Content-Type", "text/plain" ],
        [ "$body" ],
    ];
};
growthforecast起動(以下ドキュメント参照)

http://kazeburo.github.com/GrowthForecast/

待つだけ

あとは鼻歌でも歌いながら待っているだけで
勝手にこんなグラフが生成されているわけですよ!


すばらしい!


ベンチマークをとっているときには
growthforecastのWorkerのintervalを狭くすると良いかも。


ただしこのままだとcpuとか個別の指標で分かれてしまうので
自動的に複合グラフでまとめたいところですよねー。
そして後編へ続く…!!!!