#!/usr/bin/perl 
#Author:
#	Otavio Honorio (otavio.honorio@opservices.com.br)
use strict;
use Getopt::Long;
use POSIX;
use File::Basename;
use DBI;
# Global variables
our %args = ();
$args{'path'} = "/usr/local/opmon/libexec";
$args{'name'} = basename($0, ".pl");
$args{'log'} = "$args{'path'}/$args{'name'}.log";
# Setting environment
$ENV{"USER"} = "opuser";
$ENV{"HOME"} = "/home/opuser";
#--------------------------------------------------------------------------------------
sub main {
	get::option();

	if ($args{'mode'} eq "perfdata") {
		my (@err, $code);
		$err[0] = perfdata_errors();
		$err[1] = files_found("perfdata");
		if (((metric($err[0])) == 0) and ((metric($err[1]) == 0))) { $code = 0
		}elsif (((metric($err[0])) == 1) or ((metric($err[1]) == 1))) { $code = 1
		}elsif (((metric($err[0])) == 2) or ((metric($err[1]) == 2))) { $code = 2
		}else{ quit("Unable to check.",3); }
		quit("Perfdata - Errors: ".$err[0]." / Files: ".$err[1]."|perfdata_errors=".$err[0].";".$args{'warning'}.";".$args{'critical'}.";0 perfdata_files=".$err[1].";".$args{'warning'}.";".$args{'critical'}.";0",$code);
	}

	if ($args{'mode'} eq "opstatus") {
		my (@err, $code);
		$err[0] = opstatus_errors();
		$err[1] = files_found("opstatus");
		if (((metric($err[0])) == 0) and ((metric($err[1]) == 0))) { $code = 0
		}elsif (((metric($err[0])) == 1) or ((metric($err[1]) == 1))) { $code = 1
		}elsif (((metric($err[0])) == 2) or ((metric($err[1]) == 2))) { $code = 2
		}else{ quit("Unable to check.",3); }
		quit("Opstatus - Errors: ".$err[0]." / Files: ".$err[1]."|opstatus_errors=".$err[0].";".$args{'warning'}.";".$args{'critical'}.";0 opstatus_files=".$err[1].";".$args{'warning'}.";".$args{'critical'}.";0",$code);
	}

	if ($args{'mode'} eq "opstatuspri") {
		my (@err, $code);
		$err[0] = opstatuspri_errors();
		$err[1] = files_found("opstatuspri");
		if (((metric($err[0])) == 0) and ((metric($err[1]) == 0))) { $code = 0
		}elsif (((metric($err[0])) == 1) or ((metric($err[1]) == 1))) { $code = 1
		}elsif (((metric($err[0])) == 2) or ((metric($err[1]) == 2))) { $code = 2
		}else{ quit("Unable to check.",3); }
		quit("Opstatuspri - Errors: ".$err[0]." / Files: ".$err[1]."|opstatuspri_errors=".$err[0].";".$args{'warning'}.";".$args{'critical'}.";0 opstatuspri_files=".$err[1].";".$args{'warning'}.";".$args{'critical'}.";0",$code);
	}

	if ($args{'mode'} eq "logrefresh") {
		my $err = log_refresh();
		if ($err) { quit($err,2);
		}else{ quit("Logs Updateds.",0); }
	}


	quit("This module (".$args{'mode'}.") does not exist.",3);
}
#--------------------------------------------------------------------------------------
sub log_refresh {
	my $code = 0;
	my $text = "Log(s) without refresh at 5 minutes - ";
	my $path = "/usr/local/opmon/var/";
	my %logs = ("opstatus.log" => $path."opstatus.log", "opmon.log" => $path."opmon.log", "perfdata.log" => $path."perfdata.log");
	for my $key (sort keys %logs) {
		if (-e $logs{$key}) {
			if ((time - (stat($logs{$key}))[8]) >= 300) {
				$text .= $key." ";
				$code = 2;
			}
		}
	}
	if ($code) { return $text
	}else{ return 0 }
}
#--------------------------------------------------------------------------------------
sub files_found {
	my $directory = shift;
	my $found = `/bin/ls -l /usr/local/opmon/var/$directory/ | grep -v total | wc -l`;
	chomp($found);
	return $found;
}
#--------------------------------------------------------------------------------------
sub opstatuspri_errors {
	my $log = "/usr/local/opmon/var/opstatuspri.errors";
        my $err = 0;
        if (-e $log) {
		quit("$log, with 2 Gb, need remove log.",2) if ((stat($log))[7] >= 2147483648); # log igual ou mair que 2GB
		open(FILE,"$log");
		my @arr = <FILE>;
                close(FILE);
		$err = scalar(@arr);
	}
	return $err;
}
#--------------------------------------------------------------------------------------
sub opstatus_errors {
	my $log = "/usr/local/opmon/var/opstatus.errors";
        my $err = 0;
        if (-e $log) {
		quit("$log, with 2 Gb, need remove log.",2) if ((stat($log))[7] >= 2147483648); # log igual ou mair que 2GB
		open(FILE,"$log");
		my @arr = <FILE>;
                close(FILE);
		$err = scalar(@arr);
	}
	return $err;
}
#--------------------------------------------------------------------------------------
sub perfdata_errors {
	my $log = "/usr/local/opmon/var/perfdata.errors";
	my $err = 0;
	if (-e $log) {
		quit("$log, with 2 Gb, need remove log.",2) if ((stat($log))[7] >= 2147483648); # log igual ou mair que 2GB
		my ($hash, $hash_ref);
                open(FILE,"$log");
		foreach (<FILE>) {
			if ($_ =~ /(\d+)\t(\d+)\t(\d+)\t(.+)/) {
				$hash_ref->{$2}->{$3}->{"date"} = $1;
				$hash_ref->{$2}->{$3}->{"message"} = $4;
			}
		}
		close(FILE);

		for my $h (sort keys %$hash_ref) {
			for my $s (sort keys %{$hash_ref->{$h}}) {
				$hash->{$hash_ref->{$h}->{$s}->{"date"}}->{$h}->{$s} = $hash_ref->{$h}->{$s}->{"message"};
				$err++;
			}
		}

		my $text;
		for my $t (sort keys %$hash) {
			for my $h (sort keys %{$hash->{$t}}) {
				for my $s (sort keys %{$hash->{$t}->{$h}}) {
					my ($host, $service) = base($h, $s);
					$text .= strftime('%d/%m/%Y %H:%M:%S',localtime($t)).":sp:".$host.":sp:".$service.":sp:".$hash->{$t}->{$h}->{$s}."\n";
				}
			}
		}

		open(FILE,">/usr/local/opmon/share/custom/perfdata_errors.log");
		print FILE "DATE:sp:HOST:sp:SERVICE:sp:MESSAGE\n".$text;
		close(FILE);
        }
	return $err;
}
#--------------------------------------------------------------------------------------
sub base {
	my $host = shift;
	my $service = shift;
	my ($user, $pass, $addr);
	open(FILE,"/usr/local/opmon/etc/db.php");
	while (<FILE>) {
		$user = $1 if ($_ =~ /\$DBUSER="(.+)";/);
		$pass = $1 if ($_ =~ /\$DBPASS="(.+)";/);
		$addr = $1 if ($_ =~ /\$DBHOST="(.+)";/);
	}
	close(FILE);
	my $dbh = DBI->connect("DBI:mysql:database=opcfg;host=".$addr,$user,$pass,{'RaiseError' => 1});
	my $sth = $dbh->prepare("select nagios_hosts.host_name, nagios_services.service_description from nagios_hosts, nagios_services where nagios_services.service_id = $service and nagios_hosts.host_id = $host");
	$sth->execute();
        ($host, $service) = $sth->fetchrow_array;
        $sth->finish();
        $dbh->disconnect();
        return $host, $service;
}
#--------------------------------------------------------------------------------------
sub metric {
	my $value = shift;
	if ($args{'critical'} >= $args{'warning'}) {
		if ($value >= $args{'critical'}) { return 2
		}elsif ($value >= $args{'warning'}) { return 1
		}elsif ($value < $args{'warning'}) { return 0
		}else{ quit("Unable to check.",3) }
	}else{
		if ($value <= $args{'critical'}) { return 2
		}elsif ($value <= $args{'warning'}) { return 1
		}elsif ($value > $args{'critical'}) { return 0
		}else{ quit("Unable to check.",3) }
	}
}
#--------------------------------------------------------------------------------------
sub quit {
	my $mgs = shift;
	my $code = shift;
	print $mgs,"\n";
	exit($code);
}
#--------------------------------------------------------------------------------------
sub get::option  {
	Getopt::Long::Configure('bundling');
	GetOptions(
		'h|help' => \$args{'help'},
		'v|verbose=i' => \$args{'verbose'},
		'w|warning=f' => \$args{'warning'},
		'c|critical=f' => \$args{'critical'},
		'm|mode=s' => \$args{'mode'},
		'H|hostname=s' => \$args{'hostname'},
		'S|servicedesc=s' => \$args{'servicedesc'},
        );

	for my $key ( keys %args ) {
		$args{$key} = 0 if (!$args{$key})
	}

	help() if ($args{'help'});

	if ((!defined$args{'warning'}) or (!defined$args{'critical'}) or (!$args{'mode'})) {
		print "Parameters setting:\n";
		for my $key (sort keys %args) {
			print "$key => $args{$key}\n";
		}
		help();
	}
}
#--------------------------------------------------------------------------------------
sub logger {
        my $msg = shift (@_);
        open(LOG, ">>$args{'log'}");
        printf LOG ($args{'date'}." -> ".$msg);
        close(LOG);
}
#--------------------------------------------------------------------------------------
sub help {
	print "
Usage: $args{'name'}.pl [OPTION]...
-h, --help
-v, --verbose
-w, --warning
	Default = 0
-c, --critical
	Default = 0
-m, --mode
	checks whether the log file and displays the amount of services with errors insertion in the database.
	checks for files within the directory waiting to be processed.
	perfdata
	opstatus
	opstatuspri
	
";

exit;
}
#--------------------------------------------------------------------------------------
&main;
