|
1 # |
|
2 # Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # |
|
16 #!perl -w |
|
17 # |
|
18 # |
|
19 |
|
20 #********************************************************************* |
|
21 # ost_metrics.pl |
|
22 # ********************************************************************* |
|
23 # |
|
24 # VERSION : 8 Draft Feb-15-2010 Adrian Issott |
|
25 # REASION : Minor update to output style and added warnings about |
|
26 # the tool being unsupported |
|
27 # |
|
28 # VERSION : 7 Draft Sep-16-2009 Adrian Issott |
|
29 # REASION : Added support for restricting output to specific |
|
30 # components |
|
31 # |
|
32 # VERSION : 6 Draft Sep-15-2009 Adrian Issott |
|
33 # REASION : Added support for older environments with dictionaries |
|
34 # under epoc32\include\internal\symbiantraces\dictionary |
|
35 # |
|
36 # VERSION : 5 Draft Sep-11-2009 Adrian Issott |
|
37 # REASION : Added trace name listing |
|
38 # Added counting of trace / group ID with lower case names |
|
39 # Made the output of detailed inforamtion optional |
|
40 # Added support for epocroots other than \ |
|
41 # Added warning about assuming epocroot=\ when it's not set |
|
42 # Fixed illegal division by zero issue when no components were found |
|
43 # |
|
44 # VERSION : 4 Draft Sep-11-2008 Esa Karvanen |
|
45 # REASION : Skip duplicate UID's when parsing |
|
46 # |
|
47 # VERSION : 3 Draft May-07-2008 Esa Karvanen |
|
48 # REASION : Changed to print amount of traces and stuff |
|
49 # |
|
50 # VERSION : 2 Draft May-06-2008 Esa Karvanen |
|
51 # REASION : Changed to calculate unique groups names |
|
52 # |
|
53 # VERSION : 1 Draft Mar-28-2008 Teemu Piiroinen |
|
54 # REASION : Initial version |
|
55 |
|
56 use strict; |
|
57 use warnings; |
|
58 use env; |
|
59 |
|
60 use Getopt::Long; |
|
61 use Pod::Usage; |
|
62 |
|
63 warn "\n"; |
|
64 warn "Warning: this script is not supported and the Dynamic Analysis Tools team\n"; |
|
65 warn "does NOT promise to fix any bugs or add any functionality to it.\n"; |
|
66 warn "\n"; |
|
67 |
|
68 my %options; |
|
69 GetOptions('h|help|?' => \$options{showHelp}, |
|
70 'm|manual' => \$options{showManual}, |
|
71 'r|restrictTo=s' => \$options{restrictTo}, |
|
72 'c|byComponent' => \$options{byComponent}, |
|
73 't|showTraceNames' => \$options{showTraceNames}, |
|
74 'l|lowerCaseNames' => \$options{lowerCaseNames}, |
|
75 ) or pod2usage(-Verbose => 0); |
|
76 pod2usage(-Verbose => 1) if ($options{showHelp}); |
|
77 pod2usage(-Verbose => 2) if ($options{showManual}); |
|
78 |
|
79 $options{byComponent} = 1 if $options{showTraceNames}; |
|
80 |
|
81 if (defined $options{restrictTo}) { |
|
82 eval "'' =~ /$options{restrictTo}/"; |
|
83 die "Invalid restrictTo pattern ($options{restrictTo}): $@\n" if $@; |
|
84 } else { |
|
85 $options{restrictTo} = '.*'; |
|
86 } |
|
87 |
|
88 my $component_count = 0; |
|
89 |
|
90 my $group_count = 0; |
|
91 my $total_group_count = 0; |
|
92 |
|
93 my $trace_count = 0; |
|
94 my $component_trace_count = 0; |
|
95 my $total_trace_count = 0; |
|
96 my @allgroups = (); |
|
97 my %hashgroups = (); |
|
98 my %uids; |
|
99 |
|
100 my $lowerCaseGroupNames = 0; |
|
101 my $lowerCaseTraceNames = 0; |
|
102 |
|
103 my $epocroot; |
|
104 if (not defined $ENV{EPOCROOT}) { |
|
105 warn "Warning: EPOCROOT not set so assuming it's \\\n"; |
|
106 $epocroot = '\\'; |
|
107 } else { |
|
108 $epocroot = $ENV{EPOCROOT}; |
|
109 } |
|
110 die "Expected the EPOCROOT ($epocroot) to be a directory\n" unless -d $epocroot; |
|
111 |
|
112 my $ost_dictionaries_dir = $epocroot.'epoc32\ost_dictionaries'; |
|
113 print "Looking for dictionaries in $ost_dictionaries_dir ...\n"; |
|
114 |
|
115 if (not -d $ost_dictionaries_dir) { |
|
116 $ost_dictionaries_dir = $epocroot.'epoc32\include\internal\symbiantraces\dictionary'; |
|
117 print "Looking for dictionaries in $ost_dictionaries_dir ...\n"; |
|
118 } |
|
119 die "Couldn't find the OST dictionaries directory\n" unless -d $ost_dictionaries_dir; |
|
120 |
|
121 print "Found the OST dictionaries directory\n"; |
|
122 print "\n"; |
|
123 |
|
124 my $dir_cmd = "dir $ost_dictionaries_dir\\*.xml /S /B 2>NUL"; |
|
125 my $dir_return = qx($dir_cmd); |
|
126 my $current_group; |
|
127 |
|
128 foreach my $file (split("\n", $dir_return)) |
|
129 { |
|
130 next unless $file =~ /$options{restrictTo}/i; |
|
131 |
|
132 # OST Autogen headers contain "_0x" in their file name |
|
133 if ($file =~ /_0x(.+?)_/i) |
|
134 { |
|
135 # Skip duplicate UID |
|
136 if (exists($uids{$1})) |
|
137 { |
|
138 warn "Warning: skipping duplicate UID in file " . $file . "\n"; |
|
139 |
|
140 } |
|
141 # This UID for the first time, parse the file |
|
142 else |
|
143 { |
|
144 $uids{$1} = 0; |
|
145 parseFile($file); |
|
146 } |
|
147 } |
|
148 # Also calculate BTraceHooksDictionary |
|
149 elsif ($file =~ m/(BTraceHooksDictionary\.xml)/i) |
|
150 { |
|
151 parseFile($file); |
|
152 } |
|
153 } |
|
154 |
|
155 # Remove duplicates from the groups list |
|
156 my %seen = (); |
|
157 my @uniq_groups = (); |
|
158 foreach my $item (@allgroups) { |
|
159 push(@uniq_groups, $item) unless $seen{$item}++; |
|
160 } |
|
161 |
|
162 |
|
163 ### OUTPUT TOTALS ### |
|
164 |
|
165 |
|
166 my @groupNames = sort keys %hashgroups; |
|
167 my $uniq_groups = scalar @groupNames; |
|
168 |
|
169 my $avg_groups = ($component_count > 0 ? sprintf "%.2f",($total_group_count / $component_count) : 0); |
|
170 |
|
171 print "\n\n--------------TOTALS--------------\n\n"; |
|
172 print "Component count: $component_count\n"; |
|
173 print "Unique group count: $uniq_groups\n"; |
|
174 print "Average groups per component: $avg_groups\n"; |
|
175 print "Trace count: $total_trace_count\n"; |
|
176 |
|
177 if ($options{lowerCaseNames}) { |
|
178 for my $groupName (@groupNames) { |
|
179 if (uc($groupName) ne $groupName) { |
|
180 $lowerCaseGroupNames++; |
|
181 } |
|
182 |
|
183 } |
|
184 |
|
185 print "\n"; |
|
186 print "Lower case Group ID names count: $lowerCaseGroupNames\n"; |
|
187 print "Lower case Trace ID names count: $lowerCaseTraceNames\n"; |
|
188 } |
|
189 |
|
190 |
|
191 ### OUTPUT GROUP ID SUMMARY ### |
|
192 |
|
193 |
|
194 # Generate new array where key is the amount of traces and value is the string to be printed |
|
195 my @group_lines = (); |
|
196 my $groupNo = 0; |
|
197 foreach my $key (@groupNames) { |
|
198 my $line = ""; |
|
199 |
|
200 # Check how many times this group can be found from all groups array |
|
201 my $occurrences = 0; |
|
202 foreach my $item (@allgroups) { |
|
203 if ($item eq $key) { |
|
204 $occurrences = $occurrences + 1; |
|
205 } |
|
206 } |
|
207 |
|
208 my $value = $hashgroups{$key}; |
|
209 |
|
210 my $trace_percents = ($total_trace_count > 0 ? sprintf "%.2f",($value / $total_trace_count) * 100 : 0); |
|
211 my $component_percents = ($component_count > 0 ? sprintf "%.2f",($occurrences / $component_count) * 100 : 0); |
|
212 |
|
213 # Add the group name |
|
214 my $i = 0; |
|
215 $line .= "$key"; |
|
216 while ((length $key) + $i < 42){ |
|
217 $line .= " "; |
|
218 $i = $i + 1; |
|
219 } |
|
220 |
|
221 # Add the number of traces |
|
222 $i = 0; |
|
223 $line .= "$value"; |
|
224 while ((length $value) + $i < 5){ |
|
225 $line .= " "; |
|
226 $i = $i + 1; |
|
227 } |
|
228 |
|
229 # Add the number of traces in percents |
|
230 $line .= "($trace_percents %)"; |
|
231 $i = 0; |
|
232 while ((length $trace_percents) + $i < 21){ |
|
233 $line .= " "; |
|
234 $i = $i + 1; |
|
235 } |
|
236 |
|
237 # Add used by no. of components |
|
238 $i = 0; |
|
239 $line .= "$occurrences"; |
|
240 while ((length $occurrences) + $i < 3){ |
|
241 $line .= " "; |
|
242 $i = $i + 1; |
|
243 } |
|
244 |
|
245 # Add used by no. of components in percents |
|
246 $line .= "($component_percents %)\n"; |
|
247 |
|
248 $group_lines[$groupNo][0] = $value; |
|
249 $group_lines[$groupNo][1] = $line; |
|
250 $groupNo = $groupNo + 1; |
|
251 } |
|
252 |
|
253 my @sorted_group_lines = reverse sort{$a->[0] <=> $b->[0]} @group_lines; #if the $id'th column is numerically |
|
254 |
|
255 print "\n\n--------------GROUP ID SUMMARY--------------\n\n"; |
|
256 print "GROUP NAME\t\t\t\tAMOUNT OF TRACES\tUSED BY NO. OF COMPONENTS\n\n"; |
|
257 |
|
258 foreach my $line (@sorted_group_lines) { |
|
259 print $$line[1]; |
|
260 } |
|
261 |
|
262 |
|
263 ####################################################################### |
|
264 # Parses file |
|
265 ####################################################################### |
|
266 sub parseFile |
|
267 { |
|
268 |
|
269 my $file = $_[0]; |
|
270 open FILE, "<$file" or die $!; |
|
271 |
|
272 foreach my $line (<FILE>) |
|
273 { |
|
274 if ($line =~ /<path val=\"(.+?)\"/i) |
|
275 { |
|
276 print "Path: $1\n" if $options{byComponent}; |
|
277 } |
|
278 |
|
279 if ($line =~ /<component id=\"-?\d+\" name=\"(.+?)\"/i) |
|
280 { |
|
281 print "Component: $1\n" if $options{byComponent}; |
|
282 |
|
283 $component_count++; |
|
284 } |
|
285 |
|
286 if ($line =~ /<group id=\"\d+\" name=\"(.+?)\"/i) |
|
287 { |
|
288 my $group = $1; |
|
289 print "\tGroup: $group\n" if $options{byComponent}; |
|
290 push(@allgroups, $group); |
|
291 |
|
292 if (not defined $hashgroups{$group}) |
|
293 { |
|
294 $hashgroups{$group} = 0; |
|
295 } |
|
296 |
|
297 $group_count++; |
|
298 $total_group_count++; |
|
299 $current_group = $group; |
|
300 |
|
301 print "\tGroup trace names:\n" if $options{showTraceNames}; |
|
302 } |
|
303 |
|
304 if ($line =~ /<\/component>/i) |
|
305 { |
|
306 if ($options{byComponent}) { |
|
307 print "\tGroup count: $group_count\n"; |
|
308 print "\tComponent trace count: $component_trace_count\n\n\n"; |
|
309 } |
|
310 |
|
311 $group_count = 0; |
|
312 $component_trace_count = 0; |
|
313 } |
|
314 if ($line =~ /<trace data-ref=\"\d+\"(?:\s+name=\"(\w+)\")?/i) |
|
315 { |
|
316 if (defined $1) { |
|
317 print "\t\t$1\n" if $options{showTraceNames}; |
|
318 if ($options{lowerCaseNames} and uc($1) ne $1) { |
|
319 $lowerCaseTraceNames++; |
|
320 } |
|
321 } |
|
322 $trace_count++; |
|
323 $component_trace_count++; |
|
324 $total_trace_count++; |
|
325 } |
|
326 |
|
327 if ($line =~ /<\/group>/i) |
|
328 { |
|
329 print "\tGroup trace count: $trace_count\n" if $options{byComponent}; |
|
330 $hashgroups{$current_group} = ($hashgroups{$current_group} + $trace_count); |
|
331 $trace_count = 0; |
|
332 } |
|
333 } |
|
334 |
|
335 close FILE; |
|
336 } |
|
337 |
|
338 warn "\n"; |
|
339 warn "Warning: this script is not supported and the Dynamic Analysis Tools team\n"; |
|
340 warn "does NOT promise to fix any bugs or add any functionality to it.\n"; |
|
341 warn "\n"; |
|
342 |
|
343 __END__ |
|
344 |
|
345 =head1 NAME |
|
346 |
|
347 ost_metrics - Prints metrics about OST usage based on the dictionaries in an EPOCROOT |
|
348 |
|
349 =head1 SYNOPSIS |
|
350 |
|
351 ost_metrics [options] |
|
352 |
|
353 =head1 OPTIONS |
|
354 |
|
355 -h (--help) Brief help message. |
|
356 -m (--manual) Full documentation. |
|
357 -r (--restrictTo) <re> Restrict the output to just dictionaries with names |
|
358 matching the regular expression re. |
|
359 -c (--byComponent) Output detailed information about the trace used in each |
|
360 component. |
|
361 -t (--showTraceNames) Output detailed information about the trace ID names used. |
|
362 Implies -byComponent |
|
363 -l (--lowerCaseNames) Count the number of lower case names in the dictionaries. |
|
364 |
|
365 =head1 DESCRIPTION |
|
366 |
|
367 This script reads in the dictionaries found under EPOCROOT\epoc32\ost_dictionaries |
|
368 and outputs the following information: |
|
369 |
|
370 =over |
|
371 |
|
372 =item 1 OST usage breakdown by component if --byComponent is specified |
|
373 |
|
374 =item 2 OST trace ID usage by component if --showTraceNames is specified |
|
375 |
|
376 =item 3 Group ID usage in the environment |
|
377 |
|
378 =item 4 Total usage in the environment |
|
379 |
|
380 =back |
|
381 |
|
382 Note that if you don't define EPOCROOT this script assumes you mean "\". |
|
383 |
|
384 =head1 SUPPORT |
|
385 |
|
386 Please note that this script is not supported and the Dynamic Analysis Tools team |
|
387 does NOT promise to fix any bugs or add any functionality to it. |
|
388 |
|
389 =head1 COPYRIGHT |
|
390 |
|
391 Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. |
|
392 |
|
393 =cut |