Expand|Select|Wrap|Line Numbers
- Log chain 1:
- Reading: server 2\08120700.mls
- Reading: server 2\08120900.mls
- Reading: server 1\08121100.mls
- Log chain 2:
- Reading: server 2\08120700.mls
- Reading: server 2\08120900.mls
- Reading: server 2\08121100.mls
- Log chain 3:
- Reading: server 3\08120700.mls
- Reading: server 3\08120900.mls
- Reading: server 3\08121100.mls
- ================================
- # Successful Syncs: 2535
- # Failed Syncs: 34
- ================================
- Total: 2569
- Average Sync Time: 22.05 sec
following:
1. Save it as an excel file
2. Look only for error with 1000 to 1012
Expand|Select|Wrap|Line Numbers
- ================================
- I would like the out come in the new saved spreadsheet as following:
- ================================
- # Successful Syncs: 2535
- ================================
- # Event ID 1000: 30
- # Event ID 1006: 4
- Total # Failed Syncs: 34
- ================================
- Total: 2569
- Average Sync Time: 22.05 sec
Below is the code:
-------------------------------------------
Expand|Select|Wrap|Line Numbers
- # summarize_ml_syncs.pl - Read all MobiLink logs from the current directory and/or all
- # immediate subdirectores, and provide a simple summary report.
- #
- #
- use strict;
- use Time::Local;
- my $Debug = 0; # Set to 1 to see verbose debug information
- my $ReadFiles = 1; # Set to 0 to show how files will be read, without actually reading.
- my $LOG;
- my $NO_MORE = 'NO_MORE';
- my $TSPat = /(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)/;
- #---------------------------------------------------------------------
- { package MLLog;
- #---------------------------------------------------------------------
- # @MLLog::ISA = qw( Obj );
- sub new {
- my $proto = shift();
- my $path = shift();
- my $class = ref($proto) || $proto;
- my $self = {};
- bless( $self, $class );
- $self->{MLLOG_FIRST_FILE} = undef;
- $self->{MLLOG_PREV_FILES} = {};
- $self->{MLLOG_NEXT_FILES} = {};
- $self->{MLLOG_CURR_FILE} = undef;
- $self->{MLLOG_PREV_TS} = undef;
- $self->{MLLOG_CHAINS} = [];
- $self->{MLLOG_CURR_CHAIN} = undef;
- $self->{MLLOG_IS_DONE} = 0;
- $self->{MLLOG_SYNCS} = {};
- $self->{MLLOG_NUM_SYNCS} = 0;
- $self->{MLLOG_NUM_OK_SYNCS} = 0;
- $self->{MLLOG_NUM_FAILED_SYNCS} = 0;
- $self->{MLLOG_TOTAL_SYNC_TIME} = 0;
- if( -d $path ) {
- $self->AddFiles( $path, 2 ); # 2 is the maximum depth supported.
- $self->{MLLOG_DIR} = $path;
- } else {
- $self->AddFile( undef, $path, undef );
- $self->{MLLOG_DIR} = undef;
- }
- return( $self );
- };
- sub debug {
- my $self = shift();
- if( $Debug ) {
- printf( @_ );
- }
- }
- sub Dir {
- my $self = shift();
- return( $self->{MLLOG_DIR} );
- }
- sub CurrFile {
- my $self = shift();
- my $value = shift();
- if( defined( $value ) ) {
- $self->{MLLOG_CURR_FILE} = $value;
- }
- return( $self->{MLLOG_CURR_FILE} );
- }
- sub Chains {
- my $self = shift();
- return( $self->{MLLOG_CHAINS} );
- }
- sub CurrChain {
- my $self = shift();
- my $value = shift();
- if( defined( $value ) ) {
- $self->{MLLOG_CURR_CHAIN} = $value;
- }
- return( $self->{MLLOG_CURR_CHAIN} );
- }
- sub IsDone {
- my $self = shift();
- my $value = shift();
- if( defined( $value ) ) {
- $self->{MLLOG_IS_DONE} = $value;
- }
- return( $self->{MLLOG_IS_DONE} );
- }
- sub Syncs {
- my $self = shift();
- return( $self->{MLLOG_SYNCS} );
- }
- sub TotalSyncTime {
- my $self = shift();
- return( $self->{MLLOG_TOTAL_SYNC_TIME} );
- }
- sub NumSyncs {
- my $self = shift();
- return( $self->{MLLOG_NUM_SYNCS} );
- }
- sub NumOKSyncs {
- my $self = shift();
- return( $self->{MLLOG_NUM_OK_SYNCS} );
- }
- sub NumFailedSyncs {
- my $self = shift();
- return( $self->{MLLOG_NUM_FAILED_SYNCS} );
- }
- sub PrevFiles {
- my $self = shift();
- return( $self->{MLLOG_PREV_FILES} );
- }
- sub NextFiles {
- my $self = shift();
- return( $self->{MLLOG_NEXT_FILES} );
- }
- sub PrevFile {
- my $self = shift();
- my $file = shift();
- my $value = shift();
- if( defined( $value ) ) {
- $self->debug( "Prev file for %s is %s\n", $file, $value );
- ${ $self->PrevFiles }{ lc( $file ) } = $value;
- }
- return( ${ $self->PrevFiles }{ lc( $file ) } );
- }
- sub NextFile {
- my $self = shift();
- my $file = shift();
- my $value = shift();
- if( defined( $value ) ) {
- if( !defined( ${ $self->NextFiles }{ lc( $file ) } ) ) {
- $self->debug( "Next file for %s is %s\n", $file, $value );
- }
- ${ $self->NextFiles }{ lc( $file ) } = $value;
- }
- return( ${ $self->NextFiles }{ lc( $file ) } );
- }
- sub AddFile {
- my $self = shift();
- my $dir = shift();
- my $file = shift();
- my $prev_file = shift();
- if( defined( $dir ) && !( -d $dir ) ) {
- die( "$dir is not a directory" );
- }
- $file = "$dir\\$file";
- $prev_file = "$dir\\$prev_file";
- if( !( -f $prev_file ) ) {
- $prev_file = undef;
- }
- if( defined( $prev_file ) ) {
- $self->debug( "Adding file %s prev is %s\n", $file, $prev_file );
- } else {
- $self->debug( "Adding file %s\n", $file );
- # Track the root files of chains.
- push( @{ $self->Chains }, lc( $file ) );
- $self->debug( "Chain %d starts at %s\n", scalar( @{ $self->Chains } ), $file );
- }
- # Link files by pointing to the previous file.
- $self->PrevFile( $file, $prev_file );
- # Determine the next file(s).
- # Not efficient, but thorough.
- $self->NextFile( $file, undef );
- my $f;
- foreach $f (keys( %{ $self->PrevFiles } )) {
- $prev_file = $self->PrevFile( $f );
- if( defined( $prev_file ) ) {
- $self->NextFile( $prev_file, $f );
- }
- }
- }
- sub AddFiles {
- my $self = shift();
- my $dir = shift();
- my $depth = shift();
- my $e;
- my @dirs;
- opendir( D, $dir ) || die( "Unable to open directory $dir for read" );
- while( $e = readdir( D ) ) {
- my $path = $dir . '\\' . $e;
- if( -d $path ) {
- if( $e ne '.' && $e ne '..' ) {
- $self->debug( "DIR: %s\n", $e );
- push( @dirs, $e );
- }
- } else {
- my $F;
- $self->debug( "FILE: %s\n", $path );
- open( $F, "<$path" ) || die( "Unable to open $path for read" );
- my $first_line = readline( $F );
- close( $F );
- $self->debug( "First line: %s\n", $first_line );
- if( $first_line =~ m/SQL Anywhere MobiLink Server Version/ ) {
- $self->AddFile( $dir, $e, undef );
- $self->debug( "Found file: $e, no prev\n" );
- } elsif( $first_line =~ m/^[IWE]\. \d\d\d\d-.*/ ) {
- if( $first_line =~ m/old output file "[^"]+" has been renamed to file "([^"]+)"/i ) {
- my $prev = lc( $1 );
- # Strip the directory, since it is redundant and prevents hash matches.
- $prev =~ s/.*\\(.*)/$1/;
- $self->debug( "Prev: %s\n", $prev );
- # Add the file.
- $self->AddFile( $dir, $e, $prev );
- $self->debug( "Found file: $path, prev is $prev\n" );
- } else {
- $self->debug( "Ignoring %s\n", $path );
- }
- } else {
- $self->debug( "Ignoring %s\n", $path );
- }
- }
- }
- closedir( D );
- foreach $e (@dirs) {
- if( $depth > 1 ) {
- $self->AddFiles( $e, $depth - 1 );
- }
- }
- }
- sub GetNextFile {
- my $self = shift();
- my $prev_chain = $self->CurrChain;
- if( $self->IsDone ) {
- return( undef );
- }
- if( !defined( $self->CurrFile ) ) {
- $self->debug( "Next file is first in chain 0\n" );
- $self->CurrChain( 0 );
- $self->CurrFile( ${ $self->Chains }[ $self->CurrChain ] );
- } else {
- $self->{MLLOG_CURR_FILE} = $self->NextFile( $self->CurrFile );
- if( !defined( $self->CurrFile ) ) {
- $self->{MLLOG_CURR_CHAIN} = $self->CurrChain + 1;
- if( $self->CurrChain < scalar( @{ $self->Chains } ) ) {
- $self->CurrFile( ${ $self->Chains }[ $self->CurrChain ] );
- $self->debug( "Starting new chain %d\n", $self->CurrChain );
- } else {
- $self->CurrFile( undef );
- $self->debug( "Last file in all chains\n" );
- }
- } else {
- $self->debug( "In the middle of chain %s\n", $self->CurrChain );
- }
- }
- if( $prev_chain ne $self->CurrChain && $self->CurrChain < scalar( @{ $self->Chains } ) ) {
- printf( "Log chain %d\:\n", ( 1 + $self->CurrChain ) );
- }
- if( defined( $self->CurrFile ) ) {
- my $f;
- if( $self->Dir ne '' ) {
- $f = $self->Dir . '\\' . $self->CurrFile;
- } else {
- $f = $self->CurrFile;
- }
- } else {
- $self->debug( "No more files to open.\n", $self->CurrFile );
- $self->IsDone( 1 );
- }
- return( $self->CurrFile );
- }
- sub TimeStamp {
- my $self = shift();
- my ( $y, $m, $d, $h, $min, $s ) = @_;
- my $ts = Time::Local::timegm( $s, $min, $h, $d, $m - 1, $y - 1900 );
- return( $ts );
- }
- sub StartSync {
- my $self = shift();
- my $sid = shift();
- my $ts = shift();
- ${ $self->Syncs }{ $sid } = $ts;
- }
- sub EndOKSync {
- my $self = shift();
- my $sid = shift();
- my $ts = shift();
- my $start_ts = ${ $self->Syncs }{ $sid };
- if( defined( $start_ts ) ) {
- my $duration = ( $ts - $start_ts );
- $self->debug( "Sync %s has duration %d seconds\n", $sid, $duration );
- # Only count complete syncs.
- $self->{MLLOG_NUM_SYNCS} += 1;
- $self->{MLLOG_TOTAL_SYNC_TIME} += $duration;
- $self->{MLLOG_NUM_OK_SYNCS} += 1;
- ${ $self->Syncs }{ $sid } = undef;
- } else {
- $self->debug( "Sync %s has an unknown start\n", $sid );
- }
- }
- sub EndFailedSync {
- my $self = shift();
- my $sid = shift();
- my $ts = shift();
- my $start_ts = ${ $self->Syncs }{ $sid };
- if( defined( $start_ts ) ) {
- my $duration = ( $ts - $start_ts );
- $self->debug( "Failed sync %s has duration %d seconds\n", $sid, $duration );
- # Only count complete syncs.
- $self->{MLLOG_NUM_SYNCS} += 1;
- $self->{MLLOG_TOTAL_SYNC_TIME} += $duration;
- $self->{MLLOG_NUM_FAILED_SYNCS} += 1;
- ${ $self->Syncs }{ $sid } = undef;
- } else {
- $self->debug( "Failed sync %s has an unknown start\n", $sid );
- }
- }
- sub ReadFiles {
- my $self = shift();
- my $file;
- my $line;
- my $ts;
- while( $file = $self->GetNextFile ) {
- printf( " Reading: $file\n" );
- if( $ReadFiles ) {
- open( LOG, "<$file" ) || die( "Unable to open $file for read" );
- while( $line = readline( LOG ) ) {
- if( $line =~ m/(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)\. <(\d+)> Request from/ ) {
- my ( $y, $m, $d, $h, $min, $s, $sid ) = ( $1, $2, $3, $4, $5, $6, $7 );
- $ts = $self->TimeStamp( $y, $m, $d, $h, $min, $s );
- $self->StartSync( $sid, $ts );
- } elsif( $line =~ m/(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)\. <(\d+)> Synchronization complete/ ) {
- my ( $y, $m, $d, $h, $min, $s, $sid ) = ( $1, $2, $3, $4, $5, $6, $7 );
- $ts = $self->TimeStamp( $y, $m, $d, $h, $min, $s );
- $self->EndOKSync( $sid, $ts );
- } elsif( $line =~ m/(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)\. <(\d+)> Synchronization failed/ ) {
- my ( $y, $m, $d, $h, $min, $s, $sid ) = ( $1, $2, $3, $4, $5, $6, $7 );
- $ts = $self->TimeStamp( $y, $m, $d, $h, $min, $s );
- $self->EndFailedSync( $sid, $ts );
- }
- }
- }
- close( LOG );
- }
- }
- sub Report {
- my $self = shift();
- my $average_sync_time;
- if( $self->NumSyncs > 0 ) {
- $average_sync_time = ( 0.0 + $self->TotalSyncTime ) / $self->NumSyncs;
- } else {
- $average_sync_time = 0.0;
- }
- printf( "================================\n" );
- printf( "# Successful Syncs: %7d\n", $self->NumOKSyncs );
- printf( "# Failed Syncs: %7d\n", $self->NumFailedSyncs );
- printf( "---------------------------\n" );
- printf( "Total: %7d\n", $self->NumSyncs );
- printf( "\n" );
- printf( "Average Sync Time: %8.2f sec\n", $average_sync_time );
- printf( "================================\n" );
- }
- }
- my $Logs = new MLLog( '.' );
- $Logs->ReadFiles();
- $Logs->Report();
- print( "Done.\n" );
Thanks,
Mark