use strict;
use warnings;

# Change following lines according to your server
# -----------------------------------------------
my $ERRLOG = '/var/log/apache/error.log';
my $ACCLOG = '/var/log/apache/access.log';
# -----------------------------------------------
# nothing needs to be changed below

my %Names = (    # short description of errorcodes
"300","Multiple Choices",
"301","Moved",
"302","Temporarily Moved",
"303","Method",
"304","Not Modified",
"305","Use Proxy",
"307","Temporary Redirect",
"400","Bad Request",
"401","Unauthorized",
"402","Payment Required",
"403","Forbidden",
"404","Not Found",
"405","Method Not Allowed",
"406","Not Acceptable",
"407","Proxy Authentication Required",
"408","Request Timeout",
"409","Conflict",
"410","Gone",
"411","Length Required",
"412","Precondition Failed",
"413","Request Entity Too Large",
"414","Request-URI Too Long",
"415","Unsupported Media Type",
"416","Requested Range Not Satisfiable",
"417","Expectation Failed",
"500","Internal Error",
"501","Not Implemented",
"502","Bad Gateway",
"503","Service Unavailable",
"504","Gateway Timeout",
"505","HTTP Version Not Supported");

my %Errors = ();   # key=errormessage, value=count 
my $Error = '';
my $Count = 0;     # Fehlerzaehler	
my $Total = 0;     # Gesamtsumme
my $Percent = 0;   # in Prozent

# Output format
format STDOUT =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>   @##.#
$Error $Count $Percent
.

# erst einmal das Logfile komplett duchsuchen
open DAT, "$ACCLOG" or die "Cannot open $ACCLOG";
while(<DAT>)
  {
  chomp($_);
  $_ =~ s|^.*HTTP/1.." ||;  # delete all before the error message
  $_ =~ s| .*$||;           # delete all behind the error message
  if ($_ =~ /^[345]/)       # only 3xx, 4xx, 5xx
    {
    if(defined($Errors{$_})) { $Errors{$_}++; }
    else                     { $Errors{$_} = 1; }
    }
  }
close DAT;

open DAT, "$ERRLOG" or die "Cannot open $ERRLOG";
while(<DAT>)
  {
  chomp($_);
  if ($_ =~ /\[error\]/) # nur Fehlermeldungen bearbeiten
    {
    $_ =~ s/^.*\] //;    # alles vor der Fehlermeldung loeschen
    $_ =~ s/:.*$//;      # alles nach der Fehlermeldung loeschen
    if(defined($Errors{$_})) { $Errors{$_}++; }
    else                     { $Errors{$_} = 1; }
    }
  }
close DAT;

# Summe berechnen
$Total = 0;
foreach $Error(keys %Errors)
  { $Total = $Total + $Errors{$Error}; }

# huebsche Ausgabe erzeugen
print "\nError Check - summarizes access_log and error_log\n\n";
print "---------------------------------------------------------\n";
print "Error Message                          Occurrences     %\n";
print "---------------------------------------------------------\n";
foreach $Error(sort(keys %Errors))
  {
  $Count = $Errors{$Error};
  $Percent = ($Errors{$Error}*100)/$Total;
  # add explanation to error numbers
  if ($Error =~ /^[345]/)
    { $Error = $Error . ' ' . $Names{$Error}; }
  write;
  }
print "---------------------------------------------------------\n";
printf("Total                                     %7d     100\n",$Total);
print "---------------------------------------------------------\n";

