#!/usr/bin/perl

#
# By Cyril Menigoz
# cyril.menigoz@gmail.com
#







#date --date "1 hour ago"



# imports
use strict;
use Nagios::Plugin;
use List::Util qw(first);
use DateTime;
# variables
my $shinken;
my $website;
my $comSite="";
my $accessFile="/var/log/apache2/access.log";
my $warn ;
my $crit;
my $dateTmp;
my @accessValues=();
my $statut;
my $message;
my @graphDelay=("30 minute","1 hour","3 hour","1 day ");
my @date=();
my @Ip=();
my @NIp=();
my $delayT;
my $dateExtrac;
my $duration;
my %mon2num = qw(  Jan 1 Feb 2  Mar 3  Apr 4  May 5  Jun 6  Jul 7  Aug 8  Sep 9  Oct 10 Nov 11 Dec 12);


my $APACHE2=q{([\d.]+)[-\s]+\[(\w+)/(\w+)/(\d+)[\d+:](\d+)[:](\d+)[:](\d+)\s\+\d+\] "[A-Z]+ /(\S+).* [\S+].*}; 
my $dateReg=q{(\d+)[-](\d+)[-](\d+)[\s](\d+)[:](\d+)[:](\d+)};
my ($ip,$day,$month,$year,$hour,$minute,$second,$page);
my ($year,$month,$day,$hour,$minute,$second);



# plugin setup
$shinken = Nagios::Plugin->new(
        plugin                   => 'check_apache_access',
        shortname        => 'Access activity ',
        version                => '1.0',
        usage                   => 'Usage: %s  -w <warning >  -c <critical >  -i <times intervals>  [ -W <website pages(s)> , -I <IP checked> ,-N <IP ignored>, - f <access.log file>]'  ,
        blurb                    => 'This plugin checks the web access to your server activity using apache log file ',
        license                 => 'This nagios plugin is free software, and comes with ABSOLUTELY no WARRANTY!'
);



                          

$shinken->add_arg(spec => 'delay|i=s',
                          help => "how many access since X . Default value : 1_hour . \n \t  value must be number_[minute,hour,day]
\tWARNING : since this program use the apache access files a too long delay MAY give false data because of the compressed and rotated files 
\tExemple \" check access.pl -C web  -i 90_minute \" will check the number of access to the apache2 server since 1.30 hour ",
                          required => 1);

$shinken->add_arg(spec => 'website|W=s',
                          help => "website page to monitor, at least a part of it.",
                          required => 0);

$shinken->add_arg(spec => 'IP|I=s',
                          help => "Ip which you want to monitor  , can be a list separed by comma \n \t Exemple \" check_access.pl -C web -I 198.15.45.98 \" will count the number of access to the apache2 server from 198.15.45.98 ",
                          required => 0);
                          
$shinken->add_arg(spec => 'NIP|N=s',
                          help => "Ip which you want to  ignore, can be a list separed by comma \n \t Exemple \" check_access.pl -C web -N 127.0.0.1 \" will count the number of access to the apache2 server from all host except 127.0.0.1 ",
                          required => 0);

$shinken->add_arg(spec => 'file|f=s',
                          help => " full path to the access log .Default /var/log/apache/access.log ",
                          required => 0);
                          
$shinken->add_arg(spec => 'warning|w=s',
                          help => "Warning threshold  ",
                          required => 1);
$shinken->add_arg(spec => 'critical|c=s',
                          help => "Critical threshold ",
                          required => 1);                          
               

# main
$shinken->getopts;

$warn = $shinken->opts->warning;
$crit = $shinken->opts->critical;
	  



	  if (defined ($shinken->opts->website))
	  {
	
		    $website  =$shinken->opts->website; 
		    $website=~s/\./\\\./;
		    $website=~s/\+/\\\+/;
		    $website=~s/\*/\\\*/;
		      
	  }

	  if (defined ($shinken->opts->file))
	  {	
		    $accessFile =$shinken->opts->file;
		    
	  }


	  if (defined ($shinken->opts->IP))
	  {
		    @Ip  =split (',',$shinken->opts->IP); 
	  }
	    if (defined ($shinken->opts->NIP))
	  {
		    @NIp  =split (',',$shinken->opts->NIP); 
	  }
        
	 
$delayT =$shinken->opts->delay;
$delayT =~ tr/_/ /;
my @tmp=split('_',$shinken->opts->delay);


$dateExtrac=`LANG=en_us date -d "$delayT ago" +%F" "%T`;
$dateExtrac=~$dateReg;
($year,$month,$day,$hour,$minute,$second)=($1, $2, $3, $4, $5, $6);
@date[0]= DateTime->new( year =>$year,
            month      => $month,
            day        	=> $day,
            hour        	=> $hour,
            minute     => $minute,
            second     => $second);
	
	  
	  @accessValues[0]=0;

	  for(my $i=0;$i<scalar(@graphDelay);$i++)
	  {
		  
		    $dateExtrac=`LANG=en_us date -d "@graphDelay[$i] ago" +%F" "%T`;
		    $dateExtrac=~$dateReg;
		    ($year,$month,$day,$hour,$minute,$second)=($1, $2, $3, $4, $5, $6);
		    @date[$i+1]= DateTime->new( year =>$year,
                          month    	 => $month,
                          day       	 => $day,
                          hour    	 => $hour,
                          minute     	 => $minute,
                          second     	 => $second);
                 
                 @accessValues[$i+1]=0;  
	  }
	  
=for comment  
	  print  "\n accessValues[0]->". @accessValues[0];
	  print  "\n accessValues[1]->". @accessValues[1];
	  print  "\n accessValues[2]->". @accessValues[2];
	  print  "\n accessValues[3]->". @accessValues[3];
	  print  "\n accessValues[4]->". @accessValues[4]."\n";
	  
=cut

	  open (Fichier, $accessFile) or die "Can't read $accessFile\n";

	  while (my $ligne = <Fichier>){
		if ($ligne =~ $APACHE2)
		{
			($ip,$day,$month,$year,$hour,$minute,$second,$page) = ($1, $2, $3, $4, $5, $6, $7, $8);
			
			$mon2num{$month};
			
			$dateTmp=  DateTime->new( year =>$year,
			      month      => $mon2num{$month},
			      day        => $day,
			      hour       => $hour,
			      minute     => $minute,
			      second     => $second);
		    }
		else
		{
		}
		#elsif ($ligne =~ $IIS){             => pour lighthttpd?
	#		($year,$month,$day,$ip,$method,$page,$ret_code,$byte,$user_a,$referer) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);
	#}

	
	
		if ((@date[0]<$dateTmp)&&(($ip~~@Ip)||scalar(@Ip)==0)&&!($ip~~@NIp)&&(($page=~/.*$website.*/)||!defined($website)))
		{
			@accessValues[0]++;
		}
		
		if ((@date[4]<$dateTmp)&&(($ip~~@Ip)||scalar(@Ip)==0)&&!($ip~~@NIp)&&(($page=~/.*$website.*/)||!defined($website)))
		{
			if ((@date[3]<$dateTmp)&&(($ip~~@Ip)||scalar(@Ip)==0)&&!($ip~~@NIp)&&(($page=~/.*$website.*/)||!defined($website)))
			{
				if ((@date[2]<$dateTmp)&&(($ip~~@Ip)||scalar(@Ip)==0)&&!($ip~~@NIp)&&(($page=~/.*$website.*/)||!defined($website)))
			      {
					if ((@date[1]<$dateTmp)&&(($ip~~@Ip)||scalar(@Ip)==0)&&!($ip~~@NIp)&&(($page=~/.*$website.*/)||!defined($website)))
					{	
						  @accessValues[1]++;
					}
					@accessValues[2]++;
				}
				@accessValues[3]++;
			 }
			 @accessValues[4]++;
		}
		
}
=for comment
	  print  "\naccessValues[0]=>". @accessValues[0];
	  print  "\naccessValues[1]=>". @accessValues[1];
	  print  "\naccessValues[2]=>". @accessValues[2];
	  print  "\naccessValues[3]=>". @accessValues[3];
	  print  "\naccessValues[4]=>". @accessValues[4];

=cut
		    $statut = $shinken->check_threshold
		    (
			      check => @accessValues[0],
			      warning =>$warn,
			      critical => $crit,
		    );
		    $message = @accessValues[0]. " Web access for ".$delayT ;



#Web
$shinken->add_perfdata(
	  label => "Web access for the ".$delayT,
	  value => @accessValues[0],
	  );
$shinken->add_perfdata(
        label => "Web access for  30 minutes",
        value => @accessValues[1],
);
$shinken->add_perfdata(
        label => "Web access for one hour ",
        value => @accessValues[2],
);
$shinken->add_perfdata(
        label => "Web access for 3 hours",
        value => @accessValues[3],
);
$shinken->add_perfdata(
        label => "Web access for 24 hours",
        value => @accessValues[4],
);

$shinken->nagios_exit($statut, $message);




