2016年11月29日火曜日

LIO Cluster [LIO, DRBD, Pacemaker による冗長化 iSCSI Target] (その12)Munin用プラグイン(DRBD)

Munin 用のプラグインを作りました。

rhel サーバ個別のリソース監視を考えた場合、ほとんどの環境で有益なものはどれかと考えると、Munin しか選択肢がないのではないかと思います。既存環境では、Zabbix やその他の監視ソフトが既に動いていて、それらの邪魔にならないものでなければなりません。グラフ化が簡単にできるもの、負荷が軽いもの、インストールが容易なもの(本格的な RDBMS 不要は最低条件)、と考えると、RRD(Round Robin Database) Tool を利用している Munin に白羽の矢が立ちます。MRTG は rhel7 の標準パッケージとなっているという魅力がありますが、2値しかグラフ化できないことと、設定ファイルを作成するのが面倒で、候補から外れました。オープンソースを気軽に持ち込めない場合には、MRTG という選択肢は有用です。

Munin は、自動設定が進んでいて、プラグインが用意されているものを利用する限りにおいては、導入が簡単です。デフォルト設定のままだとホスト名が localhost になってしまう等の見た目を気にしなければ、インストールして、認証設定を入れ、サービス起動するだけです。
自動設定されたプラグインを個別に無効化したい場合は、シンボリックリンクを削除してサービスを再起動するだけで済みます。Zabbix 等でグラフ化しているのであれば、重複するものだけを除外するということも簡単にできます。


今回は、DRBD に関するプラグインを紹介します。

元ネタは以下にあります。

https://github.com/munin-monitoring/contrib/tree/master/plugins/drbd

2012年にコミットされてから変更されていないようです。
「drbd-stat」については、dr, dw, nr, ns の値が1024倍されていないです。
「drbd」については、dr, dw, nr, ns の値が1024倍ではなく、819倍されています。理由が分かりませんでした。ご存知の方がいらっしゃいましたら教えてください。
とりあえず、819倍の話は忘れて、以下の3つのプラグインを作りました。

dr(Disk Read), dw(Disk Write), nr(Network Receive), ns(Network Send), oos(Out Of Sync) については、KByte 単位の値が取得できるので、1つのグラフ内にまとめました。
その他の統計値に関するものを1つのグラフにまとめました。ただし、al(Activity Log) に関しては、取得される値が大きかったので、他の値に関するグラフが意味のないものになってしまうのを避けるため、別のグラフにしました。oos に関しても別グラフにした方がよいかもしれませんが、そこまではこだわらないことにします。
以上の3つです。
Disk アクセスと Netwok アクセスは、ほぼ同じ値になるため重なり合ってしまうので、分けてしまう方がいいのかもしれません。Primary と Secondary が入れ替わっても、別の種類でほぼ同じ値になってしまいます。グラフの読み方を理解していれば問題ないとも言えます。

気が向いたら、dr&,dw, nr&ns, oos, al, bm, lo, pe, ua, ap, ep の10個のグラフに分割します。

以下の DRBD8.4 に関するマニュアルを参照しながら作りました。
http://www.drbd.org/en/doc/users-guide-84/ch-admin#s-performance-indicators

ソースコードは GitHub にも置きました。


https://raw.githubusercontent.com/blog-pcoffice/public/master/drbd

cat << 'EOF' | sudo tee /usr/share/munin/plugins/drbd
#!/usr/bin/perl
#%# family=auto
#%# capabilities=autoconf
# http://www.drbd.org/en/doc/users-guide-84/ch-admin#s-performance-indicators

use strict;
my $file="/proc/drbd";
my $store = {};
my $rid;

&crunch;
&display;

sub display{
  if ($ARGV[0] and $ARGV[0] eq "config"){
    print "graph_title DRBD\n";
    print "graph_category DRBD\n";
    print "graph_info Graph DRBD\n";
    print "graph_vlabel Graph DRBD (Bytes/sec)\n";
    print "graph_scale yes\n";
    print "graph_args --base 1024 --lower-limit 0\n";
    print "graph_period second\n";
    print "graph_height 200\n";
    print "graph_width 400\n";
    print "graph_printf %7.2lf\n";
    foreach my $key ( keys %$store ){
      my $drbdname = 'drbd'.$key;
      print $drbdname."dr.label $drbdname Disk Read\n";
      print $drbdname."dw.label $drbdname Disk Write\n";
      print $drbdname."ns.label $drbdname Network Send\n";
      print $drbdname."nr.label $drbdname Network Receive\n";
      print $drbdname."os.label $drbdname Out of Sync\n";
      print $drbdname."dr.cdef ".$drbdname."dr,1024,*\n";
      print $drbdname."dw.cdef ".$drbdname."dw,1024,*\n";
      print $drbdname."ns.cdef ".$drbdname."ns,1024,*\n";
      print $drbdname."nr.cdef ".$drbdname."nr,1024,*\n";
      print $drbdname."os.cdef ".$drbdname."os,1024,*\n";
      print $drbdname."dr.min 0\n";
      print $drbdname."dw.min 0\n";
      print $drbdname."ns.min 0\n";
      print $drbdname."nr.min 0\n";
      print $drbdname."os.min 0\n";
      print $drbdname."dr.type DERIVE\n";
      print $drbdname."dw.type DERIVE\n";
      print $drbdname."ns.type DERIVE\n";
      print $drbdname."nr.type DERIVE\n";
      print $drbdname."os.type DERIVE\n";
    }
    exit 0;
  }
  foreach my $key ( keys %$store ){
    my $drbdname = 'drbd'.$key;
    print $drbdname."dw.value ".$store->{$key}->{'dw'}."\n";
    print $drbdname."dr.value ".$store->{$key}->{'dr'}."\n";
    print $drbdname."ns.value ".$store->{$key}->{'ns'}."\n";
    print $drbdname."nr.value ".$store->{$key}->{'nr'}."\n";
    print $drbdname."os.value ".$store->{$key}->{'os'}."\n";
  }
}

sub crunch{
  open (IN, $file) || die "Could not open $file for reading: $!";
  if ($ARGV[0] and $ARGV[0] eq "autoconf"){
    close (IN);
    print "yes\n";
    exit 0;
  }
  while (<IN>){
    next if /version:|GIT-hash:/;
    chomp;
    my ($drbd) = $_ =~ /^\s+(\d):/;
    $rid = $drbd if $drbd =~ /\d/;
    my ($ns) = $_ =~ /ns:(\d*)/;  $store->{ $rid }->{'ns'} = $ns if $ns ne undef;
    my ($nr) = $_ =~ /nr:(\d*)/;  $store->{ $rid }->{'nr'} = $nr if $ns ne undef;
    my ($dw) = $_ =~ /dw:(\d*)/;  $store->{ $rid }->{'dw'} = $dw if $dw ne undef;
    my ($dr) = $_ =~ /dr:(\d*)/;  $store->{ $rid }->{'dr'} = $dr if $dr ne undef;
    my ($os) = $_ =~ /oos:(\d*)/; $store->{ $rid }->{'os'} = $os if $os ne undef;
  }
  close (IN);
}

exit 0;
EOF
sudo chmod 755 /usr/share/munin/plugins/drbd



https://raw.githubusercontent.com/blog-pcoffice/public/master/drbd_al

cat << 'EOF' | sudo tee /usr/share/munin/plugins/drbd_al
#!/usr/bin/perl
#%# family=auto
#%# capabilities=autoconf
# http://www.drbd.org/en/doc/users-guide-84/ch-admin#s-performance-indicators

use strict;
my $file="/proc/drbd";
my $store = {};
my $rid;

&crunch;
&display;

sub display{
  if ($ARGV[0] and $ARGV[0] eq "config"){
    print "graph_title DRBD (Activity Log)\n";
    print "graph_category DRBD\n";
    print "graph_info Graph DRBD (Activity Log)\n";
    print "graph_vlabel Graph DRBD (Activity Log)\n";
    print "graph_scale yes\n";
    print "graph_args --base 1024 --lower-limit 0\n";
    print "graph_period second\n";
    print "graph_height 200\n";
    print "graph_width 400\n";
    print "graph_printf %7.2lf\n";
    foreach my $key ( keys %$store ){
      my $drbdname = 'drbd'.$key;
      print $drbdname."al.label $drbdname Activity log\n";
      print $drbdname."al.min 0\n";
#      print $drbdname."al.type DERIVE\n";
    }
    exit 0;
  }
  foreach my $key ( keys %$store ){
    my $drbdname = 'drbd'.$key;
    print $drbdname."al.value ".$store->{$key}->{'al'}."\n";
  }
}

