Changeset 2551

Show
Ignore:
Timestamp:
01/25/10 11:04:05 (6 months ago)
Author:
kilburn
Message:

* ENGINE: Fixed #2180: /var/log/ispcp/logdb doesn't get properly updated and is causing wrong statistics

Location:
trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/CHANGELOG

    r2550 r2551  
    11ispCP ω 1.0.4 Changelog 
    22~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     3 
     42010-01-25 Marc Pujol 
     5        - ENGINE: 
     6                * Fixed #2180: /var/log/ispcp/logdb doesn't get properly updated and is causing wrong statistics 
    37 
    482010-01-22 Marc Pujol 
  • trunk/engine/traffic/ispcp-vrl-traff

    r2505 r2551  
    3434require 'ispcp_common_code.pl'; 
    3535 
     36use strict; 
     37use warnings; 
     38use File::Basename; 
     39use Fcntl ":seek"; 
     40 
    3641%main::ftp_traffic = (); 
    37  
    3842%main::smtp_traffic = (); 
    39  
    4043%main::po_traffic = (); 
    41  
    4244%main::sub_id_name= (); 
    4345 
    44 use strict; 
    45  
    46 use warnings; 
    47  
    48 use File::Basename; 
    49  
    50  
    5146sub zero_traffic_entries { 
     47        push_el(\@main::el, 'zero_traffic_entries()', 'Starting...'); 
    5248 
    5349        my ($key, $value) = (undef, undef); 
    5450 
    55         push_el(\@main::el, 'zero_traffic_entries()', 'Starting...'); 
    56  
    5751        while (($key, $value) = each %main::domain_name_id) { 
    58  
    5952                $main::ftp_traffic{$key} = 0; 
    60  
    6153                $main::smtp_traffic{$key} = 0; 
    62  
    6354                $main::po_traffic{$key} = 0; 
    64  
    6555        } 
    6656 
    6757        while (($key, $value) = each %main::als_name_id) { 
    68  
    6958                $main::ftp_traffic{$key} = 0; 
    70  
    7159                $main::smtp_traffic{$key} = 0; 
    72  
    7360                $main::po_traffic{$key} = 0; 
    74  
    7561        } 
    7662 
    7763        push_el(\@main::el, 'zero_traffic_entries()', 'Ending...'); 
    78  
    7964        return 0; 
    80  
    81 } 
    82  
    83 sub diff_command { 
    84  
    85         my ($cmd) = @_; 
    86  
    87         push_el(\@main::el, 'diff_command()', 'Starting...'); 
    88  
    89         my $result = system($cmd); 
    90  
    91         my $exit_value = $? >> 8; 
    92  
    93         my $signal_num = $? & 127; 
    94  
    95         my $dumped_core = $? & 128; 
    96  
    97         if ($exit_value == 2) { 
    98  
    99                 push_el(\@main::el, 'diff_command()', "ERORR: '$cmd' returned '$exit_value' !"); 
    100  
    101                 return $exit_value; 
    102  
    103         } 
    104  
    105         push_el(\@main::el, 'diff_command()', 'Ending...'); 
    106  
    107         return $exit_value; 
    108  
    10965} 
    11066 
    11167sub gen_log_file { 
    112  
    11368        my ($fname, $src_dir, $dest_dir) = @_; 
    114  
    115         push_el(\@main::el, 'gen_log_file()', 'Starting...'); 
     69        push_el(\@main::el, 'gen_log_file()', "Starting for logfile $src_dir/$fname"); 
    11670 
    11771        my $rs = undef; 
    118  
    11972        $fname =~ s/\/*//i; 
    120  
    12173        my $src_file = "$src_dir/$fname"; 
    122  
    12374        my $dest_file = "$dest_dir/".basename($fname); 
    12475 
    125         my $dest_file_prev = "$dest_dir/".basename($fname).".prev"; 
    126  
    127         my $log_file = $dest_file; 
    128  
    12976        if(! -e $src_file){ 
    130  
    131                 push_el(\@main::el, 'gen_log_file()', "WARNING: File '$src_file' do not exists !"); 
    132  
     77                push_el(\@main::el, 'gen_log_file()', "WARNING: File '$src_file' does not exist !"); 
    13378                return (0, '_no_'); 
    134  
    135         } 
    136  
    137         $rs = sys_command("$main::cfg{'CMD_CP'} $src_file $dest_file"); 
    138  
    139         return ($rs, '') if ($rs != 0); 
    140  
    141         #Log Enhancement begin 
    142  
     79        } 
     80 
     81        # Log enhancement: use a small (file-based) database storing the preivous offset and first line 
     82        # of each processed logfile. 
    14383        my $logdb_file = "$dest_dir/logdb"; 
    144  
    14584        my %logdb; 
    146  
    147         my $pos = 0; 
    148  
    149         #Creating the logdb file where the log position for each log reside if not already created 
    150  
     85        my ($recPos, $recLine) = (0, ''); 
     86 
     87        # Creating the logdb file where the log position for each log reside if not already created 
    15188        if (!-e "$logdb_file") { 
    152  
    15389                $rs = sys_command("$main::cfg{'CMD_TOUCH'} $logdb_file"); 
    154  
    155                 return ($rs, '') if ($rs != 0); 
    156  
    157         } 
    158  
     90                if ($rs != 0) { 
     91                        push_el(\@main::el, 'gen_log_file()', "ERROR: Unable to create the lobdb file '$logdb_file' !"); 
     92                        return ($rs, ''); 
     93                } 
     94        } 
     95 
     96        # @TODO: 
     97        # This is unefficient because gen_log_file is called once for every log file to be processed. Therefore, the 
     98        # *whole* logdb file is read at each call, causing a lot of re-readings. Thus, logdb reading should be done 
     99        # once at the beggining of this script and, similarly, logdb writting should be done just once at the end. 
    159100        push_el(\@main::el, 'gen_log_file()', "Taking the domain log positions from '$logdb_file'..."); 
    160  
    161         $rs = open (LOGDB,'+<',"$logdb_file"); 
    162  
     101        $rs = open (LOGDB,'<',"$logdb_file"); 
    163102        if (!defined($rs)) { 
    164  
    165103                push_el(\@main::el, 'gen_log_file()', "ERROR: Can't open '$logdb_file' for reading !"); 
    166  
    167104                return (-1, ''); 
    168  
    169         } 
    170  
     105        } 
    171106        while (<LOGDB>) { 
    172  
    173                 my ($logdb_key,$logdb_val) = split(' ',$_); 
    174  
     107                chomp; 
     108                my ($logdb_key,$logdb_val) = split(' ', $_, 2); 
    175109                $logdb{$logdb_key} = $logdb_val; 
    176  
    177         } 
    178  
    179         if (-e $dest_file_prev) { 
    180  
    181                 #There is almost no chance two log files to have the same size and not to be identical. However if you find your logs too precious, keep the byte by byte cmp ;) 
    182  
    183                 if (-s $dest_file == -s $dest_file_prev) { 
    184  
    185                         $rs = del_file($dest_file); 
    186  
    187                         push_el(\@main::el, 'gen_log_file()', "No changes in $dest_file , msg: Ending..."); 
    188  
    189                         return ($rs, '') if ($rs != 0); 
    190  
    191                         return (0, '_no_'); 
    192  
    193                 } 
    194  
    195                 $log_file = $dest_file.".diff"; 
    196  
    197                 $rs = open(DESTLOG,'<',$dest_file); 
    198  
    199                 if (!defined($rs)) { 
    200  
    201                         push_el(\@main::el, 'gen_log_file()', "ERROR: Can't open '$dest_file' for reading !"); 
    202  
    203                         return (-1, ''); 
    204  
    205                 } 
    206  
    207                 $rs = open(LOGFILE, '>',$log_file); 
    208  
    209                 if (!defined($rs)) { 
    210  
    211                         push_el(\@main::el, 'gen_log_file()', "ERROR: Can't open '$log_file' for writing !"); 
    212  
    213                         return (-1, ''); 
    214  
    215                 } 
    216  
    217                 #We check if we have last saved position for this domain log 
    218  
    219                 if (exists($logdb{$fname})) { 
    220  
    221                         $pos = $logdb{$fname}; 
    222  
    223                         #The log is not rotated so we just copy the remaining entries from our last saved position to the end 
    224  
    225                         if (-s $dest_file > -s $dest_file_prev) { 
    226  
    227                                 push_el(\@main::el, 'gen_log_file'," Parsing for $dest_file begins at position $pos."); 
    228  
    229                                 seek(DESTLOG,$pos,0); 
    230  
    231                                 while (<DESTLOG>) { 
    232  
    233                                         print LOGFILE $_; 
    234  
    235                                         $pos = tell(DESTLOG) if (eof(DESTLOG)); 
    236  
    237                                 } 
    238  
    239                                 $logdb{$fname} = $pos; 
    240  
    241                         } 
    242  
    243                         #The log was rotated so we need to use the old log and copy the remaining entries and then continue from the new one. 
    244  
    245                         else { 
    246  
    247                                 my $old_src_file = "$src_file.1"; 
    248  
    249                                 my $old_dest_file = "$dest_file.1"; 
    250  
    251                                 if (-e $old_src_file) { 
    252  
    253                                         push_el(\@main::el, 'gen_log_file',"$dest_file was rotated. Parsing begins at position $pos in  $old_src_file"); 
    254  
    255                                         $rs = sys_command("$main::cfg{'CMD_CP'} $old_src_file $old_dest_file"); 
    256  
    257                                         return ($rs, '') if ($rs != 0); 
    258  
    259                                         $rs = open (OLDLOG,'<',$old_dest_file); 
    260  
    261                                         if (!defined($rs)) { 
    262  
    263                                                 push_el(\@main::el, 'gen_log_file()', "ERROR: Can't open '$old_dest_file' for reading !"); 
    264  
    265                                                 return (-1, ''); 
    266  
    267                                         } 
    268  
    269                                         seek(OLDLOG,$pos,0); 
    270  
    271                                         while (<OLDLOG>) { 
    272  
    273                                                 print LOGFILE $_; 
    274  
    275                                         } 
    276  
    277                                         close OLDLOG; 
    278  
    279                                         $rs = del_file($old_dest_file); 
    280  
    281                                         return ($rs, '') if ($rs != 0); 
    282  
    283                                 } 
    284  
    285                                 else { 
    286  
    287                                         push_el(\@main::el, 'gen_log_file',"$dest_file was rotated but no $old_src_file found!"); 
    288  
    289                                 } 
    290  
    291                                 while (<DESTLOG>) { 
    292  
    293                                         print LOGFILE $_; 
    294  
    295                                         $pos = tell(DESTLOG) if (eof(DESTLOG)); 
    296  
    297                                 } 
    298  
    299                                 $logdb{$fname} = $pos; 
    300                         } 
    301  
    302                 } 
    303  
    304                 #We have no entry for this domain log. Lets create one! 
    305                 else { 
    306  
    307                         if (-s $dest_file > -s $dest_file_prev) { 
    308  
    309  
    310                                 $rs = open(DESTLOGPREV,'<',$dest_file_prev); 
    311  
    312                                 if (!defined($rs)) { 
    313  
    314                                         push_el(\@main::el, 'gen_log_file()', "ERROR: Can't open '$dest_file' for reading !"); 
    315  
    316                                         return (-1, ''); 
    317  
    318                                 } 
    319  
    320                                 push_el(\@main::el, 'gen_log_file',"No log db entry for $dest_file. Checking last position in $dest_file_prev."); 
    321  
    322                                 seek(DESTLOGPREV,0,2); 
    323  
    324                                 $pos = tell(DESTLOGPREV); 
    325  
    326                                 close(DESTLOGPREV); 
    327  
    328                         } 
    329  
    330                         seek(DESTLOG,$pos,0); 
    331  
    332                         while (<DESTLOG>) { 
    333  
    334                                 print LOGFILE $_; 
    335  
    336                                 $pos = tell(DESTLOG) if (eof(DESTLOG)); 
    337  
    338                         } 
    339  
    340                         $logdb{$fname} = $pos; 
    341  
    342                 } 
    343  
    344                 close DESTLOG; 
    345  
    346                 close LOGFILE; 
    347  
    348                 $rs = sys_command("$main::cfg{'CMD_MV'} $dest_file $dest_file_prev"); 
    349  
    350                 return ($rs, '') if ($rs != 0); 
    351  
    352         } else { 
    353  
    354                 $rs = sys_command("$main::cfg{'CMD_CP'} $dest_file $dest_file_prev"); 
    355  
    356                 return ($rs, '') if ($rs != 0); 
    357  
    358                 $rs = open(DESTLOG,'<',$dest_file); 
    359  
    360                 if (!defined($rs)) { 
    361  
    362                         push_el(\@main::el, 'gen_log_file()', "ERROR: Can't open '$dest_file' for reading !"); 
    363  
    364                         return (-1, ''); 
    365  
    366                 } 
    367  
    368                 push_el(\@main::el, 'gen_log_file',"We have no .prev file. Parsing the whole '$dest_file'."); 
    369  
    370                 seek(DESTLOG,0,2); 
    371  
    372                 $pos = tell(DESTLOG); 
    373  
    374  
    375                 $logdb{$fname} = $pos; 
    376  
    377         } 
    378  
    379         #Let's write the new position back to the log db 
    380  
     110        } 
     111        close(LOGDB); 
     112        if (exists($logdb{$fname})) { 
     113                ($recPos, $recLine) = split(' ', $logdb{$fname}, 2); 
     114                $recLine = '' if (!defined($recLine)) ; 
     115        } 
     116 
     117        # Open the relevant files 
     118        $rs = open(SRC_FILE, '<', $src_file); 
     119        if (!defined($rs)) { 
     120                push_el(\@main::el, 'gen_log_file()', "ERROR: Can't open '$src_file' for reading !"); 
     121                return (-1, ''); 
     122        } 
     123        # Open the destination file 
     124        $rs = open(DST_FILE, '>', $dest_file); 
     125        if (!defined($rs)) { 
     126                push_el(\@main::el, 'gen_log_file()', "ERROR: Can't open '$dest_file' for writing !"); 
     127                close(SRC_FILE); 
     128                return (-1, ''); 
     129        } 
     130         
     131        # Retrieve the current first line 
     132        my $curLine = <SRC_FILE> || ''; 
     133        $curLine =~ s/\n//; 
     134        seek(SRC_FILE, 0, SEEK_SET); 
     135 
     136        # Rotated log detection conditions: 
     137        #   1. The current logfile is smaller than the previously recorded offset position 
     138        #   2. The first line of the current log is different from the previously recorded first line 
     139        # If one of these conditions is fullfilled, try to read from the rotated logfile first. 
     140        if (-s $src_file < $recPos || $curLine ne $recLine) { 
     141                my $old_src_file = "$src_file.1"; 
     142                if (-e $old_src_file) { 
     143                        push_el(\@main::el, 'gen_log_file', "Logfile has been rotated, parsing '$old_src_file' from position $recPos."); 
     144                        $rs = open(OLD_SRC_FILE, '<', $old_src_file); 
     145                        if (defined($rs)) { 
     146                                while(<OLD_SRC_FILE>) { 
     147                                        print DST_FILE $_; 
     148                                } 
     149                                close(OLD_SRC_FILE); 
     150                        } else { 
     151                                push_el(\@main::el, 'gen_log_file',"WARNING: Can't open '$old_src_file' for reading !"); 
     152                        } 
     153                } else { 
     154                        push_el(\@main::el, 'gen_log_file',"Logfile has been rotated, but '$old_src_file' doesn't exist."); 
     155                } 
     156                $recPos = 0; 
     157        } 
     158 
     159        # Read the lines from the last position to the end 
     160        seek(SRC_FILE, $recPos, SEEK_SET); 
     161        while(<SRC_FILE>) { 
     162                print DST_FILE $_; 
     163        } 
     164        $recPos = tell(SRC_FILE); 
     165        close(SRC_FILE); 
     166        close(DST_FILE); 
     167  
     168        # Let's write the new position back to the log db 
     169        $logdb{$fname} = "$recPos $curLine"; 
    381170        push_el(\@main::el, 'gen_log_file()', "Saving new domain log positions in '$logdb_file'..."); 
    382  
    383         seek(LOGDB,0,0); 
    384  
    385         truncate(LOGDB,0); 
    386  
     171        $rs = open (LOGDB,'>',"$logdb_file"); 
     172        if (!defined($rs)) { 
     173                push_el(\@main::el, 'gen_log_file()', "ERROR: Can't open '$logdb_file' for writing !"); 
     174                return (-1, ''); 
     175        } 
    387176        foreach my $logdb_key (keys %logdb) { 
    388  
    389177                print LOGDB "$logdb_key $logdb{$logdb_key}\n"; 
    390  
    391         } 
    392  
     178        } 
    393179        close LOGDB; 
    394180 
    395181        push_el(\@main::el, 'gen_log_file()', 'Ending...'); 
    396  
    397         return (0, $log_file); 
     182        return (0, $dest_file); 
    398183} 
    399184