#!/usr/bin/perl

#
# 2010 Thomas Eckhardt (http://tafe.unkelhaeusser.net)
#
# check_cpufreq - Nagios plugin for nrpe
# log the cpu frequency 
#
# v0.1 - Quick&Dirty hack

use strict;

use constant {
	CPUSYSDIR => "/sys/devices/system/cpu/",
	FREQSUBDIR => "/cpufreq/"
};

my @powers = ( 'KHz', 'MHz', 'GHz', 'THz' );

my %CPUS = ();

sub errout {
   my ($code, $msg) = @_;
   print "UNKNOWN - $msg\n";
   exit($code);
}

sub readfile1stline {
   my $file = shift;
   if ( open (FH, '<', $file ) ) {
	my $myline = <FH> || &errout(2, 'Failed to read '.$file." => $!\n");
	close FH;
	chomp($myline);
	return $myline;
   } else {
	&errout(2, 'Failed to open '.$file." => $!\n");
   }
}

sub fetchcpuinfo {
   my $cpu = shift;
   if ( -f CPUSYSDIR.'cpu'.$cpu.FREQSUBDIR.'cpuinfo_cur_freq' ) {
	my $cur = &readfile1stline( CPUSYSDIR.'cpu'.$cpu.FREQSUBDIR.'cpuinfo_cur_freq' );
	my $min = &readfile1stline( CPUSYSDIR.'cpu'.$cpu.FREQSUBDIR.'cpuinfo_min_freq' );
	my $max = &readfile1stline( CPUSYSDIR.'cpu'.$cpu.FREQSUBDIR.'cpuinfo_max_freq' );
        return ($cur,$min,$max);
   } else {
	# error out, no cpufreq loaded - TODO: get freq from /proc/cpuinfo
	&errout(2, 'Kernel has no cpufreq loaded ..');
   }
}

if ( opendir(DH, CPUSYSDIR) ) {
   while( my $dir = readdir (DH) ) {
      if ( $dir =~ /^cpu(\d+)$/ && -d CPUSYSDIR.$dir ) {
	my $cpuno = $1;
	($CPUS{$cpuno}{'cur'}, $CPUS{$cpuno}{'min'}, $CPUS{$cpuno}{'max'}) = &fetchcpuinfo($cpuno);
	$CPUS{$cpuno}{'human'} = $CPUS{$cpuno}{'cur'};
	while ($CPUS{$cpuno}{'human'} >= 1000 && $CPUS{$cpuno}{'humanpower'} < $#powers ) {
	   $CPUS{$cpuno}{'human'} = $CPUS{$cpuno}{'human'} / 1000;
	   $CPUS{$cpuno}{'humanpower'} += 1;
	}
      }
   }
   close DH;
} else {
   &errout(1, 'Failed to open '.CPUSYSDIR." $! - Is /sys mounted?");
}

# response

my $perfdata = '';
my $response = '';
foreach my $key (sort keys %CPUS) {
  if ( $response ne '') { $response .= ', '; }
  if ( $response eq '') { $response = 'OK - CPU-Freq: '; }
  $response .= sprintf ("CPU%i: %3.2f%s", $key, $CPUS{$key}{'human'}, $powers[ $CPUS{$key}{'humanpower'} ] );

  if ( $perfdata ne '') { $perfdata .= ' '; }
  if ( $perfdata eq '') { $perfdata = ' | '; }
  $perfdata .= sprintf("'cpu%i'=%i;%i;%i" , $key, $CPUS{$key}{'cur'}, $CPUS{$key}{'min'}, $CPUS{$key}{'max'} );
}


print $response.$perfdata."\n";
exit(0);
