traceservices/commsdebugutility/tools/extractlog.pl
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 # Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 # All rights reserved.
       
     3 # This component and the accompanying materials are made available
       
     4 # under the terms of "Eclipse Public License v1.0"
       
     5 # which accompanies this distribution, and is available
       
     6 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 #
       
     8 # Initial Contributors:
       
     9 # Nokia Corporation - initial contribution.
       
    10 #
       
    11 # Contributors:
       
    12 #
       
    13 # Description:
       
    14 #
       
    15 
       
    16 use strict;
       
    17 use Getopt::Long;
       
    18 
       
    19 # read in the command line parameters
       
    20 my $verbose = 0;
       
    21 my $singleLevel = 0;
       
    22 my $fromBatchFile = 0;
       
    23 my $help = 0;
       
    24 GetOptions( 'verbose|v!' => \$verbose,
       
    25 			'1!' => \$singleLevel,
       
    26 			'help|h|?!' => \$help,
       
    27 			'--fromBatchFile!' => \$fromBatchFile );
       
    28 Usage() if $help;
       
    29 my $file  = $ARGV[0];
       
    30 if(!defined($file))
       
    31 {
       
    32 	$file = "$ENV{EPOCROOT}EPOC32\\WINSCW\\C\\LOGS\\LOG.TXT";
       
    33 	$file = "$ENV{EPOCROOT}EPOC32\\WINS\\C\\LOGS\\LOG.TXT" if(!-r $file);
       
    34 	print "No file specified, defaulting to $file\n";
       
    35 }
       
    36 print "Verbose mode on\n" if $verbose;
       
    37 
       
    38 # open up the file for input
       
    39 open(INPUT_FILE, "< $file") or die "ERROR: Couldn't open the file \"$file\" for input:";
       
    40 
       
    41 # read file without intepretting CR/LF - not ideal on window's systems, but
       
    42 # I introduced this to get around apparent problem when seeking back when reading binary data
       
    43 # The seek back seemed to seek to somewhere other than where we had last "tell"'ed.
       
    44 # binmode fixes this since CR/LF is always seen as 2 distinct chars.
       
    45 binmode(INPUT_FILE);
       
    46 
       
    47 # declare handy arrays
       
    48 my %file_handles_text;   # a hash of all components seen for ascii and their associated file handle
       
    49 my %file_handles_binary; # a hash of all components seen for binary and their associated file handle
       
    50 my @comments;       # an array of all the comment lines seen so far
       
    51 
       
    52 # iterate through each line of the file
       
    53 my $filepos = tell(INPUT_FILE);
       
    54 my $linenum = 1;
       
    55 while (<INPUT_FILE>) {
       
    56     # strip off any CR/LF's since we will correctly terminate the line by one
       
    57     # if we find the line is ascii. Binary lines should also arrive with a CR/LF at their end.
       
    58     my $line = $_;
       
    59     print $line if $verbose;
       
    60     chomp($line);
       
    61 
       
    62     my $strlen = length($line);
       
    63     if (($strlen == 0) || (ord "$line" == 13)) {
       
    64        if ($verbose) { print "Line#: $linenum is an empty line.\n"; }
       
    65     } else {
       
    66 		$line =~ s/\r$//;	# chomp CR
       
    67         if ($line =~ /^#/) {
       
    68             # we are dealing with a comment line
       
    69             $line .= "\n";
       
    70             push(@comments, "$line");
       
    71             while((my $component, my $file_handle) = each(%file_handles_text)) {
       
    72                 print $file_handle "$line"
       
    73             }
       
    74         }
       
    75         else {
       
    76             #we are dealing with a component line so check the correct line format and determine if it is ascii or binary
       
    77             my @list = split("\t", $line);
       
    78 
       
    79             my $linetype = "$list[2]";
       
    80 
       
    81             if (ord "$linetype" == 97) {
       
    82                 # this is ascii, so return a CR/LF to line
       
    83                 $line .= "\n";
       
    84                 my $component = lc($list[0] . ($singleLevel? "": "_$list[1]") . ".log");
       
    85                 if (not exists $file_handles_text{$component}) {
       
    86                     # we haven't seen this component before
       
    87                     local *OUTFILE;
       
    88                     open(OUTFILE, "> $component") or die "ERROR. Line $linenum: can't open file \"$component\" for output: $!";
       
    89                     foreach my $comment (@comments) {
       
    90                         print OUTFILE "$comment";
       
    91                     }
       
    92                     $file_handles_text{$component} = *OUTFILE;
       
    93                 }
       
    94                 my $file_handle = $file_handles_text{$component};
       
    95                 print $file_handle "$line";
       
    96             } elsif (ord "$linetype" == 98) {
       
    97                 #assume it is binary
       
    98                 my $component = "$list[0]_$list[1].bin";
       
    99                 if (not exists $file_handles_binary{$component}) {
       
   100                     # we haven't seen this component before
       
   101                     local *OUTFILE;
       
   102                     open(OUTFILE, "> $component") or die "ERROR. Line $linenum: can't open file \"$component\" for output: $!";
       
   103                     binmode(OUTFILE);
       
   104                     $file_handles_binary{$component} = *OUTFILE;
       
   105                 }
       
   106 
       
   107                 # go back to start of line since CR/LF might even occur in the length field,
       
   108                 # then read to each tab until the binary tag is found again
       
   109                 seek(INPUT_FILE,$filepos,0);
       
   110 
       
   111                 my $old_rs = $/;
       
   112                 $/ = chr(9);
       
   113                 do {
       
   114                     $_ = <INPUT_FILE>;
       
   115                 } while ((ord "$_" != 98) && (length != 1));
       
   116                 $/ = $old_rs;
       
   117 
       
   118                 # read the length as a "little-endian" 4-byte unsigned integer
       
   119 				my $datalenstr;
       
   120                 my $numread = read(INPUT_FILE,$datalenstr,4);
       
   121                 if ($numread != 4) { die "ERROR: did not read all 4 bytes binary data length on line $linenum"; }
       
   122 
       
   123                 my $datatoread = unpack("v",$datalenstr);
       
   124 
       
   125                 # read next char and ensure it is a tab
       
   126 				my $onechar;
       
   127                 $numread = read(INPUT_FILE,$onechar,1);
       
   128                 if ($numread != 1) { die "ERROR: read error when reading tab char in binary line on line $linenum"; }
       
   129                 if (ord $onechar != 9) { die "ERROR: No tab char in binary line at pos : $filepos where expected between length and data at line $linenum"; }
       
   130 
       
   131                 if ($verbose) {
       
   132                     print "About to read binary data. Beginning of line is at pos: $filepos ";
       
   133                     printf " [%X] Tags: ",$filepos;
       
   134                     foreach my $d (@list) {
       
   135                        print "[$d]";
       
   136                     }
       
   137                     print "\nBytes to read: $datatoread\n";
       
   138                 }
       
   139 
       
   140 				my $datastr;
       
   141                 $numread = read(INPUT_FILE,$datastr,$datatoread);
       
   142                 if ($datatoread != $numread) { die "ERROR: only read $numread of expected $datatoread bytes binary data on line $linenum"; }
       
   143 
       
   144                 if ($verbose) { print "Read Completed.\n"; }
       
   145 
       
   146 
       
   147                 my $file_handle = $file_handles_binary{$component};
       
   148                 print $file_handle "$datastr";
       
   149 
       
   150                 # finally, read in the trailing CR/LF before reverting to textual reading
       
   151                 $_ = <INPUT_FILE>;
       
   152         
       
   153             } else {
       
   154                 if ($verbose) {
       
   155                     print "Line# $linenum at filepos $filepos is CORRUPT: linetype field is neither ascii nor binary so ignoring.\n";
       
   156                     print "Line fields: ";
       
   157                     foreach my $d (@list) {
       
   158                        print "[$d]";
       
   159                     }
       
   160                     print "\n     ... skipping line and continuing\n";
       
   161                 }
       
   162 
       
   163             }
       
   164         } # comment line check
       
   165     } #empty line check
       
   166     $filepos = tell(INPUT_FILE);
       
   167     #print "filepos at end of line proc: $filepos . input rec #: $.";
       
   168     #printf "[%X]\n",$filepos;
       
   169     $linenum++;
       
   170 }
       
   171 
       
   172 # and finally clean up
       
   173 close(INPUT_FILE) or die "ERROR: failed to close the input log file: $!";
       
   174 my $firstFile = 1;
       
   175 while((my $component, my $file_handle) = each(%file_handles_text)) 
       
   176 {
       
   177 	printf "%s%s", $firstFile? "Generated: ": ", ", $component;
       
   178 	$firstFile = 0;
       
   179     close($file_handle) or die "ERROR: failed to close the output log file for \"$component\": $!";
       
   180 }
       
   181 while((my $component, my $file_handle) = each(%file_handles_binary)) 
       
   182 {
       
   183 	printf "%s%s", $firstFile? "Generated: ": ", ", $component;
       
   184 	$firstFile = 0;
       
   185     close($file_handle) or die "ERROR: failed to close the output log file for \"$component\": $!";
       
   186 }
       
   187 print "\n";
       
   188 
       
   189 
       
   190 sub Usage () {
       
   191 print $fromBatchFile? "Common Usage: splitlog [logfile] [-v][-1]\n": "Args: [logfile] [-v][-1]\n";
       
   192     print <<ENDHERESTRING;
       
   193 Where:
       
   194   [logfile] = CDU log file (default: {EPOCROOT}\\EPOC32\\WINS[CW]\\C\\LOGS\\LOG.TXT)
       
   195   [-v]      = verbose output
       
   196   [-1]      = split only at component level (one file per unique first tag)
       
   197    
       
   198 Input Log file format:
       
   199  as specified in the FLOGGER documentation.  Briefly, there are three
       
   200  types of log messages:
       
   201    1) Comment lines.  These contain a '#' character at the beginning of
       
   202       the line.
       
   203    2) Ascii Log lines.  Contains tab separated fields - the first being the 
       
   204       name of the component that logged that particular message.
       
   205    3) Binary Log lines. Same fields as an ascii line but then contains
       
   206       a specified number of bytes of raw data. 
       
   207 
       
   208 Output:
       
   209  This script will create a number of files in the current 
       
   210  directory - one for each component found in the input log file.  Each
       
   211  file will have the same name as the first two tags separated by an underscore.
       
   212  If the component is logging ascii test, its output log file will contain all
       
   213  comment lines, and all log lines relating to that particular component.
       
   214  If the component is logging binary data, only the actual data is placed in
       
   215  the output log file.
       
   216  Ascii output files are given the extension *.log while binary files have
       
   217  extension *.bin
       
   218 
       
   219 "Out of Memory":
       
   220   error may mean the file is corrupt and the script tried to
       
   221   read a section of binary data which isn't there. Try rerunning with the "-v"
       
   222   flag to help diagnose. File position numbers reported should correlate exactly
       
   223   with the byte position if displaying file in a hex editor.
       
   224 ENDHERESTRING
       
   225 
       
   226     exit 1;
       
   227 }