summaryrefslogtreecommitdiffstats
path: root/modules-available/statistics/hooks
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/statistics/hooks')
-rw-r--r--modules-available/statistics/hooks/config-tgz.inc.php4
-rw-r--r--modules-available/statistics/hooks/cron.inc.php58
-rw-r--r--modules-available/statistics/hooks/locations-column.inc.php150
-rw-r--r--modules-available/statistics/hooks/translation.inc.php4
4 files changed, 194 insertions, 22 deletions
diff --git a/modules-available/statistics/hooks/config-tgz.inc.php b/modules-available/statistics/hooks/config-tgz.inc.php
index 8dffbff6..b732fd7a 100644
--- a/modules-available/statistics/hooks/config-tgz.inc.php
+++ b/modules-available/statistics/hooks/config-tgz.inc.php
@@ -4,12 +4,12 @@ $res = Database::simpleQuery('SELECT h.hwname FROM statistic_hw h'
. " INNER JOIN statistic_hw_prop p ON (h.hwid = p.hwid AND p.prop = :projector)"
. " WHERE h.hwtype = :screen ORDER BY h.hwname ASC", array(
'projector' => 'projector',
- 'screen' => DeviceType::SCREEN,
+ 'screen' => HardwareInfo::SCREEN,
));
if ($res !== false) { // CHeck this in case we're running on old DB during update
$content = '';
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ foreach ($res as $row) {
$content .= $row['hwname'] . "=beamer\n";
}
diff --git a/modules-available/statistics/hooks/cron.inc.php b/modules-available/statistics/hooks/cron.inc.php
index 0de233a8..4ba5e2f6 100644
--- a/modules-available/statistics/hooks/cron.inc.php
+++ b/modules-available/statistics/hooks/cron.inc.php
@@ -9,12 +9,42 @@ function logstats()
$join = 'LEFT JOIN runmode r USING (machineuuid)';
$where = 'AND (r.isclient IS NULL OR r.isclient <> 0)';
}
- $known = Database::queryFirst("SELECT Count(*) AS val FROM machine m $join WHERE m.lastseen > $cutoff $where");
- $on = Database::queryFirst("SELECT Count(*) AS val FROM machine m $join WHERE m.state IN ('IDLE', 'OCCUPIED') $where");
- $used = Database::queryFirst("SELECT Count(*) AS val FROM machine m $join WHERE m.state = 'OCCUPIED' $where");
+ // Get total/online/in-use
+ $known = Database::queryKeyValueList("SELECT locationid, Count(*) AS val FROM machine m
+ $join WHERE m.lastseen > $cutoff $where
+ GROUP BY locationid");
+ $on = Database::queryKeyValueList("SELECT locationid, Count(*) AS val FROM machine m
+ $join WHERE m.state IN ('IDLE', 'OCCUPIED') $where
+ GROUP BY locationid");
+ $used = Database::queryKeyValueList("SELECT locationid, Count(*) AS val FROM machine m
+ $join WHERE m.state = 'OCCUPIED' $where
+ GROUP BY locationid");
+ // Get calendar data if available
+ if (Module::isAvailable('locationinfo')) {
+ // Refresh all calendars around 07:00
+ $calendars = LocationInfo::getAllCalendars(date('G') != 7 || date('i') >= 10);
+ }
+ // Mash together
+ $data = ['usage' => []];
+ foreach ($known as $lid => $val) {
+ $entry = ['t' => $val];
+ if (isset($on[$lid])) {
+ $entry['o'] = $on[$lid];
+ }
+ if (isset($used[$lid])) {
+ $entry['u'] = $used[$lid];
+ }
+ if (isset($calendars[$lid])) {
+ $title = LocationInfo::extractCurrentEvent($calendars[$lid]);
+ if (!empty($title)) {
+ $entry['event'] = $title;
+ }
+ }
+ $data['usage'][$lid] = $entry;
+ }
Database::exec("INSERT INTO statistic (dateline, typeid, clientip, username, data) VALUES (:now, '~stats', '', '', :vals)", array(
'now' => $NOW,
- 'vals' => $known['val'] . '#' . $on['val'] . '#' . $used['val'],
+ 'vals' => json_encode($data),
));
}
@@ -26,18 +56,12 @@ function state_cleanup()
// Query for logging
$res = Database::simpleQuery("SELECT machineuuid, clientip, state, logintime, lastseen, live_memfree, live_swapfree, live_tmpfree
FROM machine WHERE lastseen < If(state = 'STANDBY', $standby, $on) AND state <> 'OFFLINE'");
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- Database::exec('INSERT INTO clientlog (dateline, logtypeid, clientip, machineuuid, description, extra)
- VALUES (UNIX_TIMESTAMP(), :type, :client, :uuid, :description, :longdesc)', array(
- 'type' => 'machine-mismatch-cron',
- 'client' => $row['clientip'],
- 'description' => 'Client timed out, last known state is ' . $row['state']
- . '. Free RAM: ' . Util::readableFileSize($row['live_memfree'], -1, 2)
- . ', free Swap: ' . Util::readableFileSize($row['live_swapfree'], -1, 2)
- . ', free ID44: ' . Util::readableFileSize($row['live_tmpfree'], -1, 2),
- 'longdesc' => '',
- 'uuid' => $row['machineuuid'],
- ));
+ foreach ($res as $row) {
+ ClientLog::write($row, 'machine-mismatch-cron',
+ 'Client timed out, last known state is ' . $row['state']
+ . '. Free RAM: ' . Util::readableFileSize($row['live_memfree'], -1, 2)
+ . ', free Swap: ' . Util::readableFileSize($row['live_swapfree'], -1, 2)
+ . ', free ID44: ' . Util::readableFileSize($row['live_tmpfree'], -1, 2));
if ($row['state'] === 'OCCUPIED') {
$length = $row['lastseen'] - $row['logintime'];
if ($length > 0 && $length < 86400 * 7) {
@@ -59,7 +83,7 @@ state_cleanup();
logstats();
if (mt_rand(1, 10) === 1) {
- Database::exec("DELETE FROM statistic WHERE (UNIX_TIMESTAMP() - 86400 * 190) > dateline");
+ Database::exec("DELETE FROM statistic WHERE (UNIX_TIMESTAMP() - 86400 * 365 * 2) > dateline");
if (mt_rand(1, 100) === 1) {
Database::exec("OPTIMIZE TABLE statistic");
}
diff --git a/modules-available/statistics/hooks/locations-column.inc.php b/modules-available/statistics/hooks/locations-column.inc.php
new file mode 100644
index 00000000..51f280be
--- /dev/null
+++ b/modules-available/statistics/hooks/locations-column.inc.php
@@ -0,0 +1,150 @@
+<?php
+
+if (!User::hasPermission('.statistics.view.list')) {
+ return null;
+}
+
+class ClientCountLocationColumn extends AbstractLocationColumn
+{
+
+ private $lookup;
+
+ public function __construct()
+ {
+ $this->lookup = StatisticsColumnGetData([]);
+ }
+
+ public function getColumnHtml(int $locationId): string
+ {
+ if (!isset($this->lookup[$locationId]))
+ return '';
+ if ($this->lookup[$locationId]['hasChild'] ?? false) {
+ $child = <<<EOF
+ (<a href="?do=Statistics&amp;show=list&amp;filters=location~{$locationId}">&downarrow;{$this->lookup[$locationId]['clientCountSum']}</a>)
+EOF;
+ } else {
+ $child = '';
+ }
+
+ return <<<EOF
+ <div class="pull-right">
+ <a href="?do=Statistics&amp;show=list&amp;filters=location={$locationId}">&nbsp;{$this->lookup[$locationId]['clientCount']}&nbsp;</a>
+ <span class="text-right" style="display:inline-block;width:6ex">$child</span>
+ </div>
+EOF;
+ }
+
+ public function getEditUrl(int $locationId): string
+ {
+ return '';
+ }
+
+ public function header(): string
+ {
+ return Dictionary::translateFileModule('statistics', 'module', 'location-column-header-count');
+ }
+
+ public function priority(): int
+ {
+ return 800;
+ }
+
+}
+
+class ClientLoadLocationColumn extends AbstractLocationColumn
+{
+
+ private $lookup;
+
+ public function __construct()
+ {
+ $this->lookup = StatisticsColumnGetData([]);
+ }
+
+ public function getColumnHtml(int $locationId): string
+ {
+ if (!isset($this->lookup[$locationId]) || $this->lookup[$locationId]['clientCount'] === 0)
+ return '';
+ $c =& $this->lookup[$locationId];
+ return <<<EOF
+ <div class="load-col text-right" style="background:linear-gradient(to right, #f97, #f97 {$c['clientLoad']}%,
+ #6fa {$c['clientLoad']}%, #6fa {$c['clientIdle']}%, #eee {$c['clientIdle']}%)">
+ {$c['clientLoad']}&thinsp;%
+ </div>
+EOF;
+
+ }
+
+ public function getEditUrl(int $locationId): string
+ {
+ return '';
+ }
+
+ public function header(): string
+ {
+ return Dictionary::translateFileModule('statistics', 'module', 'location-column-header-load');
+ }
+
+ public function priority(): int
+ {
+ return 900;
+ }
+
+}
+
+function StatisticsColumnGetData(array $allowedLocationIds): array
+{
+ static $data = [];
+ if (!empty($data))
+ return $data;
+ $extra = '';
+ if (in_array(0, $allowedLocationIds)) {
+ $extra = ' OR locationid IS NULL';
+ }
+ $locs = Location::getLocationsAssoc();
+ $res = Database::simpleQuery("SELECT m.locationid, Count(*) AS cnt,
+ Sum(If(m.state = 'OCCUPIED', 1, 0)) AS used, Sum(If(m.state = 'IDLE', 1, 0)) AS idle
+ FROM machine m WHERE (locationid IN (:allowedLocationIds) $extra) GROUP BY locationid", compact('allowedLocationIds'));
+ foreach ($res as $row) {
+ $locId = (int)$row['locationid'];
+ $data[$locId] = [
+ 'clientCount' => $row['cnt'],
+ 'clientLoad' => round(100 * $row['used'] / $row['cnt']),
+ 'clientIdle' => round(100 * ($row['used'] + $row['idle']) / $row['cnt']),
+ ];
+ }
+ foreach ($allowedLocationIds as $locId) {
+ if (isset($data[$locId]))
+ continue;
+ $data[$locId] = [
+ 'clientCount' => 0,
+ 'clientLoad' => 0,
+ 'clientIdle' => 0,
+ ];
+ }
+ foreach ($data as $locId => &$loc) {
+ if (!in_array($locId, $allowedLocationIds))
+ continue;
+ if (!isset($loc['clientCountSum'])) {
+ $loc['clientCountSum'] = 0;
+ }
+ $loc['clientCountSum'] += $loc['clientCount'];
+ if ($locId !== 0) {
+ foreach ($locs[$locId]['parents'] as $pid) {
+ if (!in_array($pid, $allowedLocationIds))
+ continue;
+ $data[$pid]['hasChild'] = true;
+ if (!isset($data[$pid]['clientCountSum'])) {
+ $data[$pid]['clientCountSum'] = 0;
+ }
+ $data[$pid]['clientCountSum'] += $loc['clientCount'];
+ }
+ }
+ }
+ unset($loc);
+ return $data;
+}
+
+StatisticsColumnGetData($allowedLocationIds);
+
+return [new ClientCountLocationColumn(), new ClientLoadLocationColumn()]; \ No newline at end of file
diff --git a/modules-available/statistics/hooks/translation.inc.php b/modules-available/statistics/hooks/translation.inc.php
index 4d09553a..f7a50b0d 100644
--- a/modules-available/statistics/hooks/translation.inc.php
+++ b/modules-available/statistics/hooks/translation.inc.php
@@ -16,10 +16,8 @@ $HANDLER['subsections'] = array(
/**
* Configuration categories.
- * @param \Module $module
- * @return array
*/
-$HANDLER['grep_filters'] = function($module) {
+$HANDLER['grep_filters'] = function (Module $module): array {
if (!$module->activate(1, false))
return array();
$want = StatisticsFilter::$columns;