Prevents the script to run multiple instances using a pid file. This patch adds a new command line option -P to change the default pid file (/tmp/squid-analyzer.pid). Thanks to Gaetan Slongo for the patch.

This commit is contained in:
Darold Gilles 2014-02-28 15:45:41 +01:00
parent 62e1af750c
commit 0b6d1bc80d
2 changed files with 56 additions and 5 deletions

View File

@ -38,7 +38,7 @@ $BZCAT_PROG = "/bin/bzcat";
$RM_PROG = "/bin/rm"; $RM_PROG = "/bin/rm";
# DNS Cache # DNS Cache
my %CACHE = {}; my %CACHE = ();
# Color used to draw grpahs # Color used to draw grpahs
my @GRAPH_COLORS = ('#6e9dc9', '#f4ab3a', '#ac7fa8', '#8dbd0f'); my @GRAPH_COLORS = ('#6e9dc9', '#f4ab3a', '#ac7fa8', '#8dbd0f');
@ -695,11 +695,12 @@ sub _clear_stats
sub _init sub _init
{ {
my ($self, $conf_file, $log_file, $debug, $rebuild) = @_; my ($self, $conf_file, $log_file, $debug, $rebuild, $pidfile) = @_;
# Prevent for a call without instance # Prevent for a call without instance
if (!ref($self)) { if (!ref($self)) {
print STDERR "ERROR - init : Unable to call init without an object instance.\n"; print STDERR "ERROR - init : Unable to call init without an object instance.\n";
unlink("$pidfile");
exit(0); exit(0);
} }
@ -711,7 +712,7 @@ sub _init
$conf_file = 'squidanalyzer.conf'; $conf_file = 'squidanalyzer.conf';
} }
} }
my %options = &parse_config($conf_file, $log_file, $rebuild); my %options = $self->parse_config($conf_file, $log_file, $rebuild);
# Configuration options # Configuration options
$self->{MinPie} = $options{MinPie} || 2; $self->{MinPie} = $options{MinPie} || 2;
@ -732,6 +733,7 @@ sub _init
$self->{UseClientDNSName} = $options{UseClientDNSName} || 0; $self->{UseClientDNSName} = $options{UseClientDNSName} || 0;
$self->{DNSLookupTimeout} = $options{DNSLookupTimeout} || 0.0001; $self->{DNSLookupTimeout} = $options{DNSLookupTimeout} || 0.0001;
$self->{DNSLookupTimeout} = int($self->{DNSLookupTimeout} * 1000000); $self->{DNSLookupTimeout} = int($self->{DNSLookupTimeout} * 1000000);
$self->{pidfile} = $pidfile || '/tmp/squid-analyzer.pid';
if ($self->{Lang}) { if ($self->{Lang}) {
open(IN, "$self->{Lang}") or die "ERROR: can't open translation file $self->{Lang}, $!\n"; open(IN, "$self->{Lang}") or die "ERROR: can't open translation file $self->{Lang}, $!\n";
@ -1326,6 +1328,7 @@ sub _read_stat
} else { } else {
print STDERR "ERROR: bad format at line $i into $self->{Output}/$path/stat_user.dat:\n"; print STDERR "ERROR: bad format at line $i into $self->{Output}/$path/stat_user.dat:\n";
print STDERR "$l\n"; print STDERR "$l\n";
unlink($self->{pidfile});
exit 0; exit 0;
} }
$i++; $i++;
@ -1353,6 +1356,7 @@ sub _read_stat
} else { } else {
print STDERR "ERROR: bad format at line $i into $self->{Output}/$path/stat_user_url.dat\n"; print STDERR "ERROR: bad format at line $i into $self->{Output}/$path/stat_user_url.dat\n";
print STDERR "$l\n"; print STDERR "$l\n";
unlink($self->{pidfile});
exit 0; exit 0;
} }
$i++; $i++;
@ -1403,6 +1407,7 @@ sub _read_stat
} else { } else {
print STDERR "ERROR: bad format at line $i into $self->{Output}/$path/stat_network.dat\n"; print STDERR "ERROR: bad format at line $i into $self->{Output}/$path/stat_network.dat\n";
print STDERR "$l\n"; print STDERR "$l\n";
unlink($self->{pidfile});
exit 0; exit 0;
} }
$i++; $i++;
@ -1435,6 +1440,7 @@ sub _read_stat
} else { } else {
print STDERR "ERROR: bad format at line $i into $self->{Output}/$path/stat_netuser.dat\n"; print STDERR "ERROR: bad format at line $i into $self->{Output}/$path/stat_netuser.dat\n";
print STDERR "$l\n"; print STDERR "$l\n";
unlink($self->{pidfile});
exit 0; exit 0;
} }
$i++; $i++;
@ -1467,6 +1473,7 @@ sub _read_stat
} else { } else {
print STDERR "ERROR: bad format at line $i into $self->{Output}/$path/stat_code.dat\n"; print STDERR "ERROR: bad format at line $i into $self->{Output}/$path/stat_code.dat\n";
print STDERR "$l\n"; print STDERR "$l\n";
unlink($self->{pidfile});
exit 0; exit 0;
} }
$i++; $i++;
@ -1487,6 +1494,7 @@ sub _read_stat
} else { } else {
print STDERR "ERROR: bad format at line $i into $self->{Output}/$path/stat_mime_type.dat\n"; print STDERR "ERROR: bad format at line $i into $self->{Output}/$path/stat_mime_type.dat\n";
print STDERR "$l\n"; print STDERR "$l\n";
unlink($self->{pidfile});
exit 0; exit 0;
} }
$i++; $i++;
@ -3413,7 +3421,7 @@ sub _gen_summary
sub parse_config sub parse_config
{ {
my ($file, $log_file, $rebuild) = @_; my ($self, $file, $log_file, $rebuild) = @_;
die "FATAL: no configuration file!\n" if (!-e $file); die "FATAL: no configuration file!\n" if (!-e $file);
@ -3433,26 +3441,31 @@ sub parse_config
# Check config # Check config
if (!exists $opt{Output} || !-d $opt{Output}) { if (!exists $opt{Output} || !-d $opt{Output}) {
print STDERR "Error: you must give a valid output directory. See option: Output\n"; print STDERR "Error: you must give a valid output directory. See option: Output\n";
unlink($self->{pidfile});
exit 0; exit 0;
} }
if ( !$opt{LogFile} || !-f $opt{LogFile} ) { if ( !$opt{LogFile} || !-f $opt{LogFile} ) {
if (!$rebuild) { if (!$rebuild) {
print STDERR "Error: you must give a valid path to the Squid log file. See LogFile or option -l\n"; print STDERR "Error: you must give a valid path to the Squid log file. See LogFile or option -l\n";
unlink($self->{pidfile});
exit 0; exit 0;
} }
} }
if (exists $opt{DateFormat}) { if (exists $opt{DateFormat}) {
if ( ($opt{DateFormat} !~ m#\%y#) || (($opt{DateFormat} !~ m#\%m#) && ($opt{DateFormat} !~ m#\%M#) )|| ($opt{DateFormat} !~ m#\%d#) ) { if ( ($opt{DateFormat} !~ m#\%y#) || (($opt{DateFormat} !~ m#\%m#) && ($opt{DateFormat} !~ m#\%M#) )|| ($opt{DateFormat} !~ m#\%d#) ) {
print STDERR "Error: bad date format: $opt{DateFormat}, must have \%y, \%m or \%M, \%d. See DateFormat option.\n"; print STDERR "Error: bad date format: $opt{DateFormat}, must have \%y, \%m or \%M, \%d. See DateFormat option.\n";
unlink($self->{pidfile});
exit 0; exit 0;
} }
} }
if ($opt{Lang} && !-e $opt{Lang}) { if ($opt{Lang} && !-e $opt{Lang}) {
print STDERR "Error: can't find translation file $opt{Lang}. See option: Lang\n"; print STDERR "Error: can't find translation file $opt{Lang}. See option: Lang\n";
unlink($self->{pidfile});
exit 0; exit 0;
} }
if ($opt{ImgFormat} && !grep(/^$opt{ImgFormat}$/, 'png','jpg')) { if ($opt{ImgFormat} && !grep(/^$opt{ImgFormat}$/, 'png','jpg')) {
print STDERR "Error: unknown image format. See option: ImgFormat\n"; print STDERR "Error: unknown image format. See option: ImgFormat\n";
unlink($self->{pidfile});
exit 0; exit 0;
} }
return %opt; return %opt;

View File

@ -19,6 +19,8 @@ my $debug = 0;
my $version = 0; my $version = 0;
my $build_date = ''; my $build_date = '';
my $no_year_stat = 0; my $no_year_stat = 0;
my $pid_dir = '/tmp';
my $pidfile = 'squid-analyzer.pid';
# get the command line parameters # get the command line parameters
my $result = GetOptions ( my $result = GetOptions (
@ -29,6 +31,7 @@ my $result = GetOptions (
"l|logfile=s" => \$logfile, "l|logfile=s" => \$logfile,
"r|rebuild!" => \$rebuild, "r|rebuild!" => \$rebuild,
"p|preserve=i" => \$preserve, "p|preserve=i" => \$preserve,
"P|pid_dir=s" => \$pid_dir,
"v|version!" => \$version, "v|version!" => \$version,
"no-year-stat!" => \$no_year_stat, "no-year-stat!" => \$no_year_stat,
); );
@ -62,8 +65,38 @@ if ($help) {
exit; exit;
} }
# 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);
# Die cleanly on signal
sub terminate
{
# block signal
local $SIG{TERM} = 'IGNORE';
local $SIG{INT} = 'IGNORE';
local $SIG{QUIT} = 'IGNORE';
print("LOG: Received terminating signal.\n");
if (-e "$pid_dir/$pidfile") {
unlink("$pid_dir/$pidfile") or print("ERROR: Unable to remove pid file $pid_dir/$pidfile, $!\n");
}
exit 0;
}
# Die on kill -2, -3 or -15
$SIG{'INT'} = $SIG{'QUIT'} = $SIG{'TERM'} = 'terminate';
# Instanciate SquidAnalyzer.pm perl module # Instanciate SquidAnalyzer.pm perl module
my $sa = new SquidAnalyzer($configfile, $logfile, $debug, $rebuild); my $sa = new SquidAnalyzer($configfile, $logfile, $debug, $rebuild, "$pid_dir/$pidfile");
$sa->{no_year_stat} = $no_year_stat; $sa->{no_year_stat} = $no_year_stat;
@ -85,6 +118,9 @@ if ($rebuild) {
# Generate graphics and html # Generate graphics and html
$sa->buildHTML(); $sa->buildHTML();
# Remove PID file
unlink("$pid_dir/$pidfile");
exit(0); exit(0);
@ -103,6 +139,8 @@ Usage: squid-analyzer [ -c squidanalyzer.conf ] [-l logfile]
By default: /var/log/squid/access.log By default: /var/log/squid/access.log
-p | --preserve number : used to set the statistic obsolescence in -p | --preserve number : used to set the statistic obsolescence in
number of month. Older stats will be removed. number of month. Older stats will be removed.
-P | --pid_dir directory : set directory where pid file will be stored.
Default /tmp/
-r | --rebuild : use this option to rebuild all html and graphs -r | --rebuild : use this option to rebuild all html and graphs
output from all data files. output from all data files.
-v | version : show version and exit. -v | version : show version and exit.