From e5c5e8422a74694d1abcd28f420450a25094c4b9 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 30 Nov 2015 13:48:11 +0100 Subject: Improve client logging --- lang/de/messages-hardcoded.json | 2 + lang/de/messages.json | 2 + lang/de/templates/main-menu.json | 1 + lang/de/templates/statistics/machine-notes.json | 4 + lang/de/templates/statistics/newclients.json | 4 + lang/en/messages-hardcoded.json | 2 + lang/en/messages.json | 2 + lang/en/templates/main-menu.json | 1 + lang/en/templates/statistics/machine-notes.json | 4 + lang/en/templates/statistics/newclients.json | 4 + lang/pt/templates/statistics/machine-notes.json | 3 + lang/pt/templates/statistics/newclients.json | 3 + modules/statistics.inc.php | 125 ++++++++++++++++++------ templates/statistics/clientlist.html | 6 +- templates/statistics/cpumodels.html | 2 +- templates/statistics/id44.html | 4 +- templates/statistics/kvmstate.html | 2 +- templates/statistics/machine-hdds.html | 2 +- templates/statistics/machine-main.html | 5 +- templates/statistics/machine-notes.html | 17 ++++ templates/statistics/memory.html | 4 +- templates/statistics/newclients.html | 44 +++++++++ 22 files changed, 206 insertions(+), 37 deletions(-) create mode 100644 lang/de/templates/statistics/machine-notes.json create mode 100644 lang/de/templates/statistics/newclients.json create mode 100644 lang/en/templates/statistics/machine-notes.json create mode 100644 lang/en/templates/statistics/newclients.json create mode 100644 lang/pt/templates/statistics/machine-notes.json create mode 100644 lang/pt/templates/statistics/newclients.json create mode 100644 templates/statistics/machine-notes.html create mode 100644 templates/statistics/newclients.html diff --git a/lang/de/messages-hardcoded.json b/lang/de/messages-hardcoded.json index 76d13e30..f785f042 100644 --- a/lang/de/messages-hardcoded.json +++ b/lang/de/messages-hardcoded.json @@ -11,9 +11,11 @@ "lang_noModuleFromThisGroup": "(Kein Modul dieser Gruppe)", "lang_serverConfiguration": "Serverseitige Konfiguration", "lang_titleBackup": "Sichern und Wiederherstellen", + "lang_titleClientStatistics": "Client-Statistiken", "lang_titleEventLog": "Ereignisprotokoll", "lang_titleWebinterface": "Webschnittstelle", "lang_unknwonTaskManager": "Unbekannter Taskmanager-Fehler", "today": "Heute", + "unused": "Ungenutzt", "yesterday": "Gestern" } \ No newline at end of file diff --git a/lang/de/messages.json b/lang/de/messages.json index 13b38c59..4d2859b2 100644 --- a/lang/de/messages.json +++ b/lang/de/messages.json @@ -21,6 +21,7 @@ "i18n-invalid-lang": "Ung\u00fcltige Sprache: {{0}}", "invalid-action": "Ung\u00fcltige Aktion: {{0}}", "invalid-file": "Die Datei {{0}} existiert nicht!", + "invalid-filter": "Ung\u00fcltiger Filter", "invalid-ip": "Kein Interface ist auf die Adresse {{0}} konfiguriert", "invalid-path": "Ung\u00fcltiger Pfad.", "invalid-template": "Ausgew\u00e4hlte Template ist nicht g\u00fcltig", @@ -40,6 +41,7 @@ "news-save-success": "News erfolgreich aktualisiert", "no-image": "Unter der angegebenen URL konnte kein SVG-Bild gefunden werden", "no-permission": "Keine ausreichenden Rechte, um auf diese Seite zuzugreifen", + "notes-saved": "Anmerkungen gespeichert", "password-mismatch": "Passwort und Passwortbest\u00e4tigung stimmen nicht \u00fcberein", "reboot-unconfirmed": "Sicherheitsabfrage zum Reboot nicht best\u00e4tigt", "remote-parse-failed": "Parsen der empfangenen Daten fehlgeschlagen ({{0}})", diff --git a/lang/de/templates/main-menu.json b/lang/de/templates/main-menu.json index efd918a3..3ed43eff 100644 --- a/lang/de/templates/main-menu.json +++ b/lang/de/templates/main-menu.json @@ -2,6 +2,7 @@ "lang_backup": "Backup\/Restore", "lang_client": "Client", "lang_clientLog": "Client Log", + "lang_clientStats": "Client-Statistiken", "lang_configurationBasic": "PXE\/Boot", "lang_configurationVariables": "KonfigurationsVariablen", "lang_dozmod": "Dozentenmodul", diff --git a/lang/de/templates/statistics/machine-notes.json b/lang/de/templates/statistics/machine-notes.json new file mode 100644 index 00000000..f9df1b92 --- /dev/null +++ b/lang/de/templates/statistics/machine-notes.json @@ -0,0 +1,4 @@ +{ + "lang_notes": "Anmerkungen", + "lang_save": "Speichern" +} \ No newline at end of file diff --git a/lang/de/templates/statistics/newclients.json b/lang/de/templates/statistics/newclients.json new file mode 100644 index 00000000..f1353389 --- /dev/null +++ b/lang/de/templates/statistics/newclients.json @@ -0,0 +1,4 @@ +{ + "lang_machine": "Client", + "lang_newMachines": "Neue Ger\u00e4te" +} \ No newline at end of file diff --git a/lang/en/messages-hardcoded.json b/lang/en/messages-hardcoded.json index 325f04ef..b19ef60a 100644 --- a/lang/en/messages-hardcoded.json +++ b/lang/en/messages-hardcoded.json @@ -11,9 +11,11 @@ "lang_noModuleFromThisGroup": "(No module from this group)", "lang_serverConfiguration": "Server-side Configuration", "lang_titleBackup": "Save and Restore", + "lang_titleClientStatistics": "Client statistics", "lang_titleEventLog": "Event log", "lang_titleWebinterface": "Web Interface", "lang_unknwonTaskManager": "Unknown Task Manager error", "today": "Today", + "unused": "Unused", "yesterday": "Yesterday" } \ No newline at end of file diff --git a/lang/en/messages.json b/lang/en/messages.json index bd8ffb18..aed10cce 100644 --- a/lang/en/messages.json +++ b/lang/en/messages.json @@ -21,6 +21,7 @@ "i18n-invalid-lang": "Invalid language: {{0}}", "invalid-action": "Invalid action: {{0}}", "invalid-file": "The file {{0}} does not exist!", + "invalid-filter": "Invalid filter", "invalid-ip": "No interface is configured with the address {{0}}", "invalid-path": "Invalid path.", "invalid-template": "Selected template is not valid", @@ -40,6 +41,7 @@ "news-save-success": "News updated successfully", "no-image": "Could not find an SVG-image at the given URL", "no-permission": "No sufficient privileges to access this page", + "notes-saved": "Notes have been saved", "password-mismatch": "Password and password confirmation do not match", "reboot-unconfirmed": "Confirmation prompt to reboot not confirmed", "remote-parse-failed": "Parsing the received data failed ({{0}})", diff --git a/lang/en/templates/main-menu.json b/lang/en/templates/main-menu.json index 839d65b1..be9cefed 100644 --- a/lang/en/templates/main-menu.json +++ b/lang/en/templates/main-menu.json @@ -2,6 +2,7 @@ "lang_backup": "Backup\/Restore", "lang_client": "Client", "lang_clientLog": "Client Log", + "lang_clientStats": "Client statistics", "lang_configurationBasic": "PXE\/Boot", "lang_configurationVariables": "Configuration Variables", "lang_dozmod": "Tutor module", diff --git a/lang/en/templates/statistics/machine-notes.json b/lang/en/templates/statistics/machine-notes.json new file mode 100644 index 00000000..7a13f28a --- /dev/null +++ b/lang/en/templates/statistics/machine-notes.json @@ -0,0 +1,4 @@ +{ + "lang_notes": "Notes", + "lang_save": "Save" +} \ No newline at end of file diff --git a/lang/en/templates/statistics/newclients.json b/lang/en/templates/statistics/newclients.json new file mode 100644 index 00000000..f7e55f3f --- /dev/null +++ b/lang/en/templates/statistics/newclients.json @@ -0,0 +1,4 @@ +{ + "lang_machine": "Client", + "lang_newMachines": "New machines" +} \ No newline at end of file diff --git a/lang/pt/templates/statistics/machine-notes.json b/lang/pt/templates/statistics/machine-notes.json new file mode 100644 index 00000000..c44dc44f --- /dev/null +++ b/lang/pt/templates/statistics/machine-notes.json @@ -0,0 +1,3 @@ +[ + +] \ No newline at end of file diff --git a/lang/pt/templates/statistics/newclients.json b/lang/pt/templates/statistics/newclients.json new file mode 100644 index 00000000..c44dc44f --- /dev/null +++ b/lang/pt/templates/statistics/newclients.json @@ -0,0 +1,3 @@ +[ + +] \ No newline at end of file diff --git a/modules/statistics.inc.php b/modules/statistics.inc.php index c459528f..c8c869b9 100644 --- a/modules/statistics.inc.php +++ b/modules/statistics.inc.php @@ -1,7 +1,11 @@ $uuid, + 'text' => $text + )); + Message::addSuccess('notes-saved'); + Util::redirect('?do=Statistics&uuid=' . $uuid); + } } protected function doRender() @@ -33,12 +51,38 @@ class Page_Statistics extends Page } Render::addScriptBottom('chart.min'); Render::openTag('div', array('class' => 'row')); - $this->showCpuModels(); $this->showMemory(); - $this->showKvmState(); $this->showId44(); + $this->showKvmState(); + $this->showLatestMachines(); + $this->showCpuModels(); Render::closeTag('div'); } + + private function capChart(&$json, $cutoff) + { + $total = 0; + foreach ($json as $entry) { + $total += $entry['value']; + } + $cap = ceil($total * $cutoff); + $accounted = 0; + $id = 0; + foreach ($json as $entry) { + if ($accounted < $cap || $id < 3) { + $id++; + $accounted += $entry['value']; + } + } + $json = array_slice($json, 0, $id); + if ($accounted / $total < 0.99) { + $json[] = array( + 'color' => '#eee', + 'label' => 'invalid', + 'value' => ($total - $accounted) + ); + } + } private function showCpuModels() { @@ -47,10 +91,8 @@ class Page_Statistics extends Page $lines = array(); $json = array(); $id = 0; - $total = 0; while ($row = $res->fetch(PDO::FETCH_ASSOC)) { settype($row['count'], 'integer'); - $total += $row['count']; $row['id'] = 'cpuid' . $id; $row['urlcpumodel'] = urlencode($row['cpumodel']); $lines[] = $row; @@ -61,14 +103,7 @@ class Page_Statistics extends Page ); ++$id; } - $cap = ceil($total * 0.95); - $total = 0; - $id = 0; - foreach ($json as $entry) { - $total += $entry['value']; - if ($total <= $cap) $id++; - } - $json = array_slice($json, 0, $id); + $this->capChart($json, 0.92); Render::addTemplate('statistics/cpumodels', array('rows' => $lines, 'json' => json_encode($json))); } @@ -96,7 +131,7 @@ class Page_Statistics extends Page $json = array(); $id = 0; foreach (array_reverse($lines, true) as $k => $v) { - $data['rows'][] = array('gb' => $k, 'count' => $v); + $data['rows'][] = array('gb' => $k, 'count' => $v, 'class' => $this->ramColorClass($k * 1024)); $json[] = array( 'color' => $STATS_COLORS[$id % count($STATS_COLORS)], 'label' => (string)$k, @@ -104,13 +139,14 @@ class Page_Statistics extends Page ); ++$id; } + $this->capChart($json, 0.92); $data['json'] = json_encode($json); Render::addTemplate('statistics/memory', $data); } private function showKvmState() { - $colors = array('UNKNOWN' => '#666', 'UNSUPPORTED' => '#ea5', 'DISABLED' => '#e55', 'ENABLED' => '#4d4'); + $colors = array('UNKNOWN' => '#666', 'UNSUPPORTED' => '#ea5', 'DISABLED' => '#e55', 'ENABLED' => '#6d6'); $res = Database::simpleQuery("SELECT kvmstate, Count(*) AS `count` FROM machine GROUP BY kvmstate ORDER BY `count` DESC"); $lines = array(); $json = array(); @@ -149,30 +185,62 @@ class Page_Statistics extends Page asort($lines); $data = array('rows' => array()); $json = array(); - $id = 1; + $id = 0; $cap = ceil($total * 0.95); - $total = 0; + $accounted = 0; foreach (array_reverse($lines, true) as $k => $v) { - $data['rows'][] = array('gb' => $k, 'count' => $v); - $total += $v; - if ($total <= $cap) { + $data['rows'][] = array('gb' => $k, 'count' => $v, 'class' => $this->hddColorClass($k)); + if ($accounted <= $cap) { if ($k === 0) { - $color = $STATS_COLORS[0]; + $color = '#e55'; } else { - $color = $STATS_COLORS[$id % count($STATS_COLORS)]; + $color = $STATS_COLORS[$id++ % count($STATS_COLORS)]; } $json[] = array( 'color' => $color, 'label' => (string)$k, 'value' => $v ); - ++$id; } + $accounted += $v; + } + if ($accounted / $total < 0.99) { + $json[] = array( + 'color' => '#eee', + 'label' => 'invalid', + 'value' => ($total - $accounted) + ); } $data['json'] = json_encode($json); Render::addTemplate('statistics/id44', $data); } + private function showLatestMachines() + { + $data = array('cutoff' => ceil(time() / 3600) * 3600 - 86400 * 7); + $res = Database::simpleQuery("SELECT machineuuid, clientip, hostname, firstseen, mbram, kvmstate, id44mb FROM machine" + . " WHERE firstseen > :cutoff ORDER BY firstseen DESC LIMIT 32", $data); + $rows = array(); + $count = 0; + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if (empty($row['hostname'])) { + $row['hostname'] = $row['clientip']; + } + $row['firstseen'] = date('d.m. H:i', $row['firstseen']); + $row['gbram'] = round(round($row['mbram'] / 500) / 2, 1); // Trial and error until we got "expected" rounding.. + $row['gbtmp'] = round($row['id44mb'] / 1024); + $row['ramclass'] = $this->ramColorClass($row['mbram']); + $row['kvmclass'] = $this->kvmColorClass($row['kvmstate']); + $row['hddclass'] = $this->hddColorClass($row['gbtmp']); + $row['kvmicon'] = $row['kvmstate'] === 'ENABLED' ? '✓' : '✗'; + if (++$count > 5) { + $row['style'] = 'display:none'; + } + $rows[] = $row; + } + Render::addTemplate('statistics/newclients', array('rows' => $rows, 'openbutton' => $count > 5)); + } + private function showMachineList($filter, $argument) { global $SIZE_RAM, $SIZE_ID44; @@ -202,7 +270,7 @@ class Page_Statistics extends Page return; } $res = Database::simpleQuery("SELECT machineuuid, macaddr, clientip, firstseen, lastseen," - . " logintime, lastboot, realcores, mbram, kvmstate, cpumodel, id44mb, hostname FROM machine" + . " logintime, lastboot, realcores, mbram, kvmstate, cpumodel, id44mb, hostname, notes IS NOT NULL AS hasnotes FROM machine" . " WHERE $where ORDER BY lastseen DESC, clientip ASC", $args); $rows = array(); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { @@ -275,7 +343,7 @@ class Page_Statistics extends Page private function showMachine($uuid) { $row = Database::queryFirst("SELECT machineuuid, macaddr, clientip, firstseen, lastseen, logintime, lastboot," - . " mbram, kvmstate, cpumodel, id44mb, data, hostname FROM machine WHERE machineuuid = :uuid", + . " mbram, kvmstate, cpumodel, id44mb, data, hostname, notes FROM machine WHERE machineuuid = :uuid", array('uuid' => $uuid)); // Mangle fields $row['firstseen'] = date('d.m.Y H:i', $row['firstseen']); @@ -305,6 +373,7 @@ class Page_Statistics extends Page Render::addScriptBottom('chart.min'); Render::addTemplate('statistics/machine-hdds', $hdds); } + Render::addTemplate('statistics/machine-notes', $row); } private function parseCpu(&$row, $data) @@ -341,13 +410,13 @@ class Page_Statistics extends Page $unit = $out[1] / (1024 * 1024); // Convert so that multiplying by unit yields MiB } else if (isset($hdd) && $unit !== 0 && preg_match(',^/dev/(\S+)\s+.*\s(\d+)\s+(\d+)\s+\d+\s+([0-9a-f]+)\s+(.*)$,i', $line, $out)) { // Some partition - $type = (string)$out[4]; - if ($type === '5') continue; + $type = strtolower($out[4]); + if ($type === '5' || $type === 'f' || $type === '85') continue; $partsize = round(($out[3] - $out[2]) * $unit); $hdd['partitions'][] = array( 'id' => $out[1], 'name' => $out[1], - 'size' => round($partsize / 1024), + 'size' => round($partsize / 1024, $partsize < 1024 ? 1 : 0), 'type' => ($type === '44' ? 'OpenSLX' : $out[5]), ); $hdd['json'][] = array( diff --git a/templates/statistics/clientlist.html b/templates/statistics/clientlist.html index e5f91493..879e27c4 100644 --- a/templates/statistics/clientlist.html +++ b/templates/statistics/clientlist.html @@ -14,7 +14,11 @@ {{#rows}} - {{hostname}}
{{machineuuid}}
+ + {{#hasnotes}}{{/hasnotes}} + {{hostname}} +
{{machineuuid}}
+ {{subnet}}{{lastoctet}}
{{macaddr}} {{lastboot}} {{kvmstate}} diff --git a/templates/statistics/cpumodels.html b/templates/statistics/cpumodels.html index c3d43aa4..f98b89db 100644 --- a/templates/statistics/cpumodels.html +++ b/templates/statistics/cpumodels.html @@ -31,8 +31,8 @@ animation: false, tooltipTemplate: "<%if (label){%><%=label%><%}%>", customTooltips: function(tooltip) { + if (sel !== false) sel.removeClass('info'); if (!tooltip) { - if (sel !== false) sel.removeClass('info'); sel = false; return; } diff --git a/templates/statistics/id44.html b/templates/statistics/id44.html index cd4e32d7..d9c92c47 100644 --- a/templates/statistics/id44.html +++ b/templates/statistics/id44.html @@ -12,7 +12,7 @@ {{lang_machineCount}} {{#rows}} - + {{gb}} GiB {{count}} @@ -29,8 +29,8 @@ animation: false, tooltipTemplate: "<%if (label){%><%=label%><%}%>", customTooltips: function(tooltip) { + if (sel !== false) sel.removeClass('info'); if (!tooltip) { - if (sel !== false) sel.removeClass('info'); sel = false; return; } diff --git a/templates/statistics/kvmstate.html b/templates/statistics/kvmstate.html index ea95df4e..5431990c 100644 --- a/templates/statistics/kvmstate.html +++ b/templates/statistics/kvmstate.html @@ -29,8 +29,8 @@ animation: false, tooltipTemplate: "<%if (label){%><%=label%><%}%>", customTooltips: function(tooltip) { + if (sel !== false) sel.removeClass('info'); if (!tooltip) { - if (sel !== false) sel.removeClass('info'); sel = false; return; } diff --git a/templates/statistics/machine-hdds.html b/templates/statistics/machine-hdds.html index 98cf65c5..cb3cbffc 100644 --- a/templates/statistics/machine-hdds.html +++ b/templates/statistics/machine-hdds.html @@ -35,8 +35,8 @@ animation: false, tooltipTemplate: "<%if (label){%><%=label%><%}%>", customTooltips: function(tooltip) { + if (sel !== false) sel.removeClass('info'); if (!tooltip) { - if (sel !== false) sel.removeClass('info'); sel = false; return; } diff --git a/templates/statistics/machine-main.html b/templates/statistics/machine-main.html index ac8b8001..985194bf 100644 --- a/templates/statistics/machine-main.html +++ b/templates/statistics/machine-main.html @@ -1,4 +1,7 @@ -

{{hostname}} {{#hostname}}–{{/hostname}} {{clientip}}

+

+ {{hostname}} {{#hostname}}–{{/hostname}} {{clientip}} + {{#notes}}{{/notes}} +

diff --git a/templates/statistics/machine-notes.html b/templates/statistics/machine-notes.html new file mode 100644 index 00000000..c4f97543 --- /dev/null +++ b/templates/statistics/machine-notes.html @@ -0,0 +1,17 @@ + +

{{lang_notes}}

+
+
+
+
+
+ + + + + +
+
+
+
+
\ No newline at end of file diff --git a/templates/statistics/memory.html b/templates/statistics/memory.html index b9ee77fb..1ebfbae0 100644 --- a/templates/statistics/memory.html +++ b/templates/statistics/memory.html @@ -12,7 +12,7 @@ {{lang_machineCount}} {{#rows}} - + {{gb}} GiB {{count}} @@ -29,8 +29,8 @@ animation: false, tooltipTemplate: "<%if (label){%><%=label%><%}%>", customTooltips: function(tooltip) { + if (sel !== false) sel.removeClass('info'); if (!tooltip) { - if (sel !== false) sel.removeClass('info'); sel = false; return; } diff --git a/templates/statistics/newclients.html b/templates/statistics/newclients.html new file mode 100644 index 00000000..0d9c74df --- /dev/null +++ b/templates/statistics/newclients.html @@ -0,0 +1,44 @@ +
+
+
+ {{lang_newMachines}} +
+
+ + + + + + + + + {{#rows}} + + + + + + + + {{/rows}} + {{#openbutton}} + + + + {{/openbutton}} +
{{lang_machine}}64BitRAMHDD
{{hostname}}{{firstseen}}{{kvmicon}}{{gbram}} GiB{{gbtmp}} GiB
+ + + + + + +
+
+
+
\ No newline at end of file -- cgit v1.2.3-55-g7522