use XML::Simple; use Data::Dumper; my $file = 'c:\siebel\sarm.xml'; my $timedivider = 1000000; #unix should be set to 1000000000 my $xs1 = XML::Simple->new(); my $doc = $xs1->XMLin($file, KeyAttr => 'Name'); #this bit of trickery from XML::Simple transforms the top level objcect to Name #print Dumper($doc); #dumper will show how the xml has been translated my %speed; #hash of responsetime totals for top level names my %childspeed; #hash of totalcontribute times for the children of the component with the greates responsetime my %childcalldiff; #hash of childrens differential between percentage of time and percentage call my $mosttime; #used to track the top level name area that takes most total time my $childmosttime; #used to foreach my $key (keys (%{$doc})){ #get ResponseTime->Total for each toplevel object (SMI, SWE,Scripting Engine,Database,SarmIO,etc) foreach $names (keys %{ $doc->{$key} }) { my $responsetotal = $doc->{$key}->{$names}->{ResponseTime}->{Total}; $speed{$responsetotal} = $names ; } } #sort and print the groups that take longest to shortest print "Sorting time for all toplevel names...\n"; $mosttime = sorthash(%speed); print "$mosttime = component that took most time\n"; #get min,max,average for top level componenent that takes the most time my $min = $doc->{Group}->{$mosttime}->{ResponseTime}->{Min}; my $max = $doc->{Group}->{$mosttime}->{ResponseTime}->{Max}; my $average = $doc->{Group}->{$mosttime}->{ResponseTime}->{Average}; #convert to seconds my $smin = $min / $timedivider; my $smax = $max / $timedivider; my $saverage = $average / $timedivider; print "\t$mosttime min response = $smin\n"; print "\t$mosttime max response time = $smax\n"; print "\t$mosttime average = $saverage\n"; #analyize children for the $mosttime component, to determine which of the children take the most time print "Analyzing children for $mosttime....\n"; foreach my $child (keys %{ $doc->{Group}->{$mosttime}->{Children}->{ChildGroup} }) { my $totaltime = $doc->{Group}->{$mosttime}->{Children}->{ChildGroup}->{$child}->{TotalContributedTime}; $childspeed{$totaltime} = $child ; my $percent_time = $doc->{Group}->{$mosttime}->{Children}->{ChildGroup}->{$child}->{PercentageTime}; my $percent_calls = $doc->{Group}->{$mosttime}->{Children}->{ChildGroup}->{$child}->{PercentageCalls}; my $calldif = $percent_time / $percent_calls ; $childcalldiff{$calldif} = $child; #print "calldiff = $calldif\n"; } print "Printing children for $mosttime ordered by TotalContributedTime\n"; $childmosttime = sorthash(%childspeed); print "$mosttime child component that took most time = $childmosttime\n"; print "Printing children for $mosttime ordered by PercentageTime / PercentageCalls - the higher the worse\n"; $childbiggestdiff = sortnodevidehash(%childcalldiff); #sorthash is used to reverse sort and print hashes where the key is numeric value sub sorthash { my %lspeed = @_; my $lmosttime; my @keys = sort {$b <=> $a} keys %lspeed; foreach $time (@keys) { my $seconds = $time / $timedivider; print "\t$lspeed{$time}, in seconds = $seconds \n"; unless ($lmosttime) {$lmosttime = $lspeed{$time}} } return $lmosttime; } sub sortnodevidehash { my %lspeed = @_; my $lmosttime; my @keys = sort {$b <=> $a} keys %lspeed; foreach $time (@keys) { print "\t$lspeed{$time}, = $time \n"; unless ($lmosttime) {$lmosttime = $lspeed{$time}} } return $lmosttime; }