#!/usr/bin/perl
# errlogstats v1.0  (c) 5.4.2017 by Andreas Ley  (u) 5.4.2017
# Statistics on error log entries

# The script itself may use utf-8 encoded identifiers and literals
use utf8;
# Latin-1 codepoints are considered characters
use feature 'unicode_strings';
use locale;
# Enable UTF-8 encoding for all files (but not already open handles)
use open ':encoding(utf8)';
use strict 'refs';

use Getopt::Long;
#use File::Basename;
use File::Spec::Functions;

use Term::Cap;
use Data::Dumper;
$Data::Dumper::Indent = 1;
$Data::Dumper::Terse = 1;
$Data::Dumper::Sortkeys = 1;
#warn Data::Dumper->Dump([\%hash],['*hash']) if ($opt_debug>0);

$root = '/var/www';

sub usage
{
	my $image = $0;
	$image =~ s!.*/!!;
	print  STDERR  "Usage: $image [options] [vhost [...]]\n";
	print  STDERR  "-v, --verbose	Verbose mode\n";
	print  STDERR  "If no vhost is specified, all vhosts are analyzed\n";
	exit(1);
}

@_ = @ARGV;
$Getopt::Long::ignorecase = 0;
GetOptions ('debug|D:s','help|h','trace|x','verbose|v','dry-run|n');
exec($^X,'-d:Trace',$0,@_) if (defined($opt_trace) && !defined($Devel::Trace::TRACE));

&usage if (defined($opt_help));

if (defined($opt_verbose) || defined($opt_debug)) {
	$|=1;
	select((select(STDERR),$|=1)[0]);
}

sub debug
{
	my $file = shift;
	my $line = shift;
	my $prefix = defined($debug{'path'})?$file:defined($debug{'file'})?basename($file):'';
	if (defined($debug{'line'})) {
		$prefix .= ':' if (length($prefix));
		$prefix .= $line;
	}
	$prefix .= '  ' if (length($prefix));
	warn $prefix.(scalar(@_)>1 ? join(', ',map("\"$_\"",@_))."\n" : "@_\n");
}

if (defined($opt_debug)) {
	for (split(',',$opt_debug)) {
		if (/=/) {
			$debug{$`} = $';
		}
		else {
			$debug{$_} = 1;
		}
	}
	&debug(__FILE__,__LINE__,'%debug = '.Data::Dumper->Dump([\%debug],['*debug'])) if ($debug{'debug'}>0);
	my $term = Tgetent Term::Cap { 'OSPEED'=>9600 };
	$on = $term->Tputs('md');
	$off = $term->Tputs('me');
}

# Enable UTF-8 encoding for already open handles
# ":utf8" would enable perl native coding which happens to be UTF-8 only on ASCII platforms
binmode(STDIN,':encoding(utf8)');
binmode(STDOUT,':encoding(utf8)');
binmode(STDERR,':encoding(utf8)');

my $columns = $ENV{'COLUMNS'} // 80 if (defined($opt_verbose));

if (@ARGV) {
	&read_errlog($_) for (@ARGV);
}
else {
	opendir(ROOT,$root) || die "Can't opendir $root: $!\n";
	while ($vhost = readdir(ROOT)) {
		next if ($vhost =~ /^\.\.?$/ || $vhost !~ /\./);
		&read_errlog($vhost);
	}
	closedir(ROOT);
}

sub read_errlog
{
	my ($vhost) = @_;

	my $errlog = catfile($root,$vhost,'log','error.log');
	if (!open(ERRLOG,$errlog)) {
		#warn "Can't read $errlog: $!\n";
		return;
	}

	while (<ERRLOG>) {
		warn "$.: $_" if ($debug{'file'}>0);
		if (/Permission denied/) {
			$eperm{$vhost}++;
			$eperm_msg{$vhost} .= $_ if (defined($opt_verbose));
		}
	}
	close(ERRLOG);
}

for my $vhost (sort { $eperm{$a} <=> $eperm{$b} } keys %eperm) {
	print "\n",'*' x $columns,"\n***\n***\t" if (defined($opt_verbose));
	print $eperm{$vhost},"\t",$vhost,"\n";
	print "***\n" if (defined($opt_verbose));
	print $eperm_msg{$vhost} if (defined($opt_verbose));
}
