2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-22 14:16:42 +00:00

98_apptime:introduce pause/cont - update documentation

git-svn-id: https://svn.fhem.de/fhem/trunk@14072 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
martinp876 2017-04-22 12:21:39 +00:00
parent 7c192dbfb6
commit f23d15d21e

View File

@ -15,8 +15,10 @@ use vars qw(%intAt);
use vars qw($nextat); use vars qw($nextat);
sub apptime_Initialize($); sub apptime_Initialize($);
my $apptimeStatus;
sub apptime_Initialize($){ sub apptime_Initialize($){
$apptimeStatus = 1;#set active by default
$cmds{"apptime"}{Fn} = "apptime_CommandDispTiming"; $cmds{"apptime"}{Fn} = "apptime_CommandDispTiming";
$cmds{"apptime"}{Hlp} = "[clear|<field>] [top|all] [<filter>],application function calls and duration"; $cmds{"apptime"}{Hlp} = "[clear|<field>] [top|all] [<filter>],application function calls and duration";
} }
@ -80,37 +82,42 @@ sub CallFn(@) {
sub apptime_getTiming($$$@) { sub apptime_getTiming($$$@) {
my ($e,$fnName,$fn,$tim,@arg) = @_; my ($e,$fnName,$fn,$tim,@arg) = @_;
my $h; my $h;
if (!$defs{$e}{helper} || my $ts1;
!$defs{$e}{helper}{bm} || if ($apptimeStatus){
!$defs{$e}{helper}{bm}{$fnName} ){ if (!$defs{$e}{helper} ||
!$defs{$e}{helper}{bm} ||
!$defs{$e}{helper}{bm}{$fnName} ){
%{$defs{$e}{helper}{bm}{$fnName}} =(max =>0, mAr =>"", %{$defs{$e}{helper}{bm}{$fnName}} =(max =>0, mAr =>"",
cnt =>1, tot =>0, cnt =>1, tot =>0,
dmx =>0); dmx =>0);
$h = $defs{$e}{helper}{bm}{$fnName}; $h = $defs{$e}{helper}{bm}{$fnName};
} }
else{ else{
$h = $defs{$e}{helper}{bm}{$fnName}; $h = $defs{$e}{helper}{bm}{$fnName};
$h->{cnt}++; $h->{cnt}++;
} }
my $ts1 = gettimeofday(); $ts1 = gettimeofday();
if ($tim){ if ($tim){
my $td = int(($ts1-$tim)*1000); my $td = int(($ts1-$tim)*1000);
$h->{dmx} = $td if ($h->{dmx} < $td); $h->{dmx} = $td if ($h->{dmx} < $td);
}
} }
no strict "refs"; no strict "refs";
my @ret = &{$fn}(@arg); my @ret = &{$fn}(@arg);
use strict "refs"; use strict "refs";
$ts1 = int((gettimeofday()-$ts1)*1000); if ($apptimeStatus){
if ($ts1 && $h->{max}<$ts1){ $ts1 = int((gettimeofday()-$ts1)*1000);
$h->{max}=$ts1; if ($ts1 && $h->{max} < $ts1){
$h->{mAr}= \@arg; $h->{max} = $ts1;
} $h->{mAr} = \@arg;
}
$h->{tot}+=$ts1; $h->{tot} += $ts1;
}
return @ret; return @ret;
} }
@ -120,51 +127,63 @@ sub apptime_CommandDispTiming($$@) {
my ($sFld,$top,$filter) = split" ",$param; my ($sFld,$top,$filter) = split" ",$param;
$sFld = "max" if (!$sFld); $sFld = "max" if (!$sFld);
$top = "top" if (!$top); $top = "top" if (!$top);
my %fld = (name=>0,funktion=>1,max=>2,count=>3,total=>4,average=>5,maxDly=>6,clear=>99); my %fld = (name=>0,funktion=>1,max=>2,count=>3,total=>4,average=>5,maxDly=>6,cont=>98,pause=>98,clear=>99);
return "$sFld undefined field, use one of ".join(",",keys %fld) return "$sFld undefined field, use one of ".join(",",keys %fld)
if(!defined $fld{$sFld}); if(!defined $fld{$sFld});
my @bmArr; my @bmArr;
my @a = map{"$defs{$_}:$_"} keys (%defs); # prepare mapping hash 2 name my @a = map{"$defs{$_}:$_"} keys (%defs); # prepare mapping hash 2 name
$_ =~ s/[HASH\(\)]//g foreach(@a); $_ =~ s/[HASH\(\)]//g foreach(@a);
if ($sFld eq "pause"){# no further collection of data, clear also
$apptimeStatus = 0;#stop collecting data
}
elsif ($sFld eq "cont"){# no further collection of data, clear also
$apptimeStatus = 1;#continue collecting data
}
foreach my $d (sort keys %defs) { foreach my $d (sort keys %defs) {
next if(!$defs{$d}{helper}||!$defs{$d}{helper}{bm}); next if(!$defs{$d}{helper}||!$defs{$d}{helper}{bm});
if ($sFld eq "clear"){ if ($sFld eq "clear"){
delete $defs{$d}{helper}{bm}; delete $defs{$d}{helper}{bm};
next;
} }
foreach my $f (sort keys %{$defs{$d}{helper}{bm}}) { elsif ($sFld =~ m/(pause|cont)/){
next if(!defined $defs{$d}{helper}{bm}{$f}{cnt}); }
next if($filter && $d !~ m/$filter/ && $f !~ m/$filter/); else{
my ($n,$t) = ($d,$f); foreach my $f (sort keys %{$defs{$d}{helper}{bm}}) {
($n,$t) = split(";",$f,2) if ($d eq "global"); next if(!defined $defs{$d}{helper}{bm}{$f}{cnt});
$t = "" if (!defined $t); next if($filter && $d !~ m/$filter/ && $f !~ m/$filter/);
my $h = $defs{$d}{helper}{bm}{$f}; my ($n,$t) = ($d,$f);
($n,$t) = split(";",$f,2) if ($d eq "global");
$t = "" if (!defined $t);
my $h = $defs{$d}{helper}{bm}{$f};
my $arg = ""; my $arg = "";
if ($h->{mAr} && scalar(@{$h->{mAr}})){ if ($h->{mAr} && scalar(@{$h->{mAr}})){
foreach my $i (0..scalar(@{$h->{mAr}})){ foreach my $i (0..scalar(@{$h->{mAr}})){
if(ref(${$h->{mAr}}[$i]) eq 'HASH' and exists(${$h->{mAr}}[$i]->{NAME})){ if(ref(${$h->{mAr}}[$i]) eq 'HASH' and exists(${$h->{mAr}}[$i]->{NAME})){
${$h->{mAr}}[$i] = "HASH(".${$h->{mAr}}[$i]->{NAME}.")"; ${$h->{mAr}}[$i] = "HASH(".${$h->{mAr}}[$i]->{NAME}.")";
}
} }
$arg = join ("; ",@{$h->{mAr}});
} }
$arg = join ("; ",@{$h->{mAr}});
}
push @bmArr,[($n,$t push @bmArr,[($n,$t
,$h->{max} ,$h->{max}
,$h->{cnt} ,$h->{cnt}
,$h->{tot} ,$h->{tot}
,$h->{tot} /$h->{cnt} ,$h->{tot} /$h->{cnt}
,$h->{dmx} ,$h->{dmx}
,$arg ,$arg
)]; )];
}
} }
} }
my $field = $fld{$sFld}; my $field = $fld{$sFld};
if ($field>1){@bmArr = sort { $b->[$field] <=> $a->[$field] } @bmArr;} if ($field>1){@bmArr = sort { $b->[$field] <=> $a->[$field] } @bmArr;}
else {@bmArr = sort { $b->[$field] cmp $a->[$field] } @bmArr;} else {@bmArr = sort { $b->[$field] cmp $a->[$field] } @bmArr;}
my $ret = sprintf("\n %35s %20s %6s %6s %8s %8s %s", my $ret = ($apptimeStatus ? "" : "------ apptime PAUSED data collection ----------\n")
"name","function","max","count","total","average","maxDly","param Max call"); .sprintf("\n %35s %20s %6s %6s %8s %8s %s",
"name","function","max","count","total","average","maxDly","param Max call");
my $end = ($top && $top eq "top")?20:@bmArr-1; my $end = ($top && $top eq "top")?20:@bmArr-1;
$end = @bmArr-1 if ($end>@bmArr-1); $end = @bmArr-1 if ($end>@bmArr-1);
@ -176,63 +195,129 @@ sub apptime_CommandDispTiming($$@) {
=pod =pod
=item command =item command
=item summary support to analyse function performance =item summary support to analyse function performance
=item summary_DE unterstuetzung der analyse der Performance von Funktionen =item summary_DE Unterst&uuml;tzung bei der Performanceanalyse von Funktionen
=begin html =begin html
<a name="apptime"></a> <a name="apptime"></a>
<h3>apptime</h3> <h3>apptime</h3>
<ul> <div style="padding-left: 2ex;">
<code>apptime</code> <h4><code>apptime</code></h4>
<br> <p>
<br> apptime provides information about application procedure execution time.
apptime provides information about application procedure execution time. It is designed to identify long running jobs causing latency as well as
It is designed to identify long runner jobs causing latency as well as general high <abbr>CPU</abbr> usage jobs.
overall high cpu usage jobs<br> </p>
No information about FHEM kernel times and delays will be provided. <br> <p>
Once started apptime monitors tasks. User may reset counter during operation. No information about <abbr>FHEM</abbr> kernel times and delays will be provided.
apptime adds about 1% CPU load in average to FHEM. </p>
in order to remove apptime shutdown restart is necessary. <p>
<br> Once started, apptime monitors tasks. User may reset counter during operation.
<br> apptime adds about 1% <abbr>CPU</abbr> load in average to <abbr>FHEM</abbr>.
<b>Features:</b><br> </p>
<ul> <p>
<li><code>apptime</code><br> In order to remove apptime, <kbd>shutdown restart</kbd> is necessary.
apptime is started with the its first call nad continously monitor operation.<br> </p>
To unload apptime shutdown restart is necessary<br> </li> <p>
<li><code>apptime clear</code><br> <strong>Features</strong>
reset all counter and start fom Zero<br> </li> </P>
<li><code>apptime [count|funktion|average|clear|max|name|total] [all]</code><br> <dl>
display a table sorted by the field selected<br> <dt><code><kbd>apptime</kbd></code></dt>
<b>all</b> will display the complete table while by default only the top lines are printed. <br></li> <dd>
</ul> <p>
<br> <kbd>apptime</kbd> is started with the its first call and continously monitor operations.<br>
<b>Columns:</b><br> To unload apptime, <kbd>shutdown restart</kbd> is necessary.<br> </li>
<ul> </p>
<li><b>name</b><br> </dd>
name of the entity executing the procedure<br> <dt><code><kbd>apptime clear</code></dt>
if it is a function called by InternalTimer the name starts with <b>tmr-</b>. <dd>
by then it gives the name of the funktion to be called<br> <p>
</li> Reset all counter and start from zero.
<li><b>function</b><br> </p>
procedure name which was executed<br> </dd>
if it is an InternalTimer call it gives its calling parameter <br> <dt><code><kbd>apptime pause</code></dt>
</li> <dd>
<li><b>max</b><br> <p>
longest duration measured for this procedure in ms <br> </li> Suspend accumulation of data. Data is not cleared.
<li><b>count</b><br> </p>
number of calls for this procedure<br> </li> </dd>
<li><b>total</b><br> <dt><code><kbd>apptime cont</code></dt>
accumulated duration of this procedure over all calls monitored<br> </li> <dd>
<li><b>average</b><br> <p>
average time a call of this procedure takes<br> </li> Continue data collection after pause.
<li><b>maxDly</b><br> </p>
maximum delay of a timer call to its schedules time. This column is not relevant </dd>
for non-timer calls.<br> </li> <dt><code><kbd>apptime [count|funktion|average|clear|max|name|total] [all]</kbd></code></dt>
<li><b>param Max call</b><br> <dd>
gives the parameter of the call with the max duration<br> </li> <p>
</ul> Display a table sorted by the field selected.
<br> </p>
</ul> <p>
<strong><kbd>all</kbd></strong> will display the complete table while by default only the top lines are printed.<
</p>
</dd>
</dl>
<p>
<strong>Columns:</strong>
</p>
<dl>
<dt><strong>name</strong></dt>
<dd>
<p>
Name of the entity executing the procedure.
</p>
<p>
If it is a function called by InternalTimer the name starts with <var>tmr-</var>.
By then it gives the name of the function to be called.
</p>
</dd>
<dt><strong>funktion</strong><dt>
<dd>
<p>
Procedure name which was executed.
</p>
<p>
If it is an <var>InternalTimer</var> call it gives its calling parameter.
</p>
</dd>
<dt><strong>max</strong></dt>
<dd>
<p>
Longest duration measured for this procedure in <abbr>ms</abbr>.
</p>
</dd>
<dt><strong>count</strong></dt>
<dd>
<p>
Number of calls for this procedure.
</p>
</dt>
<dt><strong>total</strong></dt>
<dd>
<p>
Accumulated duration of this procedure over all calls monitored.
</p>
</dd>
<dt><strong>average</strong></dt>
<dd>
<p>
Average time a call of this procedure takes.
</p>
</dd>
<dt><strong>maxDly</strong></dt>
<dd>
<p>
Maximum delay of a timer call to its schedules time.
This column is not relevant for non-timer calls.
</p>
</dd>
<dt><strong>param Max call</strong></dt>
<dd>
<p>
Gives the parameter of the call with the longest duration.
</p>
</dd>
</dl>
</div>
=end html =end html
=cut =cut