summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2015-12-31 00:29:34 +0100
committerSimon Rettberg2015-12-31 00:29:34 +0100
commit259f3df3f0117628ce1455dd1b61a3f9e8f08920 (patch)
treefeac370e6e2601ec59f6039734f4e8c14354bc97
parent[clientlog] Fix bootup db insert query (diff)
downloadslx-admin-259f3df3f0117628ce1455dd1b61a3f9e8f08920.tar.gz
slx-admin-259f3df3f0117628ce1455dd1b61a3f9e8f08920.tar.xz
slx-admin-259f3df3f0117628ce1455dd1b61a3f9e8f08920.zip
[statistics] Add visualization of usage
-rw-r--r--apis/clientlog.inc.php1
-rw-r--r--lang/de/templates/statistics/machine-usage.json4
-rw-r--r--lang/en/templates/statistics/machine-usage.json4
-rw-r--r--lang/pt/templates/statistics/machine-usage.json3
-rw-r--r--modules/statistics.inc.php103
-rw-r--r--style/default.css17
-rw-r--r--templates/statistics/machine-main.html8
-rw-r--r--templates/statistics/machine-usage.html51
8 files changed, 163 insertions, 28 deletions
diff --git a/apis/clientlog.inc.php b/apis/clientlog.inc.php
index 61200875..c48fcdb0 100644
--- a/apis/clientlog.inc.php
+++ b/apis/clientlog.inc.php
@@ -134,7 +134,6 @@ if ($type{0} === '~') {
// Usage (occupied/free)
$sessionLength = 0;
$used = Request::post('used', 0, 'integer');
- error_log("uuid=$uuid old=$old used=$used");
if ($old === false) die("Unknown machine.\n");
// Figure out what's happening
if ($used === 0) {
diff --git a/lang/de/templates/statistics/machine-usage.json b/lang/de/templates/statistics/machine-usage.json
new file mode 100644
index 00000000..e2c9a979
--- /dev/null
+++ b/lang/de/templates/statistics/machine-usage.json
@@ -0,0 +1,4 @@
+{
+ "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_usageDetails": "Nutzungsdetails"
+} \ No newline at end of file
diff --git a/lang/en/templates/statistics/machine-usage.json b/lang/en/templates/statistics/machine-usage.json
new file mode 100644
index 00000000..398996f6
--- /dev/null
+++ b/lang/en/templates/statistics/machine-usage.json
@@ -0,0 +1,4 @@
+{
+ "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_usageDetails": "Detailed usage"
+} \ No newline at end of file
diff --git a/lang/pt/templates/statistics/machine-usage.json b/lang/pt/templates/statistics/machine-usage.json
new file mode 100644
index 00000000..c44dc44f
--- /dev/null
+++ b/lang/pt/templates/statistics/machine-usage.json
@@ -0,0 +1,3 @@
+[
+
+] \ No newline at end of file
diff --git a/modules/statistics.inc.php b/modules/statistics.inc.php
index dd04771f..3104496a 100644
--- a/modules/statistics.inc.php
+++ b/modules/statistics.inc.php
@@ -393,51 +393,110 @@ class Page_Statistics extends Page
private function showMachine($uuid)
{
- $row = Database::queryFirst("SELECT machineuuid, macaddr, clientip, firstseen, lastseen, logintime, lastboot,"
+ $client = Database::queryFirst("SELECT machineuuid, macaddr, clientip, firstseen, lastseen, logintime, lastboot,"
. " mbram, kvmstate, cpumodel, id44mb, data, hostname, notes FROM machine WHERE machineuuid = :uuid",
array('uuid' => $uuid));
// Mangle fields
$NOW = time();
- if ($NOW - $row['lastseen'] > 610) {
- $row['state_off'] = true;
- } elseif ($row['logintime'] == 0) {
- $row['state_idle'] = true;
+ if ($NOW - $client['lastseen'] > 610) {
+ $client['state_off'] = true;
+ } elseif ($client['logintime'] == 0) {
+ $client['state_idle'] = true;
} else {
- $row['state_occupied'] = true;
- $this->fillSessionInfo($row);
- }
- $row['firstseen'] = date('d.m.Y H:i', $row['firstseen']);
- $row['lastseen'] = date('d.m.Y H:i', $row['lastseen']);
- $row['lastboot'] = date('d.m.Y H:i', $row['lastboot']);
- $row['logintime'] = date('d.m.Y H:i', $row['logintime']);
- $row['gbram'] = round(round($row['mbram'] / 500) / 2, 1);
- $row['gbtmp'] = round($row['id44mb'] / 1024);
- $row['ramclass'] = $this->ramColorClass($row['mbram']);
- $row['kvmclass'] = $this->kvmColorClass($row['kvmstate']);
- $row['hddclass'] = $this->hddColorClass($row['gbtmp']);
+ $client['state_occupied'] = true;
+ $this->fillSessionInfo($client);
+ }
+ $client['firstseen_s'] = date('d.m.Y H:i', $client['firstseen']);
+ $client['lastseen_s'] = date('d.m.Y H:i', $client['lastseen']);
+ $client['lastboot_s'] = date('d.m.Y H:i', $client['lastboot']);
+ $client['logintime_s'] = date('d.m.Y H:i', $client['logintime']);
+ $client['gbram'] = round(round($client['mbram'] / 500) / 2, 1);
+ $client['gbtmp'] = round($client['id44mb'] / 1024);
+ $client['ramclass'] = $this->ramColorClass($client['mbram']);
+ $client['kvmclass'] = $this->kvmColorClass($client['kvmstate']);
+ $client['hddclass'] = $this->hddColorClass($client['gbtmp']);
// Parse the giant blob of data
$hdds = array();
- if (preg_match_all('/##### ([^#]+) #+$(.*?)^#####/ims', $row['data'] . '########', $out, PREG_SET_ORDER)) {
+ if (preg_match_all('/##### ([^#]+) #+$(.*?)^#####/ims', $client['data'] . '########', $out, PREG_SET_ORDER)) {
foreach ($out as $section) {
if ($section[1] === 'CPU') {
- $this->parseCpu($row, $section[2]);
+ $this->parseCpu($client, $section[2]);
}
if ($section[1] === 'dmidecode') {
- $this->parseDmiDecode($row, $section[2]);
+ $this->parseDmiDecode($client, $section[2]);
}
if ($section[1] === 'Partition tables') {
$this->parseHdd($hdds, $section[2]);
}
}
}
+ unset($client['data']);
// Throw output at user
- Render::addTemplate('statistics/machine-main', $row);
+ Render::addTemplate('statistics/machine-main', $client);
+ // Sessions
+ $NOW = time();
+ $cutoff = $NOW - 86400 * 7;
+ if ($cutoff < $row['firstseen']) $cutoff = $row['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(
+ 'cutoff' => $cutoff - 86400,
+ 'uuid' => $uuid
+ ));
+ $spans['rows'] = array();
+ $last = false;
+ while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if ($row['dateline'] + $row['data'] < $cutoff || $row['data'] > 864000) continue;
+ if ($last !== false && abs($last['dateline'] - $row['dateline']) < 30
+ && abs($last['data'] - $row['data']) < 30) continue;
+ if ($last !== false && $last['dateline'] + $last['data'] > $row['dateline']) {
+ $point = $last['dateline'] + $last['data'];
+ $row['data'] -= ($point - $row['dateline']);
+ $row['dateline'] = $point;
+ }
+ if ($row['dateline'] < $cutoff) {
+ $row['data'] -= ($cutoff - $row['dateline']);
+ $row['dateline'] = $cutoff;
+ }
+ $row['from'] = date('d.m. H:i', $row['dateline']);
+ $row['duration'] = floor($row['data'] / 86400) . 'd ' . gmdate('H:i', $row['data']);
+ if ($row['typeid'] === '~offline-length') {
+ $row['glyph'] = 'off';
+ $color = '#444';
+ } else {
+ $row['glyph'] = 'user';
+ $color = '#e77';
+ }
+ $spans['graph'] .= '<div style="background:' . $color . ';left:' . round(($row['dateline'] - $cutoff) * $scale, 2) . '%;width:' . round(($row['data']) * $scale, 2) . '%">&nbsp;</div>';
+ $spans['rows'][] = $row;
+ $last = $row;
+ }
+ if (isset($client['state_occupied'])) {
+ $spans['graph'] .= '<div style="background:#e99;left:' . round(($client['logintime'] - $cutoff) * $scale, 2) . '%;width:' . round(($NOW - $client['logintime'] + 900) * $scale, 2) . '%">&nbsp;</div>';
+ } elseif (isset($client['state_off'])) {
+ $spans['graph'] .= '<div style="background:#444;left:' . round(($client['lastseen'] - $cutoff) * $scale, 2) . '%;width:' . round(($NOW - $client['lastseen'] + 900) * $scale, 2) . '%">&nbsp;</div>';
+ }
+ $t = explode('-', date('Y-n-j-G', $cutoff));
+ if ($t[3] >= 8 && $t[3] <= 22) {
+ $start = mktime(22, 0, 0, $t[1], $t[2], $t[0]);
+ } else {
+ $start = mktime(22, 0, 0, $t[1], $t[2] - 1, $t[0]);
+ }
+ for ($i = $start; $i < $NOW; $i += 86400) {
+ $spans['graph'] .= '<div style="background:rgba(0,0,90,.2);left:' . round(($i - $cutoff) * $scale, 2) . '%;width:' . round((10 * 3600) * $scale, 2) . '%">&nbsp;</div>';
+ }
+ if (count($spans['rows']) > 10) {
+ $spans['hasrows2'] = true;
+ $spans['rows2'] = array_slice($spans['rows'], ceil(count($spans['rows']) / 2));
+ $spans['rows'] = array_slice($spans['rows'], 0, ceil(count($spans['rows']) / 2));
+ }
+ Render::addTemplate('statistics/machine-usage', $spans);
// Any hdds?
if (!empty($hdds['hdds'])) {
Render::addScriptBottom('chart.min');
Render::addTemplate('statistics/machine-hdds', $hdds);
}
- Render::addTemplate('statistics/machine-notes', $row);
+ Render::addTemplate('statistics/machine-notes', $client);
}
private function parseCpu(&$row, $data)
diff --git a/style/default.css b/style/default.css
index 9c0c367a..73e4effa 100644
--- a/style/default.css
+++ b/style/default.css
@@ -216,4 +216,19 @@ body {
input[readonly] {
background-color: white !important;
cursor: text !important;
-} \ No newline at end of file
+}
+
+.timebar {
+ position: relative;
+ background: #afc;
+ border: 1px solid #0a2;
+ border-radius: 3px;
+ overflow: hidden;
+}
+
+.timebar div {
+ position: absolute;
+ top: 0px;
+ overflow: hidden;
+}
+
diff --git a/templates/statistics/machine-main.html b/templates/statistics/machine-main.html
index f9ca1c5d..8071416a 100644
--- a/templates/statistics/machine-main.html
+++ b/templates/statistics/machine-main.html
@@ -31,15 +31,15 @@
{{/hostname}}
<tr>
<td>{{lang_firstSeen}}</td>
- <td>{{firstseen}}</td>
+ <td>{{firstseen_s}}</td>
</tr>
<tr>
<td>{{lang_lastBoot}}</td>
- <td>{{lastboot}}</td>
+ <td>{{lastboot_s}}</td>
</tr>
<tr>
<td>{{lang_lastSeen}}</td>
- <td>{{lastseen}}</td>
+ <td>{{lastseen_s}}</td>
</tr>
<tr>
<td>{{lang_usageState}}</td>
@@ -57,7 +57,7 @@
{{^username}}
<span class="glyphicon glyphicon-user red"></span> {{lang_machineOccupied}}
{{/username}}
- <div>{{logintime}}</div>
+ <div>{{logintime_s}}</div>
{{/state_occupied}}
{{#session}}
<div>{{session}}</div>
diff --git a/templates/statistics/machine-usage.html b/templates/statistics/machine-usage.html
new file mode 100644
index 00000000..ffaa747b
--- /dev/null
+++ b/templates/statistics/machine-usage.html
@@ -0,0 +1,51 @@
+<div class="row">
+ <div class="col-md-12">
+ <div class="panel panel-default">
+ <div class="panel-heading">
+ {{lang_usageDetails}}
+ </div>
+ <div class="panel-body">
+ <div class="row">
+ <div class="col-sm-6">
+ <table class="table table-condensed">
+ <tr>
+ <th>Type</th>
+ <th>When</th>
+ <th>Length</th>
+ </tr>
+ {{#rows}}
+ <tr>
+ <td><span class="glyphicon glyphicon-{{glyph}}"></span></td>
+ <td>{{from}}</td>
+ <td>{{duration}}</td>
+ </tr>
+ {{/rows}}
+ </table>
+ </div>
+ <div class="col-sm-6">
+ <table class="table table-condensed">
+ {{#hasrows2}}
+ <tr>
+ <th>Type</th>
+ <th>When</th>
+ <th>Length</th>
+ </tr>
+ {{/hasrows2}}
+ {{#rows2}}
+ <tr>
+ <td><span class="glyphicon glyphicon-{{glyph}}"></span></td>
+ <td>{{from}}</td>
+ <td>{{duration}}</td>
+ </tr>
+ {{/rows2}}
+ </table>
+ </div>
+ </div>
+ <div class="timebar">&nbsp;{{{graph}}}</div>
+ <div>
+ {{lang_timebarDesc}}
+ </div>
+ </div>
+ </div>
+ </div>
+</div>