os/persistentdata/traceservices/commsdebugutility/tools/extractlog.pl
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/traceservices/commsdebugutility/tools/extractlog.pl	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,227 @@
     1.4 +# Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +# All rights reserved.
     1.6 +# This component and the accompanying materials are made available
     1.7 +# under the terms of "Eclipse Public License v1.0"
     1.8 +# which accompanies this distribution, and is available
     1.9 +# at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +#
    1.11 +# Initial Contributors:
    1.12 +# Nokia Corporation - initial contribution.
    1.13 +#
    1.14 +# Contributors:
    1.15 +#
    1.16 +# Description:
    1.17 +#
    1.18 +
    1.19 +use strict;
    1.20 +use Getopt::Long;
    1.21 +
    1.22 +# read in the command line parameters
    1.23 +my $verbose = 0;
    1.24 +my $singleLevel = 0;
    1.25 +my $fromBatchFile = 0;
    1.26 +my $help = 0;
    1.27 +GetOptions( 'verbose|v!' => \$verbose,
    1.28 +			'1!' => \$singleLevel,
    1.29 +			'help|h|?!' => \$help,
    1.30 +			'--fromBatchFile!' => \$fromBatchFile );
    1.31 +Usage() if $help;
    1.32 +my $file  = $ARGV[0];
    1.33 +if(!defined($file))
    1.34 +{
    1.35 +	$file = "$ENV{EPOCROOT}EPOC32\\WINSCW\\C\\LOGS\\LOG.TXT";
    1.36 +	$file = "$ENV{EPOCROOT}EPOC32\\WINS\\C\\LOGS\\LOG.TXT" if(!-r $file);
    1.37 +	print "No file specified, defaulting to $file\n";
    1.38 +}
    1.39 +print "Verbose mode on\n" if $verbose;
    1.40 +
    1.41 +# open up the file for input
    1.42 +open(INPUT_FILE, "< $file") or die "ERROR: Couldn't open the file \"$file\" for input:";
    1.43 +
    1.44 +# read file without intepretting CR/LF - not ideal on window's systems, but
    1.45 +# I introduced this to get around apparent problem when seeking back when reading binary data
    1.46 +# The seek back seemed to seek to somewhere other than where we had last "tell"'ed.
    1.47 +# binmode fixes this since CR/LF is always seen as 2 distinct chars.
    1.48 +binmode(INPUT_FILE);
    1.49 +
    1.50 +# declare handy arrays
    1.51 +my %file_handles_text;   # a hash of all components seen for ascii and their associated file handle
    1.52 +my %file_handles_binary; # a hash of all components seen for binary and their associated file handle
    1.53 +my @comments;       # an array of all the comment lines seen so far
    1.54 +
    1.55 +# iterate through each line of the file
    1.56 +my $filepos = tell(INPUT_FILE);
    1.57 +my $linenum = 1;
    1.58 +while (<INPUT_FILE>) {
    1.59 +    # strip off any CR/LF's since we will correctly terminate the line by one
    1.60 +    # if we find the line is ascii. Binary lines should also arrive with a CR/LF at their end.
    1.61 +    my $line = $_;
    1.62 +    print $line if $verbose;
    1.63 +    chomp($line);
    1.64 +
    1.65 +    my $strlen = length($line);
    1.66 +    if (($strlen == 0) || (ord "$line" == 13)) {
    1.67 +       if ($verbose) { print "Line#: $linenum is an empty line.\n"; }
    1.68 +    } else {
    1.69 +		$line =~ s/\r$//;	# chomp CR
    1.70 +        if ($line =~ /^#/) {
    1.71 +            # we are dealing with a comment line
    1.72 +            $line .= "\n";
    1.73 +            push(@comments, "$line");
    1.74 +            while((my $component, my $file_handle) = each(%file_handles_text)) {
    1.75 +                print $file_handle "$line"
    1.76 +            }
    1.77 +        }
    1.78 +        else {
    1.79 +            #we are dealing with a component line so check the correct line format and determine if it is ascii or binary
    1.80 +            my @list = split("\t", $line);
    1.81 +
    1.82 +            my $linetype = "$list[2]";
    1.83 +
    1.84 +            if (ord "$linetype" == 97) {
    1.85 +                # this is ascii, so return a CR/LF to line
    1.86 +                $line .= "\n";
    1.87 +                my $component = lc($list[0] . ($singleLevel? "": "_$list[1]") . ".log");
    1.88 +                if (not exists $file_handles_text{$component}) {
    1.89 +                    # we haven't seen this component before
    1.90 +                    local *OUTFILE;
    1.91 +                    open(OUTFILE, "> $component") or die "ERROR. Line $linenum: can't open file \"$component\" for output: $!";
    1.92 +                    foreach my $comment (@comments) {
    1.93 +                        print OUTFILE "$comment";
    1.94 +                    }
    1.95 +                    $file_handles_text{$component} = *OUTFILE;
    1.96 +                }
    1.97 +                my $file_handle = $file_handles_text{$component};
    1.98 +                print $file_handle "$line";
    1.99 +            } elsif (ord "$linetype" == 98) {
   1.100 +                #assume it is binary
   1.101 +                my $component = "$list[0]_$list[1].bin";
   1.102 +                if (not exists $file_handles_binary{$component}) {
   1.103 +                    # we haven't seen this component before
   1.104 +                    local *OUTFILE;
   1.105 +                    open(OUTFILE, "> $component") or die "ERROR. Line $linenum: can't open file \"$component\" for output: $!";
   1.106 +                    binmode(OUTFILE);
   1.107 +                    $file_handles_binary{$component} = *OUTFILE;
   1.108 +                }
   1.109 +
   1.110 +                # go back to start of line since CR/LF might even occur in the length field,
   1.111 +                # then read to each tab until the binary tag is found again
   1.112 +                seek(INPUT_FILE,$filepos,0);
   1.113 +
   1.114 +                my $old_rs = $/;
   1.115 +                $/ = chr(9);
   1.116 +                do {
   1.117 +                    $_ = <INPUT_FILE>;
   1.118 +                } while ((ord "$_" != 98) && (length != 1));
   1.119 +                $/ = $old_rs;
   1.120 +
   1.121 +                # read the length as a "little-endian" 4-byte unsigned integer
   1.122 +				my $datalenstr;
   1.123 +                my $numread = read(INPUT_FILE,$datalenstr,4);
   1.124 +                if ($numread != 4) { die "ERROR: did not read all 4 bytes binary data length on line $linenum"; }
   1.125 +
   1.126 +                my $datatoread = unpack("v",$datalenstr);
   1.127 +
   1.128 +                # read next char and ensure it is a tab
   1.129 +				my $onechar;
   1.130 +                $numread = read(INPUT_FILE,$onechar,1);
   1.131 +                if ($numread != 1) { die "ERROR: read error when reading tab char in binary line on line $linenum"; }
   1.132 +                if (ord $onechar != 9) { die "ERROR: No tab char in binary line at pos : $filepos where expected between length and data at line $linenum"; }
   1.133 +
   1.134 +                if ($verbose) {
   1.135 +                    print "About to read binary data. Beginning of line is at pos: $filepos ";
   1.136 +                    printf " [%X] Tags: ",$filepos;
   1.137 +                    foreach my $d (@list) {
   1.138 +                       print "[$d]";
   1.139 +                    }
   1.140 +                    print "\nBytes to read: $datatoread\n";
   1.141 +                }
   1.142 +
   1.143 +				my $datastr;
   1.144 +                $numread = read(INPUT_FILE,$datastr,$datatoread);
   1.145 +                if ($datatoread != $numread) { die "ERROR: only read $numread of expected $datatoread bytes binary data on line $linenum"; }
   1.146 +
   1.147 +                if ($verbose) { print "Read Completed.\n"; }
   1.148 +
   1.149 +
   1.150 +                my $file_handle = $file_handles_binary{$component};
   1.151 +                print $file_handle "$datastr";
   1.152 +
   1.153 +                # finally, read in the trailing CR/LF before reverting to textual reading
   1.154 +                $_ = <INPUT_FILE>;
   1.155 +        
   1.156 +            } else {
   1.157 +                if ($verbose) {
   1.158 +                    print "Line# $linenum at filepos $filepos is CORRUPT: linetype field is neither ascii nor binary so ignoring.\n";
   1.159 +                    print "Line fields: ";
   1.160 +                    foreach my $d (@list) {
   1.161 +                       print "[$d]";
   1.162 +                    }
   1.163 +                    print "\n     ... skipping line and continuing\n";
   1.164 +                }
   1.165 +
   1.166 +            }
   1.167 +        } # comment line check
   1.168 +    } #empty line check
   1.169 +    $filepos = tell(INPUT_FILE);
   1.170 +    #print "filepos at end of line proc: $filepos . input rec #: $.";
   1.171 +    #printf "[%X]\n",$filepos;
   1.172 +    $linenum++;
   1.173 +}
   1.174 +
   1.175 +# and finally clean up
   1.176 +close(INPUT_FILE) or die "ERROR: failed to close the input log file: $!";
   1.177 +my $firstFile = 1;
   1.178 +while((my $component, my $file_handle) = each(%file_handles_text)) 
   1.179 +{
   1.180 +	printf "%s%s", $firstFile? "Generated: ": ", ", $component;
   1.181 +	$firstFile = 0;
   1.182 +    close($file_handle) or die "ERROR: failed to close the output log file for \"$component\": $!";
   1.183 +}
   1.184 +while((my $component, my $file_handle) = each(%file_handles_binary)) 
   1.185 +{
   1.186 +	printf "%s%s", $firstFile? "Generated: ": ", ", $component;
   1.187 +	$firstFile = 0;
   1.188 +    close($file_handle) or die "ERROR: failed to close the output log file for \"$component\": $!";
   1.189 +}
   1.190 +print "\n";
   1.191 +
   1.192 +
   1.193 +sub Usage () {
   1.194 +print $fromBatchFile? "Common Usage: splitlog [logfile] [-v][-1]\n": "Args: [logfile] [-v][-1]\n";
   1.195 +    print <<ENDHERESTRING;
   1.196 +Where:
   1.197 +  [logfile] = CDU log file (default: {EPOCROOT}\\EPOC32\\WINS[CW]\\C\\LOGS\\LOG.TXT)
   1.198 +  [-v]      = verbose output
   1.199 +  [-1]      = split only at component level (one file per unique first tag)
   1.200 +   
   1.201 +Input Log file format:
   1.202 + as specified in the FLOGGER documentation.  Briefly, there are three
   1.203 + types of log messages:
   1.204 +   1) Comment lines.  These contain a '#' character at the beginning of
   1.205 +      the line.
   1.206 +   2) Ascii Log lines.  Contains tab separated fields - the first being the 
   1.207 +      name of the component that logged that particular message.
   1.208 +   3) Binary Log lines. Same fields as an ascii line but then contains
   1.209 +      a specified number of bytes of raw data. 
   1.210 +
   1.211 +Output:
   1.212 + This script will create a number of files in the current 
   1.213 + directory - one for each component found in the input log file.  Each
   1.214 + file will have the same name as the first two tags separated by an underscore.
   1.215 + If the component is logging ascii test, its output log file will contain all
   1.216 + comment lines, and all log lines relating to that particular component.
   1.217 + If the component is logging binary data, only the actual data is placed in
   1.218 + the output log file.
   1.219 + Ascii output files are given the extension *.log while binary files have
   1.220 + extension *.bin
   1.221 +
   1.222 +"Out of Memory":
   1.223 +  error may mean the file is corrupt and the script tried to
   1.224 +  read a section of binary data which isn't there. Try rerunning with the "-v"
   1.225 +  flag to help diagnose. File position numbers reported should correlate exactly
   1.226 +  with the byte position if displaying file in a hex editor.
   1.227 +ENDHERESTRING
   1.228 +
   1.229 +    exit 1;
   1.230 +}