#!/usr/bin/perl
#
#	usage:
#		mbmon-rrd.pl [host:port] <rrdfile>
#
#	description:
#		5分毎にcronから起動すると、mbmonの出力をrrdtoolのRRDファイルに
#		書き出す。
#
#		指定した<rrdfile>が存在しない場合は作成する。作成する際のRRDファ
#		イル中のデータソースは`mbmon -rc1`で出力されたタグ名(fan0等)を
#		辞書順にソートした順序となる。
#

use strict;
use RRDs;
use IO::Socket::INET;
use IO::File;

#  -----  default settings  -----

my $dbg   = 1;
my $usage = "usage: mbmon-rrd.pl [host:port] <rrdfile>\n";
my $peer  = '';

#  -----  argument check  -----
if ($#ARGV < 0) {
	print $usage;
	exit(1);
}
elsif ($#ARGV == 1) {
	$peer = shift;
}
my $rrdfile = shift;


#  -----  read status from mbmon  -----
my $status = read_status($peer);

#  -----  check and create rrdfile  -----
-e $rrdfile or create_rrd($rrdfile, $status);

#  -----  parse status  -----
update_rrd($status);

exit;

sub create_rrd()
{
	my($rrdfile, $status) = @_;
	my $e;

#	print "create_rrd(): \$rrdfile=\"$rrdfile\"\n" if $dbg;

	my @args = ($rrdfile);

	foreach (sort keys %$status) {
		push(@args, "DS:$_:GAUGE:600:U:U");
	}

	push(@args, qw(
		RRA:AVERAGE:0.5:1:600
		RRA:AVERAGE:0.5:6:700
		RRA:AVERAGE:0.5:24:775
		RRA:AVERAGE:0.5:288:797
		RRA:MAX:0.5:1:600
		RRA:MAX:0.5:6:700
		RRA:MAX:0.5:24:775
		RRA:MAX:0.5:288:797
		RRA:MIN:0.5:1:600
		RRA:MIN:0.5:6:700
		RRA:MIN:0.5:24:775
		RRA:MIN:0.5:288:797
		RRA:LAST:0.5:1:600
		RRA:LAST:0.5:6:700
		RRA:LAST:0.5:24:775
		RRA:LAST:0.5:288:797
	));

	print "create $rrdfile " . join(', ', @args) if $dbg;

	RRDs::create(@args);
	$e = RRDs::error() and die "ERROR: Cannot create database: $e\n"
}


sub read_status()
{
	my $peer = shift;
	my (%status, $key, $val, $fd);

	if ($peer) {
		$fd = IO::Socket::INET->new($peer) or
			die "ERROR: Cannot connect to $peer: $!\n";
	}
	else {
		$fd = IO::File->new("mbmon -rc1|") or
			die "ERROR: Cannot run mbmon: $!\n";
	}
	while($_ = $fd->getline) {
		next unless /^(\w[^:\s]+)\s*:\s*([+-]?[\d\.]+)/;
		$key = lc($1);
		$val = $2;
		$status{$key} = $val;
		print "\$status{$key} = \"$val\"\n" if $dbg;
	}
	$fd->close;
	return \%status;
}


sub update_rrd()
{
	my $status = shift;
	my (@ds, @val);
	my $e;

	foreach (sort keys %$status) {
		push(@ds, $_ );
		push(@val, $status->{$_} );
	}

	my $template = join(':', @ds);
	my $value    = join(':', 'N', @val);

	print "update template = '$template'\n"	if $dbg;
	print "update value    = '$value'\n"	if $dbg;

	RRDs::update($rrdfile, "--template", $template, $value);
	$e = RRDs::error() and die "ERROR Cannot update $rrdfile: $e\n";
}

