From a1b44825ffd402ca79a011568efe5a6e097b42a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=85kre=20Solberg?= <andreas.solberg@uninett.no> Date: Thu, 26 Feb 2009 13:14:02 +0000 Subject: [PATCH] Improvements to statistics module... git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@1331 44740490-163a-0410-bde0-09ae8108e29a --- modules/statistics/lib/Aggregator.php | 7 +- modules/statistics/lib/Graph/GoogleCharts.php | 41 ++++++-- .../statistics/templates/statistics-tpl.php | 79 +++++++++----- modules/statistics/www/resources/calendar.png | Bin 0 -> 1665 bytes modules/statistics/www/resources/report.png | Bin 0 -> 1321 bytes modules/statistics/www/showstats.php | 96 +++++++++++++----- 6 files changed, 167 insertions(+), 56 deletions(-) create mode 100644 modules/statistics/www/resources/calendar.png create mode 100644 modules/statistics/www/resources/report.png diff --git a/modules/statistics/lib/Aggregator.php b/modules/statistics/lib/Aggregator.php index 4ba6e362e..345b44638 100644 --- a/modules/statistics/lib/Aggregator.php +++ b/modules/statistics/lib/Aggregator.php @@ -58,10 +58,11 @@ class sspmod_statistics_Aggregator { $i = 0; // Parse through log file, line by line foreach ($logfile AS $logline) { - $i++; + // Continue if STAT is not found on line. if (!preg_match('/STAT/', $logline)) continue; - + $i++; + // Parse log, and extract epoch time and rest of content. $epoch = $logparser->parseEpoch($logline); $content = $logparser->parseContent($logline); @@ -72,7 +73,7 @@ class sspmod_statistics_Aggregator { echo('Log line: ' . $logline . "\n"); echo('Date parse [' . substr($logline, 0, $this->statconfig->getValue('datelength', 15)) . '] to [' . date(DATE_RFC822, $epoch) . ']' . "\n"); print_r($content); - if ($i > 2) exit; + if ($i >= 13) exit; } diff --git a/modules/statistics/lib/Graph/GoogleCharts.php b/modules/statistics/lib/Graph/GoogleCharts.php index f11231597..787843a8c 100644 --- a/modules/statistics/lib/Graph/GoogleCharts.php +++ b/modules/statistics/lib/Graph/GoogleCharts.php @@ -28,10 +28,33 @@ class sspmod_statistics_Graph_GoogleCharts { } # t:10.0,58.0,95.0 - private function encodedata($data) { - return 't:' . join(',', $data); + private function encodedata($datasets) { + $setstr = array(); + foreach ($datasets AS $dataset) { + $setstr[] = join(',', $dataset); + } + return 't:' . join('|', $setstr); } + + + /** + * Return colors between multiple graphs... + */ + private function getFillArea($datasets) { + if (count($datasets) < 2) return ''; + + $colors = array('eeeeee', 'cccccc', 'aaaaaa', '99eecc'); + $num = count($datasets) ; + $colstr = array(); + for ($i = 0; $i < $num; $i++) { + $colstr[] = 'b' . ',' . $colors[$i] . ',' . ($i) . ',' . ($i+1) . ',0'; + } + return '&chm=' . join('|', $colstr); + } + + + /** * Generate a Google Charts URL which points to a generated image. * More documentation on Google Charts here: @@ -39,19 +62,23 @@ class sspmod_statistics_Graph_GoogleCharts { * * @param $axis Axis * @param $axpis Axis positions - * @param $values Dataset values + * @param $datasets Datasets values * @param $max Max value. Will be the topmost value on the Y-axis. */ - public function show($axis, $axispos, $values, $max) { + public function show($axis, $axispos, $datasets, $max) { - $nv = count($values); $url = 'http://chart.apis.google.com/chart?' . // Dimension of graph. Default is 800x350 'chs=' . $this->x . 'x' . $this->y . // Dateset values. - '&chd=' . $this->encodedata($values) . + '&chd=' . $this->encodedata($datasets) . + + // Fill area... + $this->getFillArea($datasets) . + + // chart type is linechart '&cht=lc' . '&chxt=x,y' . '&chxl=0:|' . $this->encodeaxis($axis) . # . $'|1:||top' . @@ -59,7 +86,7 @@ class sspmod_statistics_Graph_GoogleCharts { # '&chxp=0,0.3,0.4' . '&chxr=0,0,1|1,0,' . $max . # '&chm=R,CCCCCC,0,0.25,0.5' . - '&chg=' . (2400/(count($values)-1)) . ',20,3,3'; // lines + '&chg=' . (2400/(count($datasets[0])-1)) . ',20,3,3'; // lines return $url; } diff --git a/modules/statistics/templates/statistics-tpl.php b/modules/statistics/templates/statistics-tpl.php index 9fa4a51f1..caf06c1ed 100644 --- a/modules/statistics/templates/statistics-tpl.php +++ b/modules/statistics/templates/statistics-tpl.php @@ -50,8 +50,15 @@ $this->includeAtTemplateBase('includes/header.php'); echo('<h1>'. $this->data['available.rules'][$this->data['selected.rule']]['name'] . '</h1>'); echo('<p>' . $this->data['available.rules'][$this->data['selected.rule']]['descr'] . '</p>'); -echo '<div class="selecttime" style="border: 1px solid #ccc; background: #eee; margin: 5px 0px; padding: .5em">'; -echo '<div style="display: inline">'; + + + +// Report settings +echo '<table class="selecttime" style="width: 100%; border: 1px solid #ccc; background: #eee; margin: 1px 0px; padding: 0px">'; +echo('<tr><td style="width: 50px; padding: 0px"><img style="margin: 0px" src="' . SimpleSAML_Module::getModuleURL("statistics/resources/report.png") . '" alt="Report settings" /></td>'); + +// Select report +echo '<td>'; echo '<form style="display: inline"><select onChange="submit();" name="rule">'; foreach ($this->data['available.rules'] AS $key => $rule) { if ($key === $this->data['selected.rule']) { @@ -61,12 +68,45 @@ foreach ($this->data['available.rules'] AS $key => $rule) { } } echo '</select></form>'; -echo '</div>'; +echo '</td>'; + + +// Select delimiter +echo '<td style="text-align: right">'; +echo '<form style="display: inline">'; +echo '<input type="hidden" name="rule" value="' . $this->data['selected.rule'] . '" />'; +echo '<input type="hidden" name="time" value="' . $this->data['selected.time'] . '" />'; +echo '<select onChange="submit();" name="d">'; +foreach ($this->data['availdelimiters'] AS $key => $delim) { + if ($key == '_') { + echo '<option value="_">Total</option>'; + } elseif ($delim == $_REQUEST['d']) { + echo '<option selected="selected" value="' . $delim . '">' . $delim . '</option>'; + } else { + echo '<option value="' . $delim . '">' . $delim . '</option>'; + } +} +echo '</select></form>'; +echo '</td>'; + +echo '</table>'; + +// End report settings -echo '<div style="display: inline">'; +// Select time and date +echo '<table class="selecttime" style="width: 100%; border: 1px solid #ccc; background: #eee; margin: 1px 0px; padding: 0px">'; +echo('<tr><td style="width: 50px; padding: 0px"><img style="margin: 0px" src="' . SimpleSAML_Module::getModuleURL("statistics/resources/calendar.png") . '" alt="Select date and time" /></td>'); + +if (isset($this->data['available.times.prev'])) { + echo('<td style=""><a href="showstats.php?rule=' . $this->data['selected.rule']. '&time=' . $this->data['available.times.prev'] . '">« Previous</a></td>'); +} else { + echo('<td style="color: #ccc">« Previous</td>'); +} + +echo '<td style="text-align: center">'; echo '<form style="display: inline">'; echo '<input type="hidden" name="rule" value="' . $this->data['selected.rule'] . '" />'; echo '<select onChange="submit();" name="time">'; @@ -78,30 +118,23 @@ foreach ($this->data['available.times'] AS $key => $timedescr) { } } echo '</select></form>'; -echo '</div>'; +echo '</td>'; + +if (isset($this->data['available.times.next'])) { + echo('<td style="text-align: right; padding-right: 4px"><a href="showstats.php?rule=' . $this->data['selected.rule']. '&time=' . $this->data['available.times.next'] . '">Next »</a></td>'); +} else { + echo('<td style="color: #ccc; text-align: right; padding-right: 4px">Next »</td>'); +} + + + + +echo '</tr></table>'; -echo '<div style="display: inline">'; -echo '<form style="display: inline">'; -echo '<input type="hidden" name="rule" value="' . $this->data['selected.rule'] . '" />'; -echo '<input type="hidden" name="time" value="' . $this->data['selected.time'] . '" />'; -echo '<select onChange="submit();" name="d">'; -foreach ($this->data['availdelimiters'] AS $key => $delim) { - if ($key == '_') { - echo '<option value="_">Total</option>'; - } elseif ($delim == $_REQUEST['d']) { - echo '<option selected="selected" value="' . $delim . '">' . $delim . '</option>'; - } else { - echo '<option value="' . $delim . '">' . $delim . '</option>'; - } -} -echo '</select></form>'; -echo '</div>'; -echo '<div style="clear: both; height: 0px"></div>'; -echo '</div>'; echo '<div id="tabdiv"><ul class="tabset_tabs"> diff --git a/modules/statistics/www/resources/calendar.png b/modules/statistics/www/resources/calendar.png new file mode 100644 index 0000000000000000000000000000000000000000..91ff723ee03e74bdc82f947e5300565ff7155dc7 GIT binary patch literal 1665 zcmV-{27dX8P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3labT3lag+-G2N4000McNliru(+LF=CmF(iQSJZ$06ug@ zSad^gZEa<4bO1wgWnpw>WFU8GbZ8({Xk{QrNlj1+3MgYKATls8GayP~Yjt8ECu(VJ zZDC_4AX9W@X>Mh5Co}I@000HVNkl<Zc-rljPiz#|9mhZK&&+z9uGhN;gX7xk2xSpz z))pXKp@tsf(xwuZ%E+RTxaHuSIG|qWp;94-Mr!XpaR?mR^pp}Ik@8303J!~^6bB-$ zS2A^Ea8%W>-aqW_yf@Rs?pnjdCXviBKj~>^-kX{4_x;}Q_x=6gd;8wDv3>jYy|1+n z9mm<}uoDv#zuyi=Z?_PJ;i+4<Zc(jPX|-B}VHjWk#$3;Y5C|avs8lNQ+_`h_0lx#n z?@Yk={r$~mlXAJdBTqVxL$lcgkU$V8u@wOUj08bY_dJiohY#<Fz@tZxFvciAb-`aq zKy=4+DwUG?e4b=7xg!FPA3tVzc-Y(6*cb$!#7W34z!flh;J|?a*L8Os%&AlgAPJ0g z@x*o>5ZxCvFm?L$>5NheV=M@0x7%F4bcuWS?oq8)*|lpIlleS9f9D;N$t0yxiNAmH z3Ds(qU%&e<`FtKB1g@JPpU+b+mtP0UfQb^2vEBCw{A~aJ{a9<U)?kgLUaN8C$`#hv z*U9B_+`W63KYaKhAOH1ZHYydAl-$36pUamo^Y70;$M`<h7_2qS%*-%8KK@%E6T#Zj z0}5~enNFuMz5x*eg8qJwix)4__I;i;8mv8DqwvoHeSHZW?J)7$YaBm*oP~u27Qgs{ zS>H!V1p;PfW+)U22Ub>Aa==;_E8HpuB=Ck(>J`uH$5?|g7GpYBfWTVLpFhuM|M-l( zd-syd<xpA?1_5K^<47qPNG3bqSc45L*=&~4(NTBz?%gNjaUf&h68K>*ms3i~F0jEE zA7czb5Fn)B<jGl%9XrO-(h^s%US)lK9b*gw$s|XQ9tEIQt6@y%_<Y~z%$YM{WMt%5 zKwp%EiV)CU_n$a*>eTdGZ~dg-7)ua@SR2r2)G^i|5DX6wlSm{em&;5}PV(xjqj+8) z)oPVWrNYqA5K>Cg=?p>$!Z5_qnx{{ndJ78+P2hG{lu(hg*MJM0oS&cnaW<QkK@buI z0oEF>eEKPuKKh7yz0Ts|BG<29$MZZq&*RXcL#(c@a_!nRlF202TFT`zUw-+3H{bjb zj@C$}IC$`&Tv%9m{mGLj>&BRSK&azcptYVzr_<V4iwHZBVr{_QJ$n#BQYw`YLXgR1 z7#|;J=Iys}9ft=G?(_B9*95}>p64+&HAO0wLa7e8)|$S)J}z9iFmm?n*$?XV`YX%J z%YTlhULWA4QmF^UVlgA7d`?i>?KZ7e3uDZt#(SQJQfjj>DWwoX;CUX7;{f2gE?Q}{ zqft`Q_Wkh2jT?>G+1dX#o6TS9m?q@3*8Lp;G7yG@-FTHs;q~_;!jMpi%`kQx2iJ9R z9EUIjDLWbFI4)8Ol+qny2v)xOiuw8ZTB%g}SF_pt4e%cw%YZ#n%0Ab1H_NH(x@fJx zQGQ+5-Q00>^xpA(pLV-VtyZH_sZb~sXfzu5zInF1y!<Di)Dxm;4R~X0Y^?S0;lsqr z$_j*_w0iCsg1};}CG6#qkZ7f-R4SXm08&a4i3E*CgUrwnuIn;AJx!rdP+djTfQfoQ z0b{9D>Q<xC_{HGh;CCuE)^>y{nM|T}$KCPuR;$HeD#e{Uces7~_C}Y01NhGo&{|Ii zL9kXR6ihao)i1NfYq#61uC9_!rxV$1c5-oX@ozv&N8Im9DSt3MJ-z4V&6^ct%up{5 zUZ$Nmabl!cEdI2cb<L;_Xk$!!Zf<UBZf*`C1o2dS8Md^vB#Oo22#^4@?pCD$2!bH^ z<B=mrK8O^Hm+69D3Jqj3nZNYrL^l{*AO#F`hue)(87UlMtFCs7x$p(o5U@ZC_#f~z zs)UK28pa5ySlQkVJbvGM4kFJ%w<Br;b>La=2zqUj?JlYau#9&x-?H;Kfhc$oA>ji? z#H3in+B305Jc!6o#WrMKbOce4gkqbvJU+)3U?M^y{1)$QM~eRgy1RXIP;@EI00000 LNkvXXu0mjf1_>4N literal 0 HcmV?d00001 diff --git a/modules/statistics/www/resources/report.png b/modules/statistics/www/resources/report.png new file mode 100644 index 0000000000000000000000000000000000000000..3afe8a2b956c8ce4fdd3c2cb99b8c12c58204e51 GIT binary patch literal 1321 zcmV+^1=jkBP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800004b3#c}2nYxW zd<bNS00009a7bBm000fw000fw0YWI7cmMzZ8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H11g1$uK~z|U#g^M|R8<tlf9p)=4$_;Fid8Nam2!;@F_AzFh$JS0 zu`z;F@WtDsKC3bQ0T^FQ)QHjIr4J?oQ6M42OOz;)a*+^92P+O~YD;g^nK?6a_VVG( zv@@M^>JTKZWM`k8y>iyKzV)rOkEkmDr`6qvbLY;^j%YBrKkqn8EwNNkqbf!$Rl#z^ z;x9Ynyxh~%^YbkM5DkX*ukTp5a^2dshzN?Js$f7-`V&{0j-U9h2WY(|0CM^K{SVyN zM*GTjsG6$tB}>~lcKpP`-Me?+*4^Db@t*?#5D^Cc=wobjr0T4`p~(fB%T=SR6~H@P z(h`vHTNtOyF(y)aZxn<lF~(tRbQoi*V~mXsgF3+u>)_<RT>+#7+Ol$Wfx0iVh3xCE z9ngU}0fZ#{_QJcCJh!G}LogDXR}8KkJ~c-CN&(x>lFQk?88tUHFco^5XE!zw4c8$8 zb|w@0z4xbGR|hV|fX;G%ncar(b_KJKcfJ@7hePy@HqbZT#Dz;2NvBe5-MoRe<tu!H z0~n)x_4PqUMy|8EeHF_a$5~!KOrZdWzj)6c3EK5<?$@j@1I97o=)46unNco|Hn3;! zUS4|T1s-~^oor@`b7y{?69B+Hi<-IIpP*~c^L+Zr$1IB{2}N$h3I<pJ5x^e+fQSWv zV;~lbv1#KbjvhPuuYt>L`x85e$K$Ais-Osnz^u9F3Bag@F*BZ9HgDz8EstSY79uje zmp^;$C3DN{4Zy<FgmP_^f|Z_2d%;nL$1@Zho%SjBok>VBRKA;&0i+T@If(Lg_VOST zQ#tDAM_J##r~+I$2*qVUJV1Cdpja3W24=HxZ8$|Log+Ck;R$g1dq!t8PzwVpR#geS zSV*PwsH$&?N@ny%0jN|=I<L$`gvqq+>r=r%NrWEeqXElP1G587rgNaxS<e=s78&r; zKusd_%Wf)@#~9;zUQvP@)&No^LN693(>5iyxma+M@$Pt^>)1lg+zhxP%uNq0KL(T; z5!PM;=GH)I|LBb!6;p984Y>5zItQe>1YYaFk+W=n^)tG^J>%&&{XL_g)f3Ve!0ayY ztM8%jFEMyM#pg%P&B;Qk3%tzdE~vbW{1|v@^9pXSkFj&xYNXgX#u!qm6v<?g{{DWq z15`mQyh>2h9PpcT&um@Au5D|k&y6t*4Gl3kI7lj$B9TZC2??qO74J6mWuTVJ$cuK{ zwiy^0AQFjCC=^&0I9>dM_SQgMSpWgpx6?w!y^I1D*tSh`bF(+jS*EJAwzhKq{CRqN zPjiQrWS*pO|KQzR?HnQ^qQwmB#QpsV6v0?77?*)NgGoO8;C){K`GGLTP#?+D8n`mu zP3~|LIh7y=WJRO^ICVe>hypPngcbaAV(jm`qm7GMT*$JRM9smgt);jN`GSMV=f)46 zBmy)686X`f29E;^fR=`s#=_~oHKAxD1*2l;^4#o7O-<^BU%qjE>`fm2?W!h#0^k6S z6f=(l^MQJx<=%y?ez-00NH{<ozk9TH)0`o5vfugP;x*0yNnjM11f~SH_N7vko^Lj& fFBsg+^QH9<!PHBMI<!+j00000NkvXXu0mjfd*NaA literal 0 HcmV?d00001 diff --git a/modules/statistics/www/showstats.php b/modules/statistics/www/showstats.php index c41de5dad..0cc4c9096 100644 --- a/modules/statistics/www/showstats.php +++ b/modules/statistics/www/showstats.php @@ -63,6 +63,18 @@ if (array_key_exists('time', $_GET)) { } } +// Extract previous and next time slots... +$available_times_prev = NULL; $available_times_next = NULL; +$timeslots = array_keys($available_times); +$timeslotindex = array_flip($timeslots); + +if ($timeslotindex[$fileslot] > 0) + $available_times_prev = $timeslots[$timeslotindex[$fileslot]-1]; +if ($timeslotindex[$fileslot] < (count($timeslotindex)-1) ) + $available_times_next = $timeslots[$timeslotindex[$fileslot]+1]; + + + // Get file and extract results. $resultFileName = $statdir . $rule . '-' . $fileslot . '.stat'; if (!file_exists($resultFileName)) @@ -74,10 +86,6 @@ $results = unserialize($resultfile); if (empty($results)) throw new Exception('Aggregated statistics in file [' . $resultFileName . '] was empty.'); -$dataset = array(); -$axis = array(); -$axispos = array(); -$max = 15; /* @@ -99,13 +107,20 @@ if (isset($_REQUEST['d'])) { $maxvalue = 0; $maxvaluetime = 0; $debugdata = array(); + + +$maxdelimiter = $delimiter; +if (array_key_exists('graph.total', $statrules[$rule]) && $statrules[$rule]['graph.total'] === TRUE) { + $maxdelimiter = '_'; +} + foreach($results AS $slot => &$res) { - if (!array_key_exists($delimiter, $res)) $res[$delimiter] = 0; - if ($res[$delimiter] > $maxvalue) { + if (!array_key_exists($maxdelimiter, $res)) $res[$maxdelimiter] = 0; + if ($res[$maxdelimiter] > $maxvalue) { $maxvaluetime = $datehandler->prettyDateSlot($slot, $slotsize, $dateformat_intra); } - $maxvalue = max($res[$delimiter],$maxvalue); - $debugdata[] = array($datehandler->prettyDateSlot($slot, $slotsize, $dateformat_intra), $res[$delimiter] ); + $maxvalue = max($res[$maxdelimiter],$maxvalue); + $debugdata[] = array($datehandler->prettyDateSlot($slot, $slotsize, $dateformat_intra), $res[$maxdelimiter] ); } $max = sspmod_statistics_Graph_GoogleCharts::roof($maxvalue); @@ -133,41 +148,76 @@ $summaryDataset = array_reverse($summaryDataset, TRUE); #echo '<pre>'; print_r($summaryDataset); exit; -/* - * Walk through dataset to get percent values from max into dataset[]. - */ + + + + +$datasets = array(); +$axis = array(); +$axispos = array(); +#$max = 25; $availdelimiters = array(); $xentries = count($results); $lastslot = 0; $i = 0; -foreach($results AS $slot => $res) { - $dataset[] = number_format(100*$res[$delimiter] / $max, 2); - foreach(array_keys($res) AS $nd) $availdelimiters[$nd] = 1; +/* + * Walk through dataset to get percent values from max into dataset[]. + */ +function getPercentValues($results, $delimiter) { + + #echo('<pre>'); print_r($results); exit; + + global $slot, $slotsize, $dateformat_intra, $axis, $axispos, $availdelimiters, $max, $datehandler, $axislabelint, $i, $xentries; + + $dataset = array(); + foreach($results AS $slot => $res) { + #echo ('<p>new value: ' . number_format(100*$res[$delimiter] / $max, 2)); + if (array_key_exists($delimiter, $res)) { + $dataset[] = number_format(100*$res[$delimiter] / $max, 2); + } else { + $dataset[] = '0'; + } + foreach(array_keys($res) AS $nd) $availdelimiters[$nd] = 1; + + // check if there should be an axis here... + if ( $slot % $axislabelint == 0) { + $axis[] = $datehandler->prettyDateSlot($slot, $slotsize, $dateformat_intra); + $axispos[] = (($i)/($xentries-1)); + #echo 'set axis on [' . $slot . ']'; + } + $lastslot = $slot; + $i++; + } + + return $dataset; +} - // check if there should be an axis here... - if ( $slot % $axislabelint == 0) { - $axis[] = $datehandler->prettyDateSlot($slot, $slotsize, $dateformat_intra); - $axispos[] = (($i)/($xentries-1)); - - #echo 'set axis on [' . $slot . ']'; + +$datasets[] = getPercentValues($results, '_'); +if ($delimiter !== '_') { + if (array_key_exists('graph.total', $statrules[$rule]) && $statrules[$rule]['graph.total'] === TRUE) { + $datasets[] = getPercentValues($results, $delimiter); } - $lastslot = $slot; - $i++; } + #echo 'set axis on lastslot [' . $lastslot . ']'; $axis[] = $datehandler->prettyDateSlot($lastslot+1, $slotsize, $dateformat_intra); #print_r($axis); + + $dimx = $statconfig->getValue('dimension.x', 800); $dimy = $statconfig->getValue('dimension.y', 350); $grapher = new sspmod_statistics_Graph_GoogleCharts($dimx, $dimy); $t = new SimpleSAML_XHTML_Template($config, 'statistics:statistics-tpl.php'); $t->data['header'] = 'stat'; -$t->data['imgurl'] = $grapher->show($axis, $axispos, $dataset, $max); +$t->data['imgurl'] = $grapher->show($axis, $axispos, $datasets, $max); $t->data['available.rules'] = $available_rules; $t->data['available.times'] = $available_times; +$t->data['available.times.prev'] = $available_times_prev; +$t->data['available.times.next'] = $available_times_next; $t->data['selected.rule']= $rule; $t->data['selected.time'] = $fileslot; $t->data['debugdata'] = $debugdata; -- GitLab