os/persistentdata/traceservices/commsdebugutility/tools/extractlog.pl
author sl
Tue, 10 Jun 2014 14:32:02 +0200 (2014-06-10)
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 }