#! /usr/bin/perl
# anders@fupp.met, 2008-02-16
# graph number of syscalls and context switches in FreeBSD, parsing output from
# vmstat command
#
# link this script to either vm_faults or vm_cpu in munin plugins dir

my $name = $0;
# Remove extra chars
$name =~ s@^.*?(\w+)$@\1@;
# Remove base name for plugin
$name =~ s@^vm_@@;

sub printvalues {
	# Get the values from the vmstat command
	my $i = 0;
	open(VMSTAT, "vmstat -c 2 1 |");
	while(<VMSTAT>) {
		if (/^\s*r\s+b\s+w/) {
			# the labels we are looking for
			$labelstr = $_;
			$labelstr =~ s@^\s+@@;
			@labels = split(/\s+/, $labelstr);
			$i++;
		} elsif (/^\s*\d+\s+\d+\s+\d+\s+/) {
			if ($i < 2) {
				# Too early, spin another round
				$i++;
				next;
			} else {
				# the values we are looking for
				$valstr = $_;
				$valstr =~ s@^\s+@@;
				@values = split(/\s+/, $valstr);
				last;
			}
		}
	}
	close(VMSTAT);

	# Put the labels/values in hashes for easy lookup
	for ($i=0; $i<=$#labels; $i++) {
		$l = $labels[$i];

		if ($l eq "in") {
			# interrupts
			$faults{"$l"} = $values[$i];

			# syscalls
			$i++;
			$l = $labels[$i];
			$faults{"$l"} = $values[$i];

			# context switches
			$i++;
			$l = $labels[$i];
			$faults{"$l"} = $values[$i];
		} elsif ($l eq "us") {
			# userspace
			$cpu{"$l"} = $values[$i];

			# system time
			$i++;
			$l = $labels[$i];
			$cpu{"$l"} = $values[$i];

			# idle time
			$i++;
			$l = $labels[$i];
			$cpu{"$l"} = $values[$i];
		}
	}

	# Print values from the appropriate hash
	if ($name eq "faults") {
		foreach $key (keys %faults) {
			print "$key.value " . $faults{"$key"} . "\n";
		}
	} elsif ($name eq "cpu") {
		foreach $key (keys %cpu) {
			print "$key.value " . $cpu{"$key"} . "\n";
		}
	}
}

sub printconfig {
	if ($name eq "faults") {
		print "graph_title VM faults\n";
		print "graph_vlabel n\n";
		print "graph_category system\n";
		print "graph_info This graph shows the number of VM faults, as an average per second over the last 5 seconds.\n";

		print "in.label interrupts\n";
		print "in.type GAUGE\n";
		print "in.graph yes\n";
		print "in.draw AREA\n";

		print "sy.label syscalls\n";
		print "sy.type GAUGE\n";
		print "sy.graph yes\n";
		print "sy.draw STACK\n";

		print "cs.label cswitches\n";
		print "cs.type GAUGE\n";
		print "cs.graph yes\n";
		print "cs.draw STACK\n";
	} elsif ($name eq "cpu") {
		print "graph_title VM CPU time\n";
		print "graph_vlabel %\n";
		print "graph_category system\n";
		print "graph_info This graph shows the breakdown of percentage of CPU time.\n";

		print "us.label user\n";
		print "us.type GAUGE\n";
		print "us.graph yes\n";
		print "us.draw AREA\n";

		print "sy.label system\n";
		print "sy.type GAUGE\n";
		print "sy.graph yes\n";
		print "sy.draw STACK\n";

		print "id.label idle\n";
		print "id.type GAUGE\n";
		print "id.graph yes\n";
		print "id.draw STACK\n";
	}
}

if ($ARGV[0] eq "autoconf") {
	print "yes\n";
} elsif ($ARGV[0] eq "config") {
	printconfig;
} else {
	printvalues;
}