sub crunch{
  open (IN, $file ) || die "Could not open $file for reading: $!";
  if ($ARGV[0] and $ARGV[0] eq "autoconf"){
    close (IN);
    print "yes\n";
    exit 0;
  }
  while (<IN>){
    next if /version:|GIT-hash:/;
    chomp;
    my ($drbd) = $_ =~ /^\s+(\d):/;
    $rid = $drbd if $drbd =~ /\d/;
    my ($al) = $_ =~ /al:(\d*)/; $store->{ $rid }->{'al'} = $al if $al ne undef;
  }
  close (IN);
}

exit 0;
EOF
sudo chmod 755 /usr/share/munin/plugins/drbd_al



https://raw.githubusercontent.com/blog-pcoffice/public/master/drbd_ext

cat << 'EOF' | sudo tee /usr/share/munin/plugins/drbd_ext
#!/usr/bin/perl
#%# family=auto
#%# capabilities=autoconf
# http://www.drbd.org/en/doc/users-guide-84/ch-admin#s-performance-indicators

use strict;
my $file="/proc/drbd";
my $store = {};
my $rid;

&crunch;
&display;

sub display{
  if ($ARGV[0] and $ARGV[0] eq "config"){
    print "graph_title DRBD (Ext)\n";
    print "graph_category DRBD\n";
    print "graph_info Graph DRBD (Ext)\n";
    print "graph_vlabel Graph DRBD (Ext)\n";
    print "graph_scale yes\n";
    print "graph_args --base 1024 --lower-limit 0\n";
    print "graph_period second\n";
    print "graph_height 200\n";
    print "graph_width 400\n";
    print "graph_printf %7.2lf\n";
    foreach my $key ( keys %$store ){
      my $drbdname = 'drbd'.$key;
      print $drbdname."bm.label $drbdname Bit Map\n";
      print $drbdname."lo.label $drbdname Local count\n";
      print $drbdname."pe.label $drbdname Pending\n";
      print $drbdname."ua.label $drbdname UnAcknowledged\n";
      print $drbdname."ap.label $drbdname Application Pending\n";
      print $drbdname."ep.label $drbdname Epochs\n";
    }
    exit 0;
  }
  foreach my $key ( keys %$store ){
    my $drbdname = 'drbd'.$key;
    print $drbdname."bm.value ".$store->{$key}->{'bm'}."\n";
    print $drbdname."lo.value ".$store->{$key}->{'lo'}."\n";
    print $drbdname."pe.value ".$store->{$key}->{'pe'}."\n";
    print $drbdname."ua.value ".$store->{$key}->{'ua'}."\n";
    print $drbdname."ap.value ".$store->{$key}->{'ap'}."\n";
    print $drbdname."ep.value ".$store->{$key}->{'ep'}."\n";
  }
}

sub crunch{
  open (IN, $file ) || die "Could not open $file for reading: $!";
  if ($ARGV[0] and $ARGV[0] eq "autoconf"){
    close (IN);
    print "yes\n";
    exit 0;
  }
  while (<IN>){
    next if /version:|GIT-hash:/;
    chomp;
    my ($drbd) = $_ =~ /^\s+(\d):/;
    $rid = $drbd if $drbd =~ /\d/;
    my ($bm) = $_ =~ /bm:(\d*)/; $store->{ $rid }->{'bm'} = $bm if $bm ne undef;
    my ($lo) = $_ =~ /lo:(\d*)/; $store->{ $rid }->{'lo'} = $lo if $lo ne undef;
    my ($pe) = $_ =~ /pe:(\d*)/; $store->{ $rid }->{'pe'} = $pe if $pe ne undef;
    my ($ua) = $_ =~ /ua:(\d*)/; $store->{ $rid }->{'ua'} = $ua if $ua ne undef;
    my ($ap) = $_ =~ /ap:(\d*)/; $store->{ $rid }->{'ap'} = $ap if $ap ne undef;
    my ($ep) = $_ =~ /ep:(\d*)/; $store->{ $rid }->{'ep'} = $ep if $ep ne undef;
  }
  close (IN);
}

exit 0;
EOF
sudo chmod 755 /usr/share/munin/plugins/drbd_ext




0 件のコメント:

コメントを投稿