summaryrefslogtreecommitdiffstats
path: root/modules-available/statistics/pages
diff options
context:
space:
mode:
authorSimon Rettberg2022-12-02 15:21:26 +0100
committerSimon Rettberg2022-12-02 15:24:08 +0100
commit200d92c8491d5060af5dd839aa82d1e51b058dd6 (patch)
treeafd9274f2de28b4c387f08550712629798883b26 /modules-available/statistics/pages
parent[inc/ArrayUtil] Fix sort flag handling (diff)
downloadslx-admin-200d92c8491d5060af5dd839aa82d1e51b058dd6.tar.gz
slx-admin-200d92c8491d5060af5dd839aa82d1e51b058dd6.tar.xz
slx-admin-200d92c8491d5060af5dd839aa82d1e51b058dd6.zip
[statistics] Per-location usage stats; include active lecture count
Diffstat (limited to 'modules-available/statistics/pages')
-rw-r--r--modules-available/statistics/pages/summary.inc.php102
1 files changed, 83 insertions, 19 deletions
diff --git a/modules-available/statistics/pages/summary.inc.php b/modules-available/statistics/pages/summary.inc.php
index cf3e745d..53b028fc 100644
--- a/modules-available/statistics/pages/summary.inc.php
+++ b/modules-available/statistics/pages/summary.inc.php
@@ -44,7 +44,7 @@ class SubPage
/**
* @param \StatisticsFilterSet $filterSet
*/
- private static function showSummary($filterSet)
+ private static function showSummary(StatisticsFilterSet $filterSet)
{
$filterSet->makeFragments($where, $join, $args);
$known = Database::queryFirst("SELECT Count(*) AS val FROM machine m $join WHERE $where", $args);
@@ -56,36 +56,74 @@ class SubPage
} else {
$usedpercent = 0;
}
- $data = array(
+ $data = [
'known' => $known['val'],
'online' => $on['val'],
'used' => $used['val'],
'usedpercent' => $usedpercent,
'badhdd' => $hdd['val'],
- );
+ ];
// Graph
+ // Get locations
+ $locFilter = $filterSet->hasFilter('LocationStatisticsFilter');
+ if ($locFilter === null || ($locFilter->op === '~' && (int)$locFilter->argument === 0)) {
+ $locations = null;
+ $op = null;
+ } elseif ($locFilter->op === '~') {
+ $locations = array_keys(Location::getRecursiveFlat($locFilter->argument));
+ $op = $locFilter->op;
+ } else {
+ $locations = [$locFilter->argument];
+ $op = $locFilter->op;
+ }
+ //error_log($op . ' ' . print_r($locations, true));
$cutoff = time() - 2 * 86400;
- $res = Database::simpleQuery("SELECT dateline, data FROM statistic WHERE typeid = '~stats' AND dateline > $cutoff ORDER BY dateline ASC");
- $labels = array();
- $points1 = array('data' => array(), 'label' => 'Online', 'borderColor' => '#8eb');
- $points2 = array('data' => array(), 'label' => 'In use', 'borderColor' => '#fa9');
+ $res = Database::simpleQuery("SELECT dateline, data FROM statistic
+ WHERE typeid = '~stats' AND dateline > $cutoff ORDER BY dateline DESC");
+ $labels = [];
+ $points1 = [];
+ $points2 = [];
+ $lectures = [];
+ // Get max from 6 consecutive values, which should be 6*5 = 30m
$sum = 0;
foreach ($res as $row) {
- $x = explode('#', $row['data']);
- if ($sum === 0) {
+ if ($row['data'][0] === '{') {
+ $x = json_decode($row['data'], true);
+ if (!is_array($x) || !isset($x['usage']))
+ continue;
+ $x = self::mangleStatsJson($x, $locations, $op);
+ } else if ($locations === null) {
+ $x = explode('#', $row['data']);
+ if (count($x) < 3)
+ continue;
+ $x[] = 0;
+ } else {
+ continue;
+ }
+ if ($sum % 4 === 0) {
$labels[] = date('H:i', $row['dateline']);
} else {
- $x[1] = max($x[1], array_pop($points1['data']));
- $x[2] = max($x[2], array_pop($points2['data']));
+ $x[1] = max($x[1], array_pop($points1));
+ $x[2] = max($x[2], array_pop($points2));
+ $x[3] += array_pop($lectures);
}
- $points1['data'][] = $x[1];
- $points2['data'][] = $x[2];
+ $points1[] = $x[1];
+ $points2[] = $x[2];
+ $lectures[] = $x[3];
++$sum;
- if ($sum === 12) {
- $sum = 0;
- }
}
- $data['json'] = json_encode(array('labels' => $labels, 'datasets' => array($points1, $points2)));
+ if (!empty($points1) && max(...$points1) > 0) {
+ $labels = array_reverse($labels);
+ $points1 = array_reverse($points1);
+ $points2 = array_reverse($points2);
+ $lectures = array_reverse($lectures);
+ $data['json'] = json_encode(['labels' => $labels,
+ 'datasets' => [
+ ['data' => $points1, 'label' => 'Online', 'borderColor' => '#8f3'],
+ ['data' => $points2, 'label' => 'In use', 'borderColor' => '#e76'],
+ ]]);
+ $data['markings'] = json_encode($lectures, true);
+ }
if (Module::get('runmode') !== false) {
$res = Database::queryFirst('SELECT Count(*) AS cnt FROM machine m INNER JOIN runmode r USING (machineuuid)'
. " $join WHERE $where", $args);
@@ -238,14 +276,15 @@ class SubPage
/**
* @param \StatisticsFilterSet $filterSet
*/
- private static function showLatestMachines($filterSet)
+ private static function showLatestMachines(StatisticsFilterSet $filterSet)
{
$filterSet->makeFragments($where, $join, $args);
$args['cutoff'] = ceil(time() / 3600) * 3600 - 86400 * 10;
$res = Database::simpleQuery("SELECT m.machineuuid, m.clientip, m.hostname, m.firstseen, m.mbram, m.kvmstate, m.id44mb
FROM machine m $join
- WHERE firstseen > :cutoff AND $where ORDER BY firstseen DESC LIMIT 32", $args);
+ WHERE firstseen > :cutoff AND $where
+ ORDER BY firstseen DESC LIMIT 32", $args);
$rows = array();
$count = 0;
foreach ($res as $row) {
@@ -306,4 +345,29 @@ class SubPage
}
}
+ /**
+ * @param array $json decoded json ~stats data
+ * @param ?int[] $locations
+ * @param ?string $op
+ */
+ private static function mangleStatsJson(array $json, $locations, $op): array
+ {
+ // Total, On, InUse, Lectures
+ $retval = [0, 0, 0, 0];
+ foreach ($json['usage'] as $lid => $data) {
+ $lid = (int)$lid;
+ if ($locations === null
+ || ($op === '!=' && !in_array($lid, $locations))
+ || ($op !== '!=' && in_array($lid, $locations))) {
+ $retval[0] += $data['t'];
+ $retval[1] += $data['o'] ?? 0;
+ $retval[2] += $data['u'] ?? 0;
+ if (isset($data['event'])) {
+ $retval[3] += 1;
+ }
+ }
+ }
+ return $retval;
+ }
+
}