#!@@PERL@@ -w
# 
# Plugin to monitor individual interrupts
#
#%# family=auto
#%# capabilities=autoconf
use strict;

if (defined $ARGV[0] && $ARGV[0] eq 'autoconf') {
    if(-r '/proc/interrupts') {
	print "yes\n";
	exit(0);
    } else {
	print "no\n";
	exit(1);
    }
}
open my $in, '<', '/proc/interrupts'
  or die "Can't open /proc/interrupts: $!\n";

my @cpus = split(' ', <$in>);
my $cpus = scalar @cpus;
my $cpu;

if ($0 =~ /(?:.*\/)?irqstats_(.+)/) {
    $cpu = $1;
    if ($cpu > $#cpus) {
	die "Requested CPU $cpu out of bounds (0..$#cpus)\n";
    }
}
my @irqs;


sub sum (@) {
    my $sum = 0;
    $sum += $_ || 0 for @_;	# Avoid complaints about empty strings
    return $sum;
}

while (my $line = <$in>) {
    my ($irq, $label, $type);
    my @data = split(' ', $line, $cpus + 3);
    chomp @data;
    $irq = shift @data;
    next unless length $irq;
    chop $irq;
    if ($irq =~ /^\d+$/) {
	$label = pop @data;
	$type = pop @data;
    }
    # Skip non-per-cpu values for per-cpu stats
    next if defined($cpu) and $cpus > @data;
    push @irqs, {
		 irq => $irq,
		 label => $label,
		 count => defined($cpu) ? $data[$cpu] : sum(@data)
		};
}
close $in;

if (defined $ARGV[0] && $ARGV[0] eq 'config') {
    print 'graph_title Individual interrupts',
      defined($cpu) ? " on CPU $cpu\n" : "\n";
    print <<EOM;
graph_args --base 1000 -l 0;
graph_vlabel interrupts / \${graph_period}
graph_category system
EOM
    print join(' ', 'graph_order', map {"i" . $_->{irq}} @irqs), "\n";
    for my $irq (@irqs) {
	my $f = ($irq->{label} || $irq->{irq});
	$f = $irq->{irq} if (length ($f) > 47);
	print "i", $irq->{irq}, '.label ', $f, "\n";
	print "i", $irq->{irq}, '.info Interrupt ', $irq->{irq}, ', for device(s): ', $irq->{label}, "\n"
	  if $irq->{label};
	print "i", $irq->{irq}, ".type DERIVE\n";
	print "i", $irq->{irq}, ".min 0\n";
    }
} else {
    print "i", $_->{irq}, '.value ', $_->{count}, "\n" for @irqs;
}

