From ed383e2562c6ecf219620f17f87eba3ddaf8d335 Mon Sep 17 00:00:00 2001
From: Christian Hofmaier
Date: Tue, 22 Jan 2019 12:27:45 +0100
Subject: [locationinfo] some design rework - Change "free" to "open" - h/min
display in summary - do not display colors of unused states in summary -
change seatcounter to emDash when room has current event
---
modules-available/locationinfo/lang/de/template-tags.json | 3 ++-
modules-available/locationinfo/lang/en/template-tags.json | 3 ++-
.../locationinfo/templates/frontend-default.html | 11 ++++-------
.../locationinfo/templates/frontend-summary.html | 9 +++++++--
4 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/modules-available/locationinfo/lang/de/template-tags.json b/modules-available/locationinfo/lang/de/template-tags.json
index 03eb63a5..f9c7fad5 100644
--- a/modules-available/locationinfo/lang/de/template-tags.json
+++ b/modules-available/locationinfo/lang/de/template-tags.json
@@ -30,7 +30,8 @@
"lang_error": "Fehler",
"lang_expertMode": "Expertenmodus",
"lang_fourLocsHint": "Hier k\u00f6nnen Sie bis zu vier Orte ausw\u00e4hlen, die in diesem Panel angezeigt werden.",
- "lang_free": "Frei",
+ "lang_free": "Geöffnet",
+ "lang_for": "für",
"lang_general": "Allgemein",
"lang_ignoreSslTooltip": "Akzeptiere ung\u00fcltige, abgelaufene oder selbstsignierte SSL-Zertifikate",
"lang_insecureSsl": "Unsicheres SSL",
diff --git a/modules-available/locationinfo/lang/en/template-tags.json b/modules-available/locationinfo/lang/en/template-tags.json
index 1b5ab0fd..5bbe3775 100644
--- a/modules-available/locationinfo/lang/en/template-tags.json
+++ b/modules-available/locationinfo/lang/en/template-tags.json
@@ -30,7 +30,8 @@
"lang_error": "Error",
"lang_expertMode": "Expert mode",
"lang_fourLocsHint": "You can pick up to four locations that will be shown in this panel.",
- "lang_free": "Free",
+ "lang_free": "Open",
+ "lang_for": "for",
"lang_general": "General",
"lang_ignoreSslTooltip": "Accept invalid, expired or self-signed ssl certificates",
"lang_insecureSsl": "Insecure SSL",
diff --git a/modules-available/locationinfo/templates/frontend-default.html b/modules-available/locationinfo/templates/frontend-default.html
index 4dee8ef7..cbb765d0 100755
--- a/modules-available/locationinfo/templates/frontend-default.html
+++ b/modules-available/locationinfo/templates/frontend-default.html
@@ -352,6 +352,7 @@ optional:
{{lang_room}}
{{lang_closed}}
{{lang_free}}
+ {{lang_for}}
{{lang_shortSun}}
{{lang_shortMon}}
{{lang_shortTue}}
@@ -1151,7 +1152,7 @@ optional:
*/
function SetFreeSeats(room) {
// if room has no allowed value, set text in the box to -
- room.$.seatsCounter.text(room.freePcs >= 0 ? room.freePcs : '-');
+ room.$.seatsCounter.text(room.freePcs >= 0 ? room.freePcs : '\u2014');
room.$.seatsCounter.data('state', JSON.stringify(room.state));
if (room.freePcs > 0 && room.state && room.state.free) {
room.$.seatsBackground.css('background-color', '#250');
@@ -1174,8 +1175,6 @@ optional:
var seats = room.freePcs;
if (tmp.state === 'closed' || tmp.state === 'CalendarEvent' || tmp.state === 'Free') {
newTime = GetTimeDiferenceAsString(tmp.end, MyDate(), globalConfig);
- } else if (!same) {
- newTime = '';
}
if (tmp.state === "closed") {
if (!same) newText = t("closed");
@@ -1183,16 +1182,14 @@ optional:
if (!same) newText = tmp.title;
// whilst event is running set freePcs to -, hopefully not breaking anything else with this
room.freePcs = "-";
- } else if (tmp.state === "Free") {
- if (!same) newText = t("free");
- } else if (tmp.state === "FreeNoEnd") {
+ } else if (tmp.state === "Free" || tmp.state === "FreeNoEnd") {
if (!same) newText = t("free");
}
if (newText !== false) {
room.$.currentEvent.text(newText);
}
if (newTime !== false) {
- room.$.currentRemain.text(newTime);
+ room.$.currentRemain.text(t("for") + " " +newTime);
}
if (room.lastFreeSeats !== seats || !same) {
SetFreeSeats(room);
diff --git a/modules-available/locationinfo/templates/frontend-summary.html b/modules-available/locationinfo/templates/frontend-summary.html
index 95299e63..ae089da5 100644
--- a/modules-available/locationinfo/templates/frontend-summary.html
+++ b/modules-available/locationinfo/templates/frontend-summary.html
@@ -63,7 +63,7 @@
}
.pc-idle, .pc-occupied, .pc-offline, .pc-broken, .pc-standby {
- padding: 2px 1px;
+ padding: 2px 0px;
text-align: center;
font-size: 90%;
font-weight: 800;
@@ -604,7 +604,11 @@
// TODO: Add seconds again with a better update rate.
var time_split = time.split(":");
if (time != "") {
- $("#div_Time_" + id).text(time_split[0] + ":" + time_split[1]);
+ if (time_split[0] > 0) {
+ $("#div_Time_" + id).text(t("for") + " " + time_split[0] + "h " + time_split[1]+"min");
+ } else {
+ $("#div_Time_" + id).text(t("for") + " " + time_split[1]+"min");
+ }
} else {
$("#div_Time_" + id).text(time);
}
@@ -759,6 +763,7 @@
{{lang_room}}
{{lang_closed}}
{{lang_free}}
+ {{lang_for}}
{{lang_shortSun}}
{{lang_shortMon}}
{{lang_shortTue}}
--
cgit v1.2.3-55-g7522
From 0a040966751e4a45fc9b9ac6cbaaea100b38ce53 Mon Sep 17 00:00:00 2001
From: Christian Hofmaier
Date: Tue, 22 Jan 2019 16:12:28 +0100
Subject: [inc/Render] new optional argument to change rendered language
---
inc/render.inc.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/inc/render.inc.php b/inc/render.inc.php
index 4b1d3643..4da0567e 100644
--- a/inc/render.inc.php
+++ b/inc/render.inc.php
@@ -213,7 +213,7 @@ class Render
* @param string $module name of module to load template from; defaults to currently active module
* @return string Rendered template
*/
- public static function parse($template, $params = false, $module = false)
+ public static function parse($template, $params = false, $module = false, $lang = false)
{
if ($module === false && class_exists('Page')) {
$module = Page::getModule()->getIdentifier();
@@ -228,7 +228,7 @@ class Render
}
// Now find all language tags in this array
if (preg_match_all('/{{\s*(lang_.+?)\s*}}/', $html, $out) > 0) {
- $dictionary = Dictionary::getArray($module, 'template-tags');
+ $dictionary = Dictionary::getArray($module, 'template-tags', $lang);
$fallback = false;
foreach ($out[1] as $tag) {
if ($fallback === false && empty($dictionary[$tag])) {
--
cgit v1.2.3-55-g7522
From e4ff8937a3e0da4c23a97014ade75c15ae456931 Mon Sep 17 00:00:00 2001
From: Christian Hofmaier
Date: Tue, 22 Jan 2019 16:13:26 +0100
Subject: [locationinfo] use set config language for panels
---
modules-available/locationinfo/page.inc.php | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules-available/locationinfo/page.inc.php b/modules-available/locationinfo/page.inc.php
index 8ea18940..7be875d0 100644
--- a/modules-available/locationinfo/page.inc.php
+++ b/modules-available/locationinfo/page.inc.php
@@ -1002,7 +1002,7 @@ class Page_LocationInfo extends Page
'language' => $config['language'],
);
- die(Render::parse('frontend-default', $data));
+ die(Render::parse('frontend-default', $data, $module = false, $lang = $config['language']));
}
if ($type === 'SUMMARY') {
@@ -1014,7 +1014,7 @@ class Page_LocationInfo extends Page
'language' => $config['language'],
);
- die(Render::parse('frontend-summary', $data));
+ die(Render::parse('frontend-summary', $data, $module = false, $lang = $config['language']));
}
http_response_code(500);
--
cgit v1.2.3-55-g7522
From c124192e63bd8a48ed1e7caf9542dc52505dfd22 Mon Sep 17 00:00:00 2001
From: Simon Rettberg
Date: Thu, 24 Jan 2019 12:17:07 +0100
Subject: [statistics] Handling of standby state in statistics, log crashes
Or rather, not really crashes, but log whenever a client reports a
poweron event without reporting a proper shutdown first. This isn't
neccessarily a crash but could also be due to power loss, hard poweroff,
or network failures.
---
modules-available/statistics/api.inc.php | 102 +++++++++------------
modules-available/statistics/hooks/cron.inc.php | 20 +++-
modules-available/statistics/inc/parser.inc.php | 10 +-
.../statistics/inc/statistics.inc.php | 17 ++++
modules-available/statistics/page.inc.php | 29 +++++-
5 files changed, 107 insertions(+), 71 deletions(-)
diff --git a/modules-available/statistics/api.inc.php b/modules-available/statistics/api.inc.php
index 674cc48d..813e7d54 100644
--- a/modules-available/statistics/api.inc.php
+++ b/modules-available/statistics/api.inc.php
@@ -123,32 +123,20 @@ if ($type{0} === '~') {
}
}
// Maybe log old crashed session
- if ($uptime < 120) {
+ if ($uptime < 150 && $old !== false) {
// See if we have a lingering session, create statistic entry if so
- if ($old !== false && $old['logintime'] !== 0) {
+ if ($old['state'] === 'OCCUPIED' && $old['logintime'] !== 0) {
$sessionLength = $old['lastseen'] - $old['logintime'];
if ($sessionLength > 30 && $sessionLength < 86400*2) {
- Database::exec('INSERT INTO statistic (dateline, typeid, machineuuid, clientip, username, data)'
- . " VALUES (:start, '~session-length', :uuid, :clientip, '', :length)", array(
- 'start' => $old['logintime'],
- 'uuid' => $uuid,
- 'clientip' => $ip,
- 'length' => $sessionLength
- ));
+ Statistics::logMachineState($uuid, $ip, Statistics::SESSION_LENGTH, $old['logintime'], $sessionLength);
}
}
// Write poweroff period length to statistic table
- if ($old !== false && $old['lastseen'] !== 0) {
+ if ($old['lastseen'] !== 0) {
$lastSeen = $old['lastseen'];
$offtime = ($NOW - $uptime) - $lastSeen;
- if ($offtime > 300 && $offtime < 86400 * 90) {
- Database::exec('INSERT INTO statistic (dateline, typeid, machineuuid, clientip, username, data)'
- . " VALUES (:shutdown, '~offline-length', :uuid, :clientip, '', :length)", array(
- 'shutdown' => $lastSeen,
- 'uuid' => $uuid,
- 'clientip' => $ip,
- 'length' => $offtime
- ));
+ if ($offtime > 90 && $offtime < 86400 * 30) {
+ Statistics::logMachineState($uuid, $ip, $old['state'] === 'STANDBY' ? Statistics::SUSPEND_LENGTH : Statistics::OFFLINE_LENGTH, $lastSeen, $offtime);
}
}
}
@@ -173,36 +161,41 @@ if ($type{0} === '~') {
} else if ($type === '~runstate') {
// Usage (occupied/free)
$sessionLength = 0;
+ $strUpdateBoottime = '';
if ($old === false) die("Unknown machine.\n");
if ($old['clientip'] !== $ip) {
EventLog::warning("[runstate] IP address of client $uuid seems to have changed ({$old['clientip']} -> $ip)");
die("Address changed.\n");
}
$used = Request::post('used', 0, 'integer');
- if ($old['state'] === 'OFFLINE' && $NOW - $old['lastseen'] > 600) {
- $strUpdateBoottime = ' lastboot = UNIX_TIMESTAMP(), ';
- } else {
- $strUpdateBoottime = '';
- }
- // 1) Log last session length if we didn't see the machine for a while
- if ($NOW - $old['lastseen'] > 610 && $old['lastseen'] !== 0) {
- // Old session timed out - might be caused by hard reboot
- if ($old['logintime'] !== 0) {
- if ($old['lastseen'] > $old['logintime']) {
- $sessionLength = $old['lastseen'] - $old['logintime'];
- }
- $old['logintime'] = 0;
- }
- }
- // Figure out what's happening - state changes
$params = array(
'uuid' => $uuid,
'oldlastseen' => $old['lastseen'],
'oldstate' => $old['state'],
);
+ if ($old['state'] === 'OFFLINE') {
+ // This should never happen -- we expect a poweron event before runstate, which would set the state to IDLE
+ // So it might be that the poweron event got lost, or that a couple of runstate events got lost, which
+ // caused our cron.inc.php to time out the client and reset it to OFFLINE
+ if ($NOW - $old['lastseen'] > 900) {
+ $strUpdateBoottime = ' lastboot = UNIX_TIMESTAMP(), ';
+ }
+ // 1) Log last session length if we didn't see the machine for a while
+ if ($NOW - $old['lastseen'] > 900 && $old['lastseen'] !== 0) {
+ // Old session timed out - might be caused by hard reboot
+ if ($old['logintime'] !== 0) {
+ if ($old['lastseen'] > $old['logintime']) {
+ $sessionLength = $old['lastseen'] - $old['logintime'];
+ }
+ }
+ }
+ }
+ // Figure out what's happening - state changes
if ($used === 0 && $old['state'] !== 'IDLE') {
- // Is not in use, was in use before
- $sessionLength = $NOW - $old['logintime'];
+ if ($old['state'] === 'OCCUPIED' && $sessionLength === 0) {
+ // Is not in use, was in use before
+ $sessionLength = $NOW - $old['logintime'];
+ }
$res = Database::exec('UPDATE machine SET lastseen = UNIX_TIMESTAMP(),'
. $strUpdateBoottime
. " logintime = 0, currentuser = NULL, state = 'IDLE' "
@@ -232,13 +225,7 @@ if ($type{0} === '~') {
}
// 9) Log last session length if applicable
if ($mode === false && $sessionLength > 0 && $sessionLength < 86400*2 && $old['logintime'] !== 0) {
- Database::exec('INSERT INTO statistic (dateline, typeid, machineuuid, clientip, username, data)'
- . " VALUES (:start, '~session-length', :uuid, :clientip, '', :length)", array(
- 'start' => $old['logintime'],
- 'uuid' => $uuid,
- 'clientip' => $ip,
- 'length' => $sessionLength
- ));
+ Statistics::logMachineState($uuid, $ip, Statistics::SESSION_LENGTH, $old['logintime'], $sessionLength);
}
} elseif ($type === '~poweroff') {
if ($old === false) die("Unknown machine.\n");
@@ -246,16 +233,10 @@ if ($type{0} === '~') {
EventLog::warning("[poweroff] IP address of client $uuid seems to have changed ({$old['clientip']} -> $ip)");
die("Address changed.\n");
}
- if ($mode === false && $old['logintime'] !== 0) {
+ if ($mode === false && $old['state'] === 'OCCUPIED' && $old['logintime'] !== 0) {
$sessionLength = $old['lastseen'] - $old['logintime'];
if ($sessionLength > 0 && $sessionLength < 86400*2) {
- Database::exec('INSERT INTO statistic (dateline, typeid, machineuuid, clientip, username, data)'
- . " VALUES (:start, '~session-length', :uuid, :clientip, '', :length)", array(
- 'start' => $old['logintime'],
- 'uuid' => $uuid,
- 'clientip' => $ip,
- 'length' => $sessionLength
- ));
+ Statistics::logMachineState($uuid, $ip, Statistics::SESSION_LENGTH, $old['logintime'], $sessionLength);
}
}
Database::exec("UPDATE machine SET logintime = 0, lastseen = UNIX_TIMESTAMP(), state = 'OFFLINE'
@@ -368,13 +349,7 @@ if ($type{0} === '~') {
$lastSeen = $old['lastseen'];
$duration = $NOW - $lastSeen;
if ($duration > 500 && $duration < 86400 * 14) {
- Database::exec('INSERT INTO statistic (dateline, typeid, machineuuid, clientip, username, data)'
- . " VALUES (:suspend, '~suspend-length', :uuid, :clientip, '', :length)", array(
- 'suspend' => $lastSeen,
- 'uuid' => $uuid,
- 'clientip' => $ip,
- 'length' => $duration
- ));
+ Statistics::logMachineState($uuid, $ip, Statistics::SUSPEND_LENGTH, $lastSeen, $duration);
}
}
} else {
@@ -449,9 +424,14 @@ if ($type{0} === '.') {
function checkHardwareChange($old, $new)
{
if ($new['mbram'] !== 0) {
- if ($new['mbram'] + 1000 < $old['mbram']) {
- $ram1 = round($old['mbram'] / 512) / 2;
- $ram2 = round($new['mbram'] / 512) / 2;
+ if ($new['mbram'] < 6200) {
+ $ram1 = ceil($old['mbram'] / 512) / 2;
+ $ram2 = ceil($new['mbram'] / 512) / 2;
+ } else {
+ $ram1 = ceil($old['mbram'] / 1024);
+ $ram2 = ceil($new['mbram'] / 1024);
+ }
+ if ($ram1 !== $ram2) {
EventLog::warning('[poweron] Client ' . $new['uuid'] . ' (' . $new['clientip'] . "): RAM decreased from {$ram1}GB to {$ram2}GB");
}
if (!empty($old['cpumodel']) && !empty($new['cpumodel']) && $new['cpumodel'] !== $old['cpumodel']) {
diff --git a/modules-available/statistics/hooks/cron.inc.php b/modules-available/statistics/hooks/cron.inc.php
index f05762bc..0b8e740e 100644
--- a/modules-available/statistics/hooks/cron.inc.php
+++ b/modules-available/statistics/hooks/cron.inc.php
@@ -21,10 +21,11 @@ function logstats()
function state_cleanup()
{
// Fix online state of machines that crashed
- $standby = time() - 86400 * 2; // Reset standby machines after two days
+ $standby = time() - 86400 * 4; // Reset standby machines after four days
$on = time() - 610; // Reset others after ~10 minutes
// Query for logging
- $res = Database::simpleQuery("SELECT machineuuid, clientip, state FROM machine WHERE lastseen < If(state = 'STANDBY', $standby, $on) AND state <> 'OFFLINE'");
+ $res = Database::simpleQuery("SELECT machineuuid, clientip, state, logintime, lastseen 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(
@@ -34,9 +35,20 @@ function state_cleanup()
'longdesc' => '',
'uuid' => $row['machineuuid'],
));
+ if ($row['state'] === 'OCCUPIED') {
+ $length = $row['lastseen'] - $row['logintime'];
+ if ($length > 0 && $length < 86400 * 7) {
+ Statistics::logMachineState($row['machineuuid'], $row['clientip'], Statistics::SESSION_LENGTH, $row['logintime'], $length);
+ }
+ } elseif ($row['state'] === 'STANDBY') {
+ $length = time() - $row['lastseen'];
+ if ($length > 0 && $length < 86400 * 7) {
+ Statistics::logMachineState($row['machineuuid'], $row['clientip'], Statistics::SUSPEND_LENGTH, $row['lastseen'], $length);
+ }
+ }
}
- // Update -- yes this is not atomic. Should be sufficient for simple warnings though.
- Database::exec("UPDATE machine SET state = 'OFFLINE' WHERE lastseen < If(state = 'STANDBY', $standby, $on) AND state <> 'OFFLINE'");
+ // Update -- yes this is not atomic. Should be sufficient for simple warnings and bookkeeping though.
+ Database::exec("UPDATE machine SET logintime = 0, state = 'OFFLINE' WHERE lastseen < If(state = 'STANDBY', $standby, $on) AND state <> 'OFFLINE'");
}
state_cleanup();
diff --git a/modules-available/statistics/inc/parser.inc.php b/modules-available/statistics/inc/parser.inc.php
index b179b4a3..0d39079d 100644
--- a/modules-available/statistics/inc/parser.inc.php
+++ b/modules-available/statistics/inc/parser.inc.php
@@ -104,10 +104,12 @@ class Parser {
foreach ($lines as $line) {
if (preg_match('/^Disk (\S+):.* (\d+) bytes/i', $line, $out)) {
// --- Beginning of MBR disk ---
+ unset($hdd);
if ($out[2] < 10000) // sometimes vmware reports lots of 512byte disks
continue;
+ if (substr($out[1], 0, 8) === '/dev/dm-') // Ignore device mapper
+ continue;
// disk total size and name
- unset($hdd);
$mbrToMbFactor = 0; // This is != 0 for mbr
$sectorToMbFactor = 0; // This is != for gpt
$hdd = array(
@@ -122,10 +124,12 @@ class Parser {
$hdds[] = &$hdd;
} elseif (preg_match('/^Disk (\S+):\s+(\d+)\s+sectors,/i', $line, $out)) {
// --- Beginning of GPT disk ---
+ unset($hdd);
if ($out[2] < 1000) // sometimes vmware reports lots of 512byte disks
continue;
+ if (substr($out[1], 0, 8) === '/dev/dm-') // Ignore device mapper
+ continue;
// disk total size and name
- unset($hdd);
$mbrToMbFactor = 0; // This is != 0 for mbr
$sectorToMbFactor = 0; // This is != for gpt
$hdd = array(
@@ -213,7 +217,7 @@ class Parser {
$hdd['size'] = round(($hdd['sectors'] * $sectorToMbFactor) / 1024);
}
$free = $hdd['size'] - $hdd['used'];
- if ($free > 5 || ($free / $hdd['size']) > 0.1) {
+ if ($hdd['size'] > 0 && ($free > 5 || ($free / $hdd['size']) > 0.1)) {
$hdd['partitions'][] = array(
'id' => 'free-id-' . $i,
'name' => Dictionary::translate('unused'),
diff --git a/modules-available/statistics/inc/statistics.inc.php b/modules-available/statistics/inc/statistics.inc.php
index 2500f16f..1f8a081a 100644
--- a/modules-available/statistics/inc/statistics.inc.php
+++ b/modules-available/statistics/inc/statistics.inc.php
@@ -70,4 +70,21 @@ class Statistics
return $list;
}
+ const SESSION_LENGTH = '~session-length';
+ const OFFLINE_LENGTH = '~offline-length';
+ const SUSPEND_LENGTH = '~suspend-length';
+
+ public static function logMachineState($uuid, $ip, $type, $start, $length, $username = '')
+ {
+ return Database::exec('INSERT INTO statistic (dateline, typeid, machineuuid, clientip, username, data)'
+ . " VALUES (:start, :type, :uuid, :clientip, :username, :length)", array(
+ 'start' => $start,
+ 'type' => $type,
+ 'uuid' => $uuid,
+ 'clientip' => $ip,
+ 'username' => $username,
+ 'length' => $length,
+ ));
+ }
+
}
diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php
index abacc8d2..2d86615e 100644
--- a/modules-available/statistics/page.inc.php
+++ b/modules-available/statistics/page.inc.php
@@ -910,16 +910,18 @@ class Page_Statistics extends Page
//if ($cutoff < $client['firstseen']) $cutoff = $client['firstseen'];
$scale = 100 / ($NOW - $cutoff);
$res = Database::simpleQuery('SELECT dateline, typeid, data FROM statistic'
- . " WHERE dateline > :cutoff AND typeid IN ('~session-length', '~offline-length') AND machineuuid = :uuid ORDER BY dateline ASC", array(
+ . " WHERE dateline > :cutoff AND typeid IN (:sessionLength, :offlineLength) AND machineuuid = :uuid ORDER BY dateline ASC", array(
'cutoff' => $cutoff - 86400 * 14,
'uuid' => $uuid,
+ 'sessionLength' => Statistics::SESSION_LENGTH,
+ 'offlineLength' => Statistics::OFFLINE_LENGTH,
));
$spans['rows'] = array();
$spans['graph'] = '';
$last = false;
$first = true;
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- if (!$client['isclient'] && $row['typeid'] === '~session-length')
+ if (!$client['isclient'] && $row['typeid'] === Statistics::SESSION_LENGTH)
continue; // Don't differentiate between session and idle for non-clients
if ($first && $row['dateline'] > $cutoff && $client['lastboot'] > $cutoff) {
// Special case: offline before
@@ -945,9 +947,12 @@ class Page_Statistics extends Page
}
$row['from'] = Util::prettyTime($row['dateline']);
$row['duration'] = floor($row['data'] / 86400) . 'd ' . gmdate('H:i', $row['data']);
- if ($row['typeid'] === '~offline-length') {
+ if ($row['typeid'] === Statistics::OFFLINE_LENGTH) {
$row['glyph'] = 'off';
$color = '#444';
+ } elseif ($row['typeid'] === Statistics::SUSPEND_LENGTH) {
+ $row['glyph'] = 'pause';
+ $color = '#686';
} else {
$row['glyph'] = 'user';
$color = '#e77';
@@ -967,8 +972,26 @@ class Page_Statistics extends Page
}
if ($client['state'] === 'OCCUPIED') {
$spans['graph'] .= '
';
+ $spans['rows'][] = [
+ 'from' => Util::prettyTime($client['logintime']),
+ 'duration' => '-',
+ 'glyph' => 'user',
+ ];
+ $row['duration'] = floor($row['data'] / 86400) . 'd ' . gmdate('H:i', $row['data']);
} elseif ($client['state'] === 'OFFLINE') {
$spans['graph'] .= '
';
+ $spans['rows'][] = [
+ 'from' => Util::prettyTime($client['lastseen']),
+ 'duration' => '-',
+ 'glyph' => 'off',
+ ];
+ } elseif ($client['state'] === 'STANDBY') {
+ $spans['graph'] .= '
';
+ $spans['rows'][] = [
+ 'from' => Util::prettyTime($client['lastseen']),
+ 'duration' => '-',
+ 'glyph' => 'pause',
+ ];
}
$t = explode('-', date('Y-n-j-G', $cutoff));
if ($t[3] >= 8 && $t[3] <= 22) {
--
cgit v1.2.3-55-g7522
From ab6171159d5471ea1d4c1be0736ef8db230f5dcc Mon Sep 17 00:00:00 2001
From: Simon Rettberg
Date: Thu, 24 Jan 2019 14:00:31 +0100
Subject: [default.css] Make slx-table columns a bit wider
---
style/default.css | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/style/default.css b/style/default.css
index 6b0c28f6..6c2beb86 100644
--- a/style/default.css
+++ b/style/default.css
@@ -76,7 +76,7 @@ body {
}
.slx-table td {
- padding-right: 5px;
+ padding-right: 7px;
padding-bottom: 2px;
}
--
cgit v1.2.3-55-g7522
From 9ae2c70073490a253ccf2fcb567d57b07811389b Mon Sep 17 00:00:00 2001
From: Simon Rettberg
Date: Thu, 24 Jan 2019 17:31:38 +0100
Subject: [statistics] Minor refactoring (PHP >= 5.6)
---
modules-available/statistics/inc/filter.inc.php | 16 ++++---
modules-available/statistics/page.inc.php | 58 ++++++++++++-------------
2 files changed, 38 insertions(+), 36 deletions(-)
diff --git a/modules-available/statistics/inc/filter.inc.php b/modules-available/statistics/inc/filter.inc.php
index 3ccea2c3..46de467b 100644
--- a/modules-available/statistics/inc/filter.inc.php
+++ b/modules-available/statistics/inc/filter.inc.php
@@ -14,6 +14,13 @@ class Filter
public $operator;
public $argument;
+ private static $keyCounter = 0;
+
+ public static function getNewKey($colname)
+ {
+ return $colname . '_' . (self::$keyCounter++);
+ }
+
public function __construct($column, $operator, $argument = null)
{
$this->column = trim($column);
@@ -24,8 +31,7 @@ class Filter
/* returns a where clause and adds needed operators to the passed array */
public function whereClause(&$args, &$joins)
{
- global $unique_key;
- $key = $this->column . '_arg' . ($unique_key++);
+ $key = Filter::getNewKey($this->column);
$addendum = '';
/* check if we have to do some parsing*/
@@ -226,8 +232,7 @@ class StateFilter extends Filter
$map = [ 'on' => ['IDLE', 'OCCUPIED'], 'off' => ['OFFLINE'], 'idle' => ['IDLE'], 'occupied' => ['OCCUPIED'], 'standby' => ['STANDBY'] ];
$neg = $this->operator == '!=' ? 'NOT ' : '';
if (array_key_exists($this->argument, $map)) {
- global $unique_key;
- $key = $this->column . '_arg' . ($unique_key++);
+ $key = Filter::getNewKey($this->column);
$args[$key] = $map[$this->argument];
return " machine.state $neg IN ( :$key ) ";
} else {
@@ -259,8 +264,7 @@ class LocationFilter extends Filter
if ($this->argument === 0) {
return "machine.locationid IS $neg NULL";
} else {
- global $unique_key;
- $key = $this->column . '_arg' . ($unique_key++);
+ $key = Filter::getNewKey($this->column);
if ($recursive) {
$args[$key] = array_keys(Location::getRecursiveFlat($this->argument));
} else {
diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php
index 2d86615e..c9a0cac5 100644
--- a/modules-available/statistics/page.inc.php
+++ b/modules-available/statistics/page.inc.php
@@ -1,7 +1,6 @@
=', '=', '<', '>'];
+ const OP_STRCMP = ['!~', '~', '=', '!='];
public static $columns;
private $query;
@@ -27,123 +26,120 @@ class Page_Statistics extends Page
*/
private $haveSubpage;
- /* PHP sucks, no static, const array definitions... Or am I missing something? */
- public function initConstants()
+ /**
+ * Do this here instead of const since we need to check for available modules while building array.
+ */
+ public static function initConstants()
{
- Page_Statistics::$op_nominal = ['!=', '='];
- Page_Statistics::$op_ordinal = ['!=', '<=', '>=', '=', '<', '>'];
- Page_Statistics::$op_stringcmp = ['!~', '~', '=', '!='];
Page_Statistics::$columns = [
'machineuuid' => [
- 'op' => Page_Statistics::$op_nominal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'string',
'column' => true,
],
'macaddr' => [
- 'op' => Page_Statistics::$op_nominal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'string',
'column' => true,
],
'firstseen' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'date',
'column' => true,
],
'lastseen' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'date',
'column' => true,
],
'logintime' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'date',
'column' => true,
],
'realcores' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'int',
'column' => true,
],
'systemmodel' => [
- 'op' => Page_Statistics::$op_stringcmp,
+ 'op' => Page_Statistics::OP_STRCMP,
'type' => 'string',
'column' => true,
],
'cpumodel' => [
- 'op' => Page_Statistics::$op_stringcmp,
+ 'op' => Page_Statistics::OP_STRCMP,
'type' => 'string',
'column' => true,
],
'hddgb' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'int',
'column' => false,
'map_sort' => 'id44mb'
],
'gbram' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'int',
'map_sort' => 'mbram',
'column' => false,
],
'kvmstate' => [
- 'op' => Page_Statistics::$op_nominal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'enum',
'column' => true,
'values' => ['ENABLED', 'DISABLED', 'UNSUPPORTED']
],
'badsectors' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'int',
'column' => true
],
'clientip' => [
- 'op' => Page_Statistics::$op_nominal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'string',
'column' => true
],
'hostname' => [
- 'op' => Page_Statistics::$op_stringcmp,
+ 'op' => Page_Statistics::OP_STRCMP,
'type' => 'string',
'column' => true
],
'subnet' => [
- 'op' => Page_Statistics::$op_nominal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'string',
'column' => false
],
'currentuser' => [
- 'op' => Page_Statistics::$op_nominal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'string',
'column' => true
],
'state' => [
- 'op' => Page_Statistics::$op_nominal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'enum',
'column' => true,
'values' => ['occupied', 'on', 'off', 'idle', 'standby']
],
'runtime' => [
- 'op' => Page_Statistics::$op_ordinal,
+ 'op' => Page_Statistics::OP_NOMINAL,
'type' => 'int',
'column' => true
],
];
if (Module::isAvailable('locations')) {
Page_Statistics::$columns['location'] = [
- 'op' => Page_Statistics::$op_stringcmp,
+ 'op' => Page_Statistics::OP_STRCMP,
'type' => 'enum',
'column' => false,
'values' => array_keys(Location::getLocationsAssoc()),
];
}
- /* TODO ... */
}
protected function doPreprocess()
{
- $this->initConstants();
User::load();
if (!User::isLoggedIn()) {
Message::addError('main.no-permission');
@@ -1127,3 +1123,5 @@ class Page_Statistics extends Page
), true);
}
}
+
+Page_Statistics::initConstants();
--
cgit v1.2.3-55-g7522
From 54a0a4c9b920bce1dc4e93d2cf05ebbea6502be0 Mon Sep 17 00:00:00 2001
From: Simon Rettberg
Date: Mon, 28 Jan 2019 13:48:03 +0100
Subject: [inc/Util] readableFileSize: support input in KB/MB/...
---
inc/util.inc.php | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/inc/util.inc.php b/inc/util.inc.php
index 1a5cbefe..e459cc46 100644
--- a/inc/util.inc.php
+++ b/inc/util.inc.php
@@ -234,9 +234,10 @@ SADFACE;
*
* @param float|int $bytes numeric value of the filesize to make readable
* @param int $decimals number of decimals to show, -1 for automatic
+ * @param int $shift how many units to skip, i.e. if you pass in KiB or MiB
* @return string human readable string representing the given file size
*/
- public static function readableFileSize($bytes, $decimals = -1)
+ public static function readableFileSize($bytes, $decimals = -1, $shift = 0)
{
$bytes = round($bytes);
static $sz = array('Byte', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB');
@@ -249,7 +250,7 @@ SADFACE;
$decimals = 2 - floor(strlen((int)$bytes) - 1);
}
}
- return sprintf("%.{$decimals}f", $bytes) . "\xe2\x80\x89" . $sz[$factor];
+ return sprintf("%.{$decimals}f", $bytes) . "\xe2\x80\x89" . $sz[$factor + $shift];
}
public static function sanitizeFilename($name)
--
cgit v1.2.3-55-g7522
From 3b1df888c963d906005ff139892df06a0d1ae2b4 Mon Sep 17 00:00:00 2001
From: Simon Rettberg
Date: Mon, 28 Jan 2019 13:48:35 +0100
Subject: [statistics] Track and display memory/tmp usage of clients
---
modules-available/statistics/api.inc.php | 13 ++++++--
modules-available/statistics/hooks/cron.inc.php | 9 ++++--
modules-available/statistics/install.inc.php | 17 ++++++++++
.../statistics/lang/de/template-tags.json | 4 +++
.../statistics/lang/en/template-tags.json | 4 +++
modules-available/statistics/page.inc.php | 37 ++++++++++++++++------
modules-available/statistics/style.css | 32 +++++++++++++++++++
.../statistics/templates/filterbox.html | 5 ++-
.../statistics/templates/machine-main.html | 33 ++++++++++++++++---
9 files changed, 135 insertions(+), 19 deletions(-)
diff --git a/modules-available/statistics/api.inc.php b/modules-available/statistics/api.inc.php
index 813e7d54..57c4cee2 100644
--- a/modules-available/statistics/api.inc.php
+++ b/modules-available/statistics/api.inc.php
@@ -34,7 +34,8 @@ if ($type{0} === '~') {
// External mode of operation?
$mode = Request::post('mode', false, 'string');
$NOW = time();
- $old = Database::queryFirst('SELECT clientip, logintime, lastseen, lastboot, state, mbram, cpumodel FROM machine WHERE machineuuid = :uuid', array('uuid' => $uuid));
+ $old = Database::queryFirst('SELECT clientip, logintime, lastseen, lastboot, state, mbram, cpumodel, live_memfree, live_swapfree, live_tmpfree
+ FROM machine WHERE machineuuid = :uuid', array('uuid' => $uuid));
if ($old !== false) {
settype($old['logintime'], 'integer');
settype($old['lastseen'], 'integer');
@@ -114,6 +115,7 @@ if ($type{0} === '~') {
. ' cpumodel = :cpumodel,'
. ' systemmodel = :systemmodel,'
. ' id44mb = :id44mb,'
+ . ' live_tmpsize = 0, live_swapsize = 0, live_memsize = 0,'
. ' badsectors = :badsectors,'
. ' data = :data,'
. ' state = :state '
@@ -152,7 +154,10 @@ if ($type{0} === '~') {
// Log potential crash
if ($old['state'] === 'IDLE' || $old['state'] === 'OCCUPIED') {
- writeClientLog('machine-mismatch-poweron', 'Client sent poweron event, but previous known state is ' . $old['state']);
+ writeClientLog('machine-mismatch-poweron', 'Poweron event, but previous known state is ' . $old['state']
+ . '. RAM: ' . Util::readableFileSize($old['live_memfree'], -1, 2)
+ . ', Swap: ' . Util::readableFileSize($old['live_swapfree'], -1, 2)
+ . ', ID44: ' . Util::readableFileSize($old['live_memfree'], -1, 2));
}
}
@@ -190,6 +195,10 @@ if ($type{0} === '~') {
}
}
}
+ foreach (['memsize', 'tmpsize', 'swapsize', 'memfree', 'tmpfree', 'swapfree'] as $item) {
+ $strUpdateBoottime .= ' live_' . $item . ' = :_' . $item . ', ';
+ $params['_' . $item] = ceil(Request::post($item, 0, 'int') / 1024);
+ }
// Figure out what's happening - state changes
if ($used === 0 && $old['state'] !== 'IDLE') {
if ($old['state'] === 'OCCUPIED' && $sessionLength === 0) {
diff --git a/modules-available/statistics/hooks/cron.inc.php b/modules-available/statistics/hooks/cron.inc.php
index 0b8e740e..f22d0475 100644
--- a/modules-available/statistics/hooks/cron.inc.php
+++ b/modules-available/statistics/hooks/cron.inc.php
@@ -24,14 +24,17 @@ function state_cleanup()
$standby = time() - 86400 * 4; // Reset standby machines after four days
$on = time() - 610; // Reset others after ~10 minutes
// Query for logging
- $res = Database::simpleQuery("SELECT machineuuid, clientip, state, logintime, lastseen FROM machine
- WHERE lastseen < If(state = 'STANDBY', $standby, $on) AND state <> 'OFFLINE'");
+ $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'],
+ 'description' => 'Client timed out, last known state is ' . $row['state']
+ . '. RAM: ' . Util::readableFileSize($row['live_memfree'], -1, 2)
+ . ', Swap: ' . Util::readableFileSize($row['live_swapfree'], -1, 2)
+ . ', ID44: ' . Util::readableFileSize($row['live_memfree'], -1, 2),
'longdesc' => '',
'uuid' => $row['machineuuid'],
));
diff --git a/modules-available/statistics/install.inc.php b/modules-available/statistics/install.inc.php
index 4e2dfcca..84e038a4 100644
--- a/modules-available/statistics/install.inc.php
+++ b/modules-available/statistics/install.inc.php
@@ -234,5 +234,22 @@ if (!tableHasColumn('machine', 'state')) {
$res[] = UPDATE_DONE;
}
+// 2019-01-25: Add memory/temp stats column
+if (!tableHasColumn('machine', 'live_tmpsize')) {
+ $ret = Database::exec("ALTER TABLE `machine`
+ ADD COLUMN `live_tmpsize` int(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `id44mb`,
+ ADD COLUMN `live_tmpfree` int(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `live_tmpsize`,
+ ADD COLUMN `live_swapsize` int(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `live_tmpfree`,
+ ADD COLUMN `live_swapfree` int(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `live_swapsize`,
+ ADD COLUMN `live_memsize` int(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `live_swapfree`,
+ ADD COLUMN `live_memfree` int(10) UNSIGNED NOT NULL DEFAULT '0' AFTER `live_memsize`,
+ ADD INDEX `live_tmpfree` (`live_tmpfree`),
+ ADD INDEX `live_memfree` (`live_memfree`)");
+ if ($ret === false) {
+ finalResponse(UPDATE_FAILED, 'Adding state column to machine table failed: ' . Database::lastError());
+ }
+ $res[] = UPDATE_DONE;
+}
+
// Create response
responseFromArray($res);
diff --git a/modules-available/statistics/lang/de/template-tags.json b/modules-available/statistics/lang/de/template-tags.json
index 84c4690c..2567eea1 100644
--- a/modules-available/statistics/lang/de/template-tags.json
+++ b/modules-available/statistics/lang/de/template-tags.json
@@ -14,6 +14,7 @@
"lang_event": "Ereignis",
"lang_eventType": "Typ",
"lang_firstSeen": "Erste Aktivit\u00e4t",
+ "lang_free": "frei",
"lang_gbRam": "RAM",
"lang_hardwareSummary": "Hardware",
"lang_hdds": "Festplatten",
@@ -40,6 +41,7 @@
"lang_machineStandby": "Im Standby",
"lang_machineSummary": "Zusammenfassung",
"lang_maximumAbbrev": "Max.",
+ "lang_memFree": "RAM frei (MB)",
"lang_memoryStats": "Arbeitsspeicher",
"lang_model": "Modell",
"lang_modelCount": "Anzahl",
@@ -82,10 +84,12 @@
"lang_subnet": "Subnetz",
"lang_sureDeletePermanent": "M\u00f6chten Sie diese(n) Rechner wirklich unwiderruflich aus der Datenbank entfernen?\r\n\r\nWichtig: L\u00f6schen verhindert nicht, dass ein Rechner nach erneutem Starten von bwLehrpool wieder in die Datenbank aufgenommen wird.",
"lang_sureReplaceNoUndo": "Wollen Sie die Daten ausgew\u00e4hlten Rechner \u00fcbertragen? Diese Aktion kann nicht r\u00fcckg\u00e4ngig gemacht werden.",
+ "lang_swapFree": "swap frei (MB)",
"lang_tempPart": "Temp. Partition",
"lang_tempPartStats": "Tempor\u00e4re Partition",
"lang_thoseAreProjectors": "Diese Modellnamen werden als Beamer behandelt, auch wenn die EDID-Informationen des Ger\u00e4tes anderes berichten.",
"lang_timebarDesc": "Visuelle Darstellung der letzten Tage. Rote Abschnitte zeigen, wann der Rechner belegt war, gr\u00fcne, wann er nicht verwendet wurde, aber eingeschaltet war. Die leicht abgedunkelten Abschnitte markieren N\u00e4chte (22 bis 8 Uhr).",
+ "lang_tmpFree": "ID44 frei (MB)",
"lang_tmpGb": "Temp-HDD",
"lang_total": "Gesamt",
"lang_usageDetails": "Nutzungsdetails",
diff --git a/modules-available/statistics/lang/en/template-tags.json b/modules-available/statistics/lang/en/template-tags.json
index b064ee50..1d9cd4da 100644
--- a/modules-available/statistics/lang/en/template-tags.json
+++ b/modules-available/statistics/lang/en/template-tags.json
@@ -14,6 +14,7 @@
"lang_event": "Event",
"lang_eventType": "Type",
"lang_firstSeen": "First seen",
+ "lang_free": "free",
"lang_gbRam": "RAM",
"lang_hardwareSummary": "Hardware",
"lang_hdds": "Hard disk drives",
@@ -40,6 +41,7 @@
"lang_machineStandby": "In standby mode",
"lang_machineSummary": "Summary",
"lang_maximumAbbrev": "max.",
+ "lang_memFree": "RAM free (MB)",
"lang_memoryStats": "Memory",
"lang_model": "Model",
"lang_modelCount": "Count",
@@ -82,10 +84,12 @@
"lang_subnet": "Subnet",
"lang_sureDeletePermanent": "Are your sure you want to delete the selected machine(s) from the database? This cannot be undone.\r\n\r\nNote: Deleting machines from the database does not prevent booting up bwLehrpool again, which would recreate their respective database entries.",
"lang_sureReplaceNoUndo": "Are you sure you want to replace the selected machine pairs? This action cannot be undone.",
+ "lang_swapFree": "swap free (MB)",
"lang_tempPart": "Temp. partition",
"lang_tempPartStats": "Temporary partition",
"lang_thoseAreProjectors": "These model names will always be treated as beamers, even if the device's EDID data says otherwise.",
"lang_timebarDesc": "Visual representation of the last few days. Red parts mark periods where the client was occupied, green parts where the client was idle. Dimmed parts mark nights (10pm to 8am).",
+ "lang_tmpFree": "ID44 free (MB)",
"lang_tmpGb": "Temp HDD",
"lang_total": "Total",
"lang_usageDetails": "Detailed usage",
diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php
index c9a0cac5..a9cde6fb 100644
--- a/modules-available/statistics/page.inc.php
+++ b/modules-available/statistics/page.inc.php
@@ -122,8 +122,18 @@ class Page_Statistics extends Page
'column' => true,
'values' => ['occupied', 'on', 'off', 'idle', 'standby']
],
- 'runtime' => [
- 'op' => Page_Statistics::OP_NOMINAL,
+ 'live_swapfree' => [
+ 'op' => Page_Statistics::OP_ORDINAL,
+ 'type' => 'int',
+ 'column' => true
+ ],
+ 'live_memfree' => [
+ 'op' => Page_Statistics::OP_ORDINAL,
+ 'type' => 'int',
+ 'column' => true
+ ],
+ 'live_tmpfree' => [
+ 'op' => Page_Statistics::OP_ORDINAL,
'type' => 'int',
'column' => true
],
@@ -764,9 +774,9 @@ class Page_Statistics extends Page
$row['currentsession'] = $lecture['displayname'];
$row['lectureid'] = $lecture['lectureid'];
}
+ $row['session'] = $row['currentsession'];
+ return;
}
- $row['session'] = $row['currentsession'];
- return;
}
$res = Database::simpleQuery('SELECT dateline, username, data FROM statistic'
. " WHERE clientip = :ip AND typeid = '.vmchooser-session-name'"
@@ -783,14 +793,17 @@ class Page_Statistics extends Page
}
if ($session !== false) {
$row['session'] = $session['data'];
- $row['username'] = $session['username'];
+ if (empty($row['currentuser'])) {
+ $row['username'] = $session['username'];
+ }
}
}
private function showMachine($uuid)
{
- $client = Database::queryFirst('SELECT machineuuid, locationid, macaddr, clientip, firstseen, lastseen, logintime, lastboot, state,'
- . ' mbram, kvmstate, cpumodel, id44mb, data, hostname, currentuser, currentsession, notes FROM machine WHERE machineuuid = :uuid',
+ $client = Database::queryFirst('SELECT machineuuid, locationid, macaddr, clientip, firstseen, lastseen, logintime, lastboot, state,
+ mbram, live_tmpsize, live_tmpfree, live_swapsize, live_swapfree, live_memsize, live_memfree,
+ kvmstate, cpumodel, id44mb, data, hostname, currentuser, currentsession, notes FROM machine WHERE machineuuid = :uuid',
array('uuid' => $uuid));
if ($client === false) {
Message::addError('unknown-machine', $uuid);
@@ -826,6 +839,7 @@ class Page_Statistics extends Page
$client['state_' . $client['state']] = true;
$client['firstseen_s'] = date('d.m.Y H:i', $client['firstseen']);
$client['lastseen_s'] = date('d.m.Y H:i', $client['lastseen']);
+ $client['logintime_s'] = date('d.m.Y H:i', $client['logintime']);
if ($client['lastboot'] == 0) {
$client['lastboot_s'] = '-';
} else {
@@ -835,9 +849,14 @@ class Page_Statistics extends Page
$client['lastboot_s'] .= ' (Up ' . floor($uptime / 86400) . 'd ' . gmdate('H:i', $uptime) . ')';
}
}
- $client['logintime_s'] = date('d.m.Y H:i', $client['logintime']);
- $client['gbram'] = round(round($client['mbram'] / 500) / 2, 1);
+ $client['gbram'] = round(ceil($client['mbram'] / 512) / 2, 1);
$client['gbtmp'] = round($client['id44mb'] / 1024);
+ foreach (['tmp', 'swap', 'mem'] as $item) {
+ if ($client['live_' . $item . 'size'] == 0)
+ continue;
+ $client['live_' . $item . 'percent'] = round(($client['live_' . $item . 'free'] / $client['live_' . $item . 'size']) * 100, 2);
+ $client['live_' . $item . 'free_s'] = Util::readableFileSize($client['live_' . $item . 'free'], -1, 2);
+ }
$client['ramclass'] = $this->ramColorClass($client['mbram']);
$client['kvmclass'] = $this->kvmColorClass($client['kvmstate']);
$client['hddclass'] = $this->hddColorClass($client['gbtmp']);
diff --git a/modules-available/statistics/style.css b/modules-available/statistics/style.css
index 1496ac87..c48275ba 100644
--- a/modules-available/statistics/style.css
+++ b/modules-available/statistics/style.css
@@ -8,4 +8,36 @@
border-radius: 25px;
font-size: 20px;
line-height: 40px;
+}
+
+.meter {
+ position: relative;
+ border-radius: 5px;
+ border: 1px solid #999;
+ background: linear-gradient(to right, #9e6 0%, #fb8 66%, #f32 100%);
+ height: 1.25em;
+ padding: 0;
+ width: 100%;
+ overflow: hidden;
+}
+
+.meter .bar {
+ position: absolute;
+ top: 0;
+ height: 100%;
+ right: 0;
+ background: #efe;
+ display: inline-block;
+ padding: 0;
+ margin: 0 0 0 auto;
+}
+
+.meter .text {
+ position: absolute;
+ right: 5px;
+ overflow: visible;
+ font-size: 8pt;
+ white-space: nowrap;
+ z-index: 1000;
+ text-shadow: #fff 1px 1px;
}
\ No newline at end of file
diff --git a/modules-available/statistics/templates/filterbox.html b/modules-available/statistics/templates/filterbox.html
index cd8ec24d..07aa7320 100644
--- a/modules-available/statistics/templates/filterbox.html
+++ b/modules-available/statistics/templates/filterbox.html
@@ -101,7 +101,10 @@ var slxFilterNames = {
currentuser: '{{lang_currentUser}}',
subnet: '{{lang_subnet}}',
runtime: '{{lang_runtimeHours}}',
- hostname: '{{lang_hostname}}'
+ hostname: '{{lang_hostname}}',
+ live_swapfree: '{{lang_swapFree}}',
+ live_memfree: '{{lang_memFree}}',
+ live_tmpfree: '{{lang_tmpFree}}'
};
slxLocations = {{{locations}}};
diff --git a/modules-available/statistics/templates/machine-main.html b/modules-available/statistics/templates/machine-main.html
index f1021482..904c780b 100644
--- a/modules-available/statistics/templates/machine-main.html
+++ b/modules-available/statistics/templates/machine-main.html
@@ -1,3 +1,4 @@
+{{%FILTERS}}
{{hostname}} {{#hostname}}–{{/hostname}} {{clientip}}
{{#notes}}{{/notes}}
@@ -117,9 +118,23 @@
{{lang_ram}} |
- {{gbram}} GiB
- {{#maxram}}({{lang_maximumAbbrev}} {{maxram}}){{/maxram}}
- {{ramtype}}
+
+ {{gbram}} GiB
+ {{#maxram}}({{lang_maximumAbbrev}} {{maxram}}){{/maxram}}
+ {{ramtype}}
+
+ {{#live_memsize}}
+
+ {{live_memfree_s}} {{lang_free}}
+
+
+ {{/live_memsize}}
+ {{#live_swapsize}}
+
+ {{live_swapfree_s}} {{lang_free}}
+
+
+ {{/live_swapsize}}
|
{{#extram}}
@@ -135,7 +150,17 @@
{{/extram}}
{{lang_tempPart}} |
- {{gbtmp}} GiB |
+
+
+ {{gbtmp}} GiB
+
+ {{#live_tmpsize}}
+
+ {{live_tmpfree_s}} {{lang_free}}
+
+
+ {{/live_tmpsize}}
+ |
{{lang_64bitSupport}} |
--
cgit v1.2.3-55-g7522
From 8c5c14eb4ad2fcaeb35d746d2183943f6dc52fb1 Mon Sep 17 00:00:00 2001
From: Simon Rettberg
Date: Mon, 28 Jan 2019 14:33:16 +0100
Subject: [statistics] Cleanup template
---
modules-available/statistics/templates/machine-main.html | 1 -
1 file changed, 1 deletion(-)
diff --git a/modules-available/statistics/templates/machine-main.html b/modules-available/statistics/templates/machine-main.html
index 904c780b..44f03a99 100644
--- a/modules-available/statistics/templates/machine-main.html
+++ b/modules-available/statistics/templates/machine-main.html
@@ -1,4 +1,3 @@
-{{%FILTERS}}
{{hostname}} {{#hostname}}–{{/hostname}} {{clientip}}
{{#notes}}{{/notes}}
--
cgit v1.2.3-55-g7522
From 1b53e1ac441f547e4524a512eff3d6b25457f95e Mon Sep 17 00:00:00 2001
From: Simon Rettberg
Date: Mon, 28 Jan 2019 14:38:47 +0100
Subject: [statistics] Fix copypasta
---
modules-available/statistics/api.inc.php | 2 +-
modules-available/statistics/hooks/cron.inc.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules-available/statistics/api.inc.php b/modules-available/statistics/api.inc.php
index 57c4cee2..280e5abc 100644
--- a/modules-available/statistics/api.inc.php
+++ b/modules-available/statistics/api.inc.php
@@ -157,7 +157,7 @@ if ($type{0} === '~') {
writeClientLog('machine-mismatch-poweron', 'Poweron event, but previous known state is ' . $old['state']
. '. RAM: ' . Util::readableFileSize($old['live_memfree'], -1, 2)
. ', Swap: ' . Util::readableFileSize($old['live_swapfree'], -1, 2)
- . ', ID44: ' . Util::readableFileSize($old['live_memfree'], -1, 2));
+ . ', ID44: ' . Util::readableFileSize($old['live_tmpfree'], -1, 2));
}
}
diff --git a/modules-available/statistics/hooks/cron.inc.php b/modules-available/statistics/hooks/cron.inc.php
index f22d0475..6393b2c6 100644
--- a/modules-available/statistics/hooks/cron.inc.php
+++ b/modules-available/statistics/hooks/cron.inc.php
@@ -34,7 +34,7 @@ function state_cleanup()
'description' => 'Client timed out, last known state is ' . $row['state']
. '. RAM: ' . Util::readableFileSize($row['live_memfree'], -1, 2)
. ', Swap: ' . Util::readableFileSize($row['live_swapfree'], -1, 2)
- . ', ID44: ' . Util::readableFileSize($row['live_memfree'], -1, 2),
+ . ', ID44: ' . Util::readableFileSize($row['live_tmpfree'], -1, 2),
'longdesc' => '',
'uuid' => $row['machineuuid'],
));
--
cgit v1.2.3-55-g7522
From 533a2964535bcae48eb30ded2edaa6dd6d2c321b Mon Sep 17 00:00:00 2001
From: Simon Rettberg
Date: Tue, 29 Jan 2019 09:20:55 +0100
Subject: [locationinfo] Suppress XML parsing error spam
The SimpleXML constructor is quite verbose if you pass it e.g. an HTML
error page instead of the expected XML. Suppress those errors, we'll do
our own (more concise) logging in the exception handler.
---
modules-available/locationinfo/inc/coursebackend.inc.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules-available/locationinfo/inc/coursebackend.inc.php b/modules-available/locationinfo/inc/coursebackend.inc.php
index 1da0086a..dcd92f6f 100644
--- a/modules-available/locationinfo/inc/coursebackend.inc.php
+++ b/modules-available/locationinfo/inc/coursebackend.inc.php
@@ -334,7 +334,7 @@ abstract class CourseBackend
{
$cleanresponse = preg_replace('/(<\/?)(\w+):([^>]*>)/', '$1$2$3', $response);
try {
- $xml = new SimpleXMLElement($cleanresponse);
+ $xml = @new SimpleXMLElement($cleanresponse); // This spams before throwing exception
} catch (Exception $e) {
$this->error = 'Could not parse reply as XML, got ' . get_class($e) . ': ' . $e->getMessage();
if (CONFIG_DEBUG) {
--
cgit v1.2.3-55-g7522
From f538335087e18ad5950eee0ec1c9654fff5addc5 Mon Sep 17 00:00:00 2001
From: Simon Rettberg
Date: Tue, 29 Jan 2019 09:22:28 +0100
Subject: [locationinfo] HisInOne: Properly handle multiple plannedDates
If a course has been running for several semesters, older plannedDate
entries tend to have no individualDate entries. Ignore those and don't
error_log about it.
---
.../locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php
index 22b1d8fb..c71623b3 100644
--- a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php
+++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php
@@ -271,6 +271,7 @@ class CourseBackend_HisInOne extends CourseBackend
$eventDetails = array_merge($eventDetails, $event);
}
$name = false;
+ $now = time();
foreach ($eventDetails as $event) {
foreach (array('/hisdefaulttext',
'/hisshorttext',
@@ -293,6 +294,12 @@ class CourseBackend_HisInOne extends CourseBackend
foreach ($planElements as $planElement) {
if (empty($planElement['hisplannedDates']))
continue;
+ $checkDate = $this->getArrayPath($planElement, '/hisplannedDates/hisplannedDate/hisenddate');
+ if (!empty($checkDate) && strtotime($checkDate[0]) + 86400 < $now)
+ continue; // Course ended
+ $checkDate = $this->getArrayPath($planElement, '/hisplannedDates/hisplannedDate/hisstartdate');
+ if (!empty($checkDate) && strtotime($checkDate[0]) - 86400 > $now)
+ continue; // Course didn't start yet
$unitPlannedDates = $this->getArrayPath($planElement,
'/hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate');
if ($unitPlannedDates === false) {
--
cgit v1.2.3-55-g7522
From 16c94742e46834336d77ca6825fa681db9c966bb Mon Sep 17 00:00:00 2001
From: Simon Rettberg
Date: Wed, 30 Jan 2019 13:24:03 +0100
Subject: [systemstatus] Don't show swap warning too early
---
modules-available/systemstatus/page.inc.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules-available/systemstatus/page.inc.php b/modules-available/systemstatus/page.inc.php
index 958e763f..04423eaf 100644
--- a/modules-available/systemstatus/page.inc.php
+++ b/modules-available/systemstatus/page.inc.php
@@ -209,7 +209,7 @@ class Page_SystemStatus extends Page
$data['swapTotal'] = Util::readableFileSize($info['SwapTotal'] * 1024);
$data['swapUsed'] = Util::readableFileSize(($info['SwapTotal'] - $info['SwapFree']) * 1024);
$data['swapPercent'] = 100 - round(($info['SwapFree'] / $info['SwapTotal']) * 100);
- $data['swapWarning'] = ($data['swapPercent'] > 50 || ($info['SwapTotal'] - $info['SwapFree']) > 200000);
+ $data['swapWarning'] = ($data['swapPercent'] > 50 || $info['SwapFree'] < 400000);
}
if (isset($info['CpuIdle']) && isset($info['CpuSystem']) && isset($info['CpuTotal'])) {
$data['cpuLoad'] = 100 - round(($info['CpuIdle'] / $info['CpuTotal']) * 100);
--
cgit v1.2.3-55-g7522
From 120956761383f8365e95e669a11b344af4764c74 Mon Sep 17 00:00:00 2001
From: Simon Rettberg
Date: Wed, 30 Jan 2019 13:39:41 +0100
Subject: [inc/Dictionary] Teh evil unvalidated redirects must die!
---
inc/dictionary.inc.php | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/inc/dictionary.inc.php b/inc/dictionary.inc.php
index fcbfdfb8..935d1f4e 100644
--- a/inc/dictionary.inc.php
+++ b/inc/dictionary.inc.php
@@ -30,10 +30,15 @@ class Dictionary
if ($lang !== false && in_array($lang, self::$languages)) {
setcookie('lang', $lang, time() + 60 * 60 * 24 * 30 * 12);
$url = Request::get('url');
- if ($url === false && isset($_SERVER['HTTP_REFERER']))
+ if ($url === false && isset($_SERVER['HTTP_REFERER'])) {
$url = $_SERVER['HTTP_REFERER'];
- if ($url === false)
- $url = '?do=Main';
+ }
+ $parts = parse_url($url);
+ if ($url === false || $parts === false || empty($parts['query'])) {
+ $url = '?do=main';
+ } else {
+ $url = '?' . $parts['query'];
+ }
Util::redirect($url);
}
--
cgit v1.2.3-55-g7522