2012-04-06 10:47:56 +02:00
|
|
|
#!/usr/bin/perl
|
|
|
|
#
|
|
|
|
# Perl frontend to SquidAnalyzer.pm.
|
|
|
|
#
|
|
|
|
use strict;
|
|
|
|
use SquidAnalyzer;
|
|
|
|
use Getopt::Long;
|
2014-08-11 15:44:53 +02:00
|
|
|
use Benchmark;
|
2014-08-14 22:06:22 +02:00
|
|
|
use POSIX ":sys_wait_h";
|
2012-04-06 10:47:56 +02:00
|
|
|
|
|
|
|
$| = 1;
|
|
|
|
|
|
|
|
my $DEFAULT_CONFFILE = '/etc/squidanalyzer/squidanalyzer.conf';
|
|
|
|
|
2013-01-29 12:19:07 +01:00
|
|
|
my $logfile = '';
|
2012-04-06 10:47:56 +02:00
|
|
|
my $configfile = '';
|
2013-01-29 12:19:07 +01:00
|
|
|
my $help = '';
|
|
|
|
my $rebuild = '';
|
|
|
|
my $preserve = '';
|
2013-01-29 12:33:13 +01:00
|
|
|
my $debug = 0;
|
|
|
|
my $version = 0;
|
2013-05-27 22:27:18 +02:00
|
|
|
my $build_date = '';
|
2013-05-29 01:03:58 +02:00
|
|
|
my $no_year_stat = 0;
|
2014-02-28 15:45:41 +01:00
|
|
|
my $pid_dir = '/tmp';
|
|
|
|
my $pidfile = 'squid-analyzer.pid';
|
2014-08-14 22:06:22 +02:00
|
|
|
my $queue_size = 0;
|
2014-08-11 15:44:53 +02:00
|
|
|
my $t0 = Benchmark->new;
|
2012-04-06 10:47:56 +02:00
|
|
|
|
|
|
|
# get the command line parameters
|
|
|
|
my $result = GetOptions (
|
|
|
|
"c|configfile=s" => \$configfile,
|
2013-05-27 22:27:18 +02:00
|
|
|
"b|build_date=s" => \$build_date,
|
2013-01-29 12:33:13 +01:00
|
|
|
"d|debug!" => \$debug,
|
2012-04-06 10:47:56 +02:00
|
|
|
"h|help" => \$help,
|
2014-08-14 22:06:22 +02:00
|
|
|
"j|jobs=i" => \$queue_size,
|
2013-01-29 12:19:07 +01:00
|
|
|
"l|logfile=s" => \$logfile,
|
2012-04-06 10:47:56 +02:00
|
|
|
"r|rebuild!" => \$rebuild,
|
2013-01-29 12:19:07 +01:00
|
|
|
"p|preserve=i" => \$preserve,
|
2014-02-28 15:45:41 +01:00
|
|
|
"P|pid_dir=s" => \$pid_dir,
|
2013-01-29 12:33:13 +01:00
|
|
|
"v|version!" => \$version,
|
2013-05-29 01:03:58 +02:00
|
|
|
"no-year-stat!" => \$no_year_stat,
|
2012-04-06 10:47:56 +02:00
|
|
|
);
|
|
|
|
|
2013-01-29 12:33:13 +01:00
|
|
|
# Show version and exit
|
|
|
|
if ($version) {
|
|
|
|
print "SquidAnalyzer version $SquidAnalyzer::VERSION\n";
|
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
|
2013-05-27 22:27:18 +02:00
|
|
|
if ($build_date) {
|
|
|
|
$rebuild = 1;
|
|
|
|
if ( ($build_date !~ /^\d{4}-\d{2}-\d{2}$/) && ($build_date !~ /^\d{4}-\d{2}$/) && ($build_date !~ /^\d{4}$/) ) {
|
|
|
|
die("FATAL: bad syntax for build_date, expecting format: yyyy-mm-dd, yyyy-mm or yyyy\n");
|
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-29 16:27:56 +02:00
|
|
|
# Look at configuration file
|
|
|
|
if (!$configfile) {
|
|
|
|
# Backward compatibility with release < 4.0 with configuration
|
|
|
|
# file as single argument.
|
|
|
|
$configfile = $ARGV[0] if (($#ARGV == 0) && $ARGV[0]);
|
|
|
|
|
|
|
|
# Set default configuration file
|
|
|
|
$configfile ||= $DEFAULT_CONFFILE;
|
2012-04-06 10:47:56 +02:00
|
|
|
}
|
|
|
|
|
2013-05-29 16:27:56 +02:00
|
|
|
if ($help) {
|
2012-04-06 10:47:56 +02:00
|
|
|
&usage;
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
2014-02-28 15:45:41 +01:00
|
|
|
# Check if an other process is already running
|
|
|
|
if (-e "$pid_dir/$pidfile") {
|
|
|
|
die "FATAL: pid file ($pid_dir/$pidfile) exists, an other squid-analalyzer process may still running.\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
# Write the pid file
|
|
|
|
open(OUT, ">$pid_dir/$pidfile") or die "FATAL: can not write to pid file $pid_dir/$pidfile, $!\n";
|
|
|
|
print OUT "$$";
|
|
|
|
close(OUT);
|
|
|
|
|
2014-08-14 22:06:22 +02:00
|
|
|
# Clear multiprocess temporary file if any
|
|
|
|
unlink("$pid_dir/last_parsed.tmp");
|
|
|
|
|
|
|
|
# Instanciate SquidAnalyzer.pm perl module
|
|
|
|
my $sa = new SquidAnalyzer($configfile, $logfile, $debug, $rebuild, $pid_dir, $pidfile);
|
|
|
|
$sa->{no_year_stat} = $no_year_stat;
|
|
|
|
$sa->{queue_size} = $queue_size;
|
|
|
|
|
2014-02-28 15:45:41 +01:00
|
|
|
# Die cleanly on signal
|
|
|
|
sub terminate
|
|
|
|
{
|
|
|
|
# block signal
|
|
|
|
local $SIG{TERM} = 'IGNORE';
|
|
|
|
local $SIG{INT} = 'IGNORE';
|
|
|
|
|
|
|
|
print("LOG: Received terminating signal.\n");
|
2014-08-14 22:06:22 +02:00
|
|
|
|
|
|
|
$sa->{terminate} = 1;
|
|
|
|
|
|
|
|
# Wait for all child processes to die except for the logger
|
|
|
|
my $kid = 0;
|
|
|
|
do {
|
|
|
|
sleep(1);
|
|
|
|
$kid = waitpid(-1, WNOHANG);
|
|
|
|
} while ($kid > 0);
|
|
|
|
|
|
|
|
# Removed pid iand temp file
|
2014-02-28 15:45:41 +01:00
|
|
|
if (-e "$pid_dir/$pidfile") {
|
|
|
|
unlink("$pid_dir/$pidfile") or print("ERROR: Unable to remove pid file $pid_dir/$pidfile, $!\n");
|
2014-08-14 22:06:22 +02:00
|
|
|
}
|
|
|
|
if (-e "$pid_dir/last_parsed.tmp") {
|
|
|
|
unlink("$pid_dir/last_parsed.tmp") or print("ERROR: Unable to remove temp file $pid_dir/last_parsed.tmp, $!\n");
|
2014-02-28 15:45:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
|
2014-08-14 22:06:22 +02:00
|
|
|
# Handle signals to die cleanly
|
|
|
|
$SIG{'INT'} = \&terminate;
|
|
|
|
$SIG{'TERM'} = \&terminate;
|
|
|
|
$SIG{'CHLD'} = 'DEFAULT';
|
2013-05-29 01:03:58 +02:00
|
|
|
|
2014-08-11 15:44:53 +02:00
|
|
|
my $t1;
|
2013-05-27 22:27:18 +02:00
|
|
|
# Run parsing only if we have a log file or that we are not in rebuild mode
|
2014-08-11 15:44:53 +02:00
|
|
|
if (!$rebuild || $logfile) {
|
|
|
|
$sa->parseFile();
|
|
|
|
$t1 = Benchmark->new;
|
|
|
|
my $td = timediff($t1, $t0);
|
|
|
|
print STDERR "DEBUG: the log statistics gathering took:", timestr($td), "\n";
|
|
|
|
}
|
2012-04-06 10:47:56 +02:00
|
|
|
|
2013-01-29 12:19:07 +01:00
|
|
|
# Remove old statistics
|
|
|
|
if ($preserve) {
|
|
|
|
$sa->{preserve} = $preserve;
|
|
|
|
}
|
|
|
|
|
2013-05-27 22:27:18 +02:00
|
|
|
# In rebuild mode history time is not use and we must store the
|
|
|
|
# specific rebuild date if any is provided at command line.
|
2012-04-06 10:47:56 +02:00
|
|
|
if ($rebuild) {
|
|
|
|
$sa->{history_time} = '';
|
2013-05-27 22:27:18 +02:00
|
|
|
$sa->{build_date} = $build_date;
|
2012-04-06 10:47:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Generate graphics and html
|
|
|
|
$sa->buildHTML();
|
2014-08-11 15:44:53 +02:00
|
|
|
my $t2 = Benchmark->new;
|
|
|
|
if (defined $t1) {
|
|
|
|
my $td = timediff($t2, $t1);
|
|
|
|
print STDERR "DEBUG: generating HTML output took:", timestr($td), "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
my $td = timediff($t2, $t0);
|
2014-08-14 22:06:22 +02:00
|
|
|
print STDERR "DEBUG: total execution time:", timestr($td), "\n";
|
2012-04-06 10:47:56 +02:00
|
|
|
|
2014-02-28 15:45:41 +01:00
|
|
|
# Remove PID file
|
|
|
|
unlink("$pid_dir/$pidfile");
|
|
|
|
|
2012-04-06 10:47:56 +02:00
|
|
|
exit(0);
|
|
|
|
|
|
|
|
|
|
|
|
sub usage
|
|
|
|
{
|
|
|
|
print qq{
|
|
|
|
Usage: squid-analyzer [ -c squidanalyzer.conf ] [-l logfile]
|
|
|
|
|
|
|
|
-c | --configfile filename : path to the SquidAnalyzer configuration file.
|
2014-02-14 11:41:52 +01:00
|
|
|
By default: $DEFAULT_CONFFILE
|
2013-05-27 22:27:18 +02:00
|
|
|
-b | --build_date date : set the date to be rebuilt, format: yyyy-mm-dd
|
|
|
|
or yyyy-mm or yyyy. Used with -r or --rebuild.
|
2013-01-29 12:33:13 +01:00
|
|
|
-d | --debug : show debug informations.
|
2013-01-29 12:19:07 +01:00
|
|
|
-h | --help : show this message and exit.
|
2014-08-14 22:38:14 +02:00
|
|
|
-j | --jobs number : number of jobs to run at same time. Default is 1,
|
2014-08-14 22:06:22 +02:00
|
|
|
run as single process.
|
2013-01-29 12:19:07 +01:00
|
|
|
-l | --logfile filename : path to the Squid logfile to parse.
|
|
|
|
By default: /var/log/squid/access.log
|
|
|
|
-p | --preserve number : used to set the statistic obsolescence in
|
|
|
|
number of month. Older stats will be removed.
|
2014-02-28 15:45:41 +01:00
|
|
|
-P | --pid_dir directory : set directory where pid file will be stored.
|
|
|
|
Default /tmp/
|
2012-04-06 10:47:56 +02:00
|
|
|
-r | --rebuild : use this option to rebuild all html and graphs
|
|
|
|
output from all data files.
|
2013-01-29 12:33:13 +01:00
|
|
|
-v | version : show version and exit.
|
2013-09-01 21:42:33 +02:00
|
|
|
--no-year-stat : disable years statistics, reports will start
|
|
|
|
from month level only.
|
2012-04-06 10:47:56 +02:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
|