X-Git-Url: https://code.th-h.de/?p=usenet%2Fnewsstats.git;a=blobdiff_plain;f=feedlog.pl;h=636de83d74c510187a2e6efc5633d4fab1ac2fae;hp=61311ac35d83c063c899c514b900e676d67ae5fc;hb=36cffe7aedd7e7efa2bcffc6b993240c89f5b51a;hpb=76ead5f97bbc730e39d50d188aa11eb6fc7dcffb diff --git a/feedlog.pl b/feedlog.pl index 61311ac..636de83 100755 --- a/feedlog.pl +++ b/feedlog.pl @@ -7,7 +7,7 @@ # # It is part of the NewsStats package. # -# Copyright (c) 2010 Thomas Hochstein +# Copyright (c) 2010-2012 Thomas Hochstein # # It can be redistributed and/or modified under the same terms under # which Perl itself is published. @@ -25,26 +25,63 @@ use Sys::Syslog qw(:standard :macros); use Date::Format; use DBI; +use Getopt::Long qw(GetOptions); +Getopt::Long::config ('bundling'); + +################################# Subroutines ################################## + +sub PrepareDB { +### initialise database connection, prepare statement +### and catch errors +### IN : \%Conf : reference to configuration hash +### OUT: $DBHandle: database handle +### $DBQuery : prepared statement + our ($DBHandle, $DBQuery, $OptQuiet); + my ($ConfigR) = @_; + my %Conf = %$ConfigR; + # drop current database connection - hard, if necessary + if ($DBHandle) { + $DBHandle->disconnect; + undef $DBHandle; + }; + # connect to database; try again every 5 seconds + while (!$DBHandle) { + $DBHandle = InitDB($ConfigR,0); + if (!$DBHandle) { + syslog(LOG_CRIT, 'Database connection failed: %s', $DBI::errstr); + sleep(5); + } else {; + syslog(LOG_NOTICE, "Database connection (re-)established successfully.") if !$OptQuiet; + } + }; + $DBQuery = $DBHandle->prepare(sprintf("INSERT INTO %s.%s (day,date,mid, + timestamp,token,size,peer,path, + newsgroups,headers) + VALUES (?,?,?,?,?,?,?,?,?,?)", + $Conf{'DBDatabase'}, + $Conf{'DBTableRaw'})); + return ($DBHandle,$DBQuery); +} + ################################# Main program ################################# ### read commandline options -my %Options = &ReadOptions('qd'); +my ($OptDebug,$OptQuiet); +GetOptions ('d|debug!' => \$OptDebug, + 'q|test!' => \$OptQuiet, + 'h|help' => \&ShowPOD, + 'V|version' => \&ShowVersion) or exit 1; ### read configuration -my %Conf = %{ReadConfig('newsstats.conf')}; +my %Conf = %{ReadConfig($HomePath.'/newsstats.conf')}; ### init syslog -openlog($MySelf, 'nofatal,pid', LOG_NEWS); -syslog(LOG_NOTICE, "$MyVersion starting up.") if !$Options{'q'}; +openlog($0, 'nofatal,pid', LOG_NEWS); +syslog(LOG_NOTICE, "$MyVersion starting up.") if !$OptQuiet; ### init database -my $DBHandle = InitDB(\%Conf,0); -if (!$DBHandle) { - syslog(LOG_CRIT, 'Database connection failed: %s', $DBI::errstr); - while (1) {}; # go into endless loop to suppress further errors and respawning -}; -my $DBQuery = $DBHandle->prepare(sprintf("INSERT INTO %s.%s (day,date,mid,timestamp,token,size,peer,path,newsgroups,headers) VALUES (?,?,?,?,?,?,?,?,?,?)",$Conf{'DBDatabase'},$Conf{'DBTableRaw'})); +my ($DBHandle,$DBQuery) = PrepareDB(\%Conf); ### main loop while (<>) { @@ -72,17 +109,35 @@ while (<>) { my $Date = time2str("%Y-%m-%d %H:%M:%S", $Timestamp); # write to database - if (!$DBQuery->execute($Day, $Date, $Mid, $Timestamp, $Token, $Size, $Peer, $Path, $Newsgroups, $Headers)) { - syslog(LOG_ERR, 'Database error: %s', $DBI::errstr); + if (!$DBQuery->execute($Day, $Date, $Mid, $Timestamp, $Token, $Size, $Peer, + $Path, $Newsgroups, $Headers)) { + syslog(LOG_ERR, 'Database error %s while processing %s: %s', + $DBI::err, $Mid, $DBI::errstr); + # if "MySQL server has gone away", try to recover + if ($DBI::err == 2006) { + # try to reconnect to database + ($DBHandle,$DBQuery) = PrepareDB(\%Conf); + # try to repeat the write attempt as before + if (!$DBQuery->execute($Day, $Date, $Mid, $Timestamp, $Token, $Size, $Peer, + $Path, $Newsgroups, $Headers)) { + syslog(LOG_ERR, '%s was dropped and lost.',$Mid); + }; + # otherwise log missing posting + } else { + syslog(LOG_ERR, '%s was dropped and lost.',$Mid); + }; }; $DBQuery->finish; - warn sprintf("-----\nDay: %s\nDate: %s\nMID: %s\nTS: %s\nToken: %s\nSize: %s\nPeer: %s\nPath: %s\nNewsgroups: %s\nHeaders: %s\n",$Day, $Date, $Mid, $Timestamp, $Token, $Size, $Peer, $Path, $Newsgroups, $Headers) if $Options{'d'}; + warn sprintf("-----\nDay: %s\nDate: %s\nMID: %s\nTS: %s\nToken: %s\n". + "Size: %s\nPeer: %s\nPath: %s\nNewsgroups: %s\nHeaders: %s\n", + $Day, $Date, $Mid, $Timestamp, $Token, $Size, $Peer, $Path, + $Newsgroups, $Headers) if $OptDebug; } ### close handles $DBHandle->disconnect; -syslog(LOG_NOTICE, "$MySelf closing down.") if !$Options{'q'}; +syslog(LOG_NOTICE, "$0 closing down.") if !$OptQuiet; closelog(); __END__ @@ -99,23 +154,7 @@ B [B<-Vhdq>] =head1 REQUIREMENTS -See doc/README: Perl 5.8.x itself and the following modules from CPAN: - -=over 2 - -=item - - -Config::Auto - -=item - - -Date::Format - -=item - - -DBI - -=back +See L. =head1 DESCRIPTION @@ -131,29 +170,29 @@ terminating would only result in a rapid respawn. =head2 Configuration -F will read its configuration from F which +B will read its configuration from F which should be present in the same directory via Config::Auto. -See doc/INSTALL for an overview of possible configuration options. +See L for an overview of possible configuration options. =head1 OPTIONS =over 3 -=item B<-V> (version) +=item B<-V>, B<--version> -Print out version and copyright information on B and exit. +Print out version and copyright information and exit. -=item B<-h> (help) +=item B<-h>, B<--help> Print this man page and exit. -=item B<-d> (debug) +=item B<-d>, B<--debug> Output debugging information to STDERR while parsing STDIN. You'll find that information most probably in your B F file. -=item B<-q> (quiet) +=item B<-q>, B<--quiet> Suppress logging to syslog. @@ -161,7 +200,7 @@ Suppress logging to syslog. =head1 INSTALLATION -See doc/INSTALL. +See L =head1 EXAMPLES @@ -172,7 +211,7 @@ Set up a feed like that in your B F file: :!*,de.* :Tc,WmtfbsPNH,Ac:/path/to/feedlog.pl -See doc/INSTALL for further information. +See L for further information. =head1 FILES @@ -188,7 +227,7 @@ Library functions for the NewsStats package. =item F -Runtime configuration file for B. +Runtime configuration file. =back @@ -203,11 +242,11 @@ bug tracker at L! =item - -doc/README +L =item - -doc/INSTALL +L =back @@ -219,7 +258,7 @@ Thomas Hochstein =head1 COPYRIGHT AND LICENSE -Copyright (c) 2010 Thomas Hochstein +Copyright (c) 2010-2012 Thomas Hochstein This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself.