diff options
Diffstat (limited to 'modules-available/statistics/page.inc.php')
-rw-r--r-- | modules-available/statistics/page.inc.php | 176 |
1 files changed, 128 insertions, 48 deletions
diff --git a/modules-available/statistics/page.inc.php b/modules-available/statistics/page.inc.php index 2b12c69f..c3ecf52b 100644 --- a/modules-available/statistics/page.inc.php +++ b/modules-available/statistics/page.inc.php @@ -106,11 +106,17 @@ class Page_Statistics extends Page 'op' => Page_Statistics::$op_nominal, 'type' => 'string', 'column' => true + ], + 'state' => [ + 'op' => Page_Statistics::$op_nominal, + 'type' => 'enum', + 'column' => true, + 'values' => ['occupied', 'on', 'off', 'idle', 'standby'] ] ]; if (Module::isAvailable('locations')) { Page_Statistics::$columns['location'] = [ - 'op' => Page_Statistics::$op_nominal, + 'op' => Page_Statistics::$op_stringcmp, 'type' => 'enum', 'column' => false, 'values' => array_keys(Location::getLocationsAssoc()), @@ -189,9 +195,36 @@ class Page_Statistics extends Page Util::redirect('?do=Statistics&uuid=' . $uuid); } elseif ($action === 'addprojector' || $action === 'delprojector') { $this->handleProjector($action); + } elseif ($action === 'delmachines') { + $this->deleteMachines(); + Util::redirect('?do=statistics', true); + } + } + + private function deleteMachines() + { + $ids = Request::post('uuid', [], 'array'); + $ids = array_values($ids); + if (empty($ids)) { + Message::addError('main.parameter-empty', 'uuid'); + return; + } + $res = Database::simpleQuery('SELECT machineuuid, locationid FROM machine WHERE machineuuid IN (:ids)', compact('ids')); + $ids = array_flip($ids); + $delete = []; + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + // TODO: Check locationid permissions + unset($ids[$row['machineuuid']]); + $delete[] = $row['machineuuid']; + } + if (!empty($delete)) { + Database::exec('DELETE FROM machine WHERE machineuuid IN (:delete)', compact('delete')); + Message::addSuccess('deleted-n-machines', count($delete)); + } + if (!empty($ids)) { + // TODO: Warn permissions + Message::addWarning('unknown-machine', implode(', ', array_keys($ids))); } - // Fix online state of machines that crashed -- TODO: Make cronjob for this - Database::exec("UPDATE machine SET lastboot = 0 WHERE lastseen < UNIX_TIMESTAMP() - 610"); } protected function doRender() @@ -199,7 +232,12 @@ class Page_Statistics extends Page $uuid = Request::get('uuid', false, 'string'); if ($uuid !== false) { $this->showMachine($uuid); + return; + } + $show = Request::get('show', 'stat', 'string'); + if ($show === 'projectors') { + $this->showProjectors(); return; } @@ -210,23 +248,19 @@ class Page_Statistics extends Page } $sortColumn = Request::any('sortColumn'); $sortDirection = Request::any('sortDirection'); - $filters = Filter::parseQuery($this->query); + $filters = Filter::parseQuery($this->query); $filterSet = new FilterSet($filters); $filterSet->setSort($sortColumn, $sortDirection); - - $show = Request::get('show', 'stat', 'string'); if ($show == 'list') { Render::openTag('div', array('class' => 'row')); $this->showFilter('list', $filterSet); Render::closeTag('div'); $this->showMachineList($filterSet); return; - } elseif ($show === 'projectors') { - $this->showProjectors(); - return; } + $filterSet->filterNonClients(); Render::openTag('div', array('class' => 'row')); $this->showFilter('stat', $filterSet); $this->showSummary($filterSet); @@ -253,11 +287,11 @@ class Page_Statistics extends Page ); if ($show === 'list') { - $data['listButtonClass'] = 'btn-primary'; - $data['statButtonClass'] = 'btn-default'; + $data['listButtonClass'] = 'active'; + $data['statButtonClass'] = ''; } else { - $data['listButtonClass'] = 'btn-default'; - $data['statButtonClass'] = 'btn-primary'; + $data['listButtonClass'] = ''; + $data['statButtonClass'] = 'active'; } @@ -308,6 +342,14 @@ class Page_Statistics extends Page } } + private function redirectFirst($where, $join, $args) + { + $res = Database::queryFirst("SELECT machineuuid FROM machine $join WHERE ($where) LIMIT 1", $args); + if ($res !== false) { + Util::redirect('?do=statistics&uuid=' . $res['machineuuid']); + } + } + /** * @param \FilterSet $filterSet */ @@ -316,8 +358,12 @@ class Page_Statistics extends Page $filterSet->makeFragments($where, $join, $sort, $args); $known = Database::queryFirst("SELECT Count(*) AS val FROM machine $join WHERE ($where)", $args); - $on = Database::queryFirst("SELECT Count(*) AS val FROM machine $join WHERE lastboot <> 0 AND ($where)", $args); - $used = Database::queryFirst("SELECT Count(*) AS val FROM machine $join WHERE lastboot <> 0 AND logintime <> 0 AND ($where)", $args); + // If we only have one machine, redirect to machine details + if ($known['val'] == 1) { + $this->redirectFirst($where, $join, $args); + } + $on = Database::queryFirst("SELECT Count(*) AS val FROM machine $join WHERE state IN ('IDLE', 'OCCUPIED') AND ($where)", $args); + $used = Database::queryFirst("SELECT Count(*) AS val FROM machine $join WHERE state = 'OCCUPIED' AND ($where)", $args); $hdd = Database::queryFirst("SELECT Count(*) AS val FROM machine $join WHERE badsectors >= 10 AND ($where)", $args); if ($on['val'] != 0) { $usedpercent = round($used['val'] / $on['val'] * 100); @@ -355,6 +401,10 @@ class Page_Statistics extends Page } $data['json'] = json_encode(array('labels' => $labels, 'datasets' => array($points1, $points2))); $data['query'] = $this->query; + if (Module::get('runmode') !== false) { + $res = Database::queryFirst('SELECT Count(*) AS cnt FROM runmode'); + $data['runmode'] = $res['cnt']; + } // Draw Render::addTemplate('summary', $data); } @@ -533,7 +583,8 @@ class Page_Statistics extends Page if (empty($row['hostname'])) { $row['hostname'] = $row['clientip']; } - $row['firstseen'] = date('d.m. H:i', $row['firstseen']); + $row['firstseen_int'] = $row['firstseen']; + $row['firstseen'] = Util::prettyTime($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']); @@ -553,29 +604,37 @@ class Page_Statistics extends Page */ private function showMachineList($filterSet) { + Module::isAvailable('js_stupidtable'); $filterSet->makeFragments($where, $join, $sort, $args); $xtra = ''; if ($filterSet->isNoId44Filter()) { - $xtra = ', data'; + $xtra .= ', data'; + } + if (Module::isAvailable('runmode')) { + $xtra .= ', runmode.module AS rmmodule'; + if (strpos($join, 'runmode') === false) { + $join .= ' LEFT JOIN runmode USING (machineuuid) '; + } } - $res = Database::simpleQuery('SELECT machineuuid, macaddr, clientip, firstseen, lastseen,' - . ' logintime, lastboot, realcores, mbram, kvmstate, cpumodel, id44mb, hostname, notes IS NOT NULL AS hasnotes,' + $res = Database::simpleQuery('SELECT machineuuid, macaddr, clientip, lastseen,' + . ' logintime, state, realcores, mbram, kvmstate, cpumodel, id44mb, hostname, notes IS NOT NULL AS hasnotes,' . ' badsectors ' . $xtra . ' FROM machine' . " $join WHERE $where $sort", $args); $rows = array(); $NOW = time(); + $singleMachine = 'none'; while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if ($row['lastboot'] == 0) { - $row['state_off'] = true; - } elseif ($row['logintime'] == 0) { - $row['state_idle'] = true; + if ($singleMachine === 'none') { + $singleMachine = $row['machineuuid']; } else { - $row['state_occupied'] = true; + $singleMachine = false; } - //$row['firstseen'] = date('d.m.Y H:i', $row['firstseen']); - $row['lastseen'] = date('d.m. H:i', $row['lastseen']); - //$row['lastboot'] = date('d.m. H:i', $row['lastboot']); + $row['state_' . $row['state']] = true; + //$row['firstseen'] = Util::prettyTime($row['firstseen']); + $row['lastseen_int'] = $row['lastseen']; + $row['lastseen'] = Util::prettyTime($row['lastseen']); + //$row['lastboot'] = Util::prettyTime($row['lastboot']); $row['gbram'] = round(round($row['mbram'] / 500) / 2, 1); // Trial and error until we got "expected" rounding.. $row['gbtmp'] = round($row['id44mb'] / 1024); $octets = explode('.', $row['clientip']); @@ -594,8 +653,12 @@ class Page_Statistics extends Page $row['nohdd'] = true; } } + $row['cpumodel'] = preg_replace('/\(R\)|\(TM\)|\bintel\b|\bamd\b|\bcpu\b|dual-core|\bdual\s+core\b|\bdual\b|\bprocessor\b/i', ' ', $row['cpumodel']); $rows[] = $row; } + if ($singleMachine !== false && $singleMachine !== 'none') { + Util::redirect('?do=statistics&uuid=' . $singleMachine); + } Render::addTemplate('clientlist', array( 'rowCount' => count($rows), 'rows' => $rows, @@ -605,7 +668,8 @@ class Page_Statistics extends Page 'sortColumn' => $filterSet->getSortColumn(), 'columns' => json_encode(Page_Statistics::$columns), 'showList' => 1, - 'show' => 'list' + 'show' => 'list', + 'redirect' => $_SERVER['QUERY_STRING'] )); } @@ -702,24 +766,40 @@ class Page_Statistics extends Page private function showMachine($uuid) { - $client = Database::queryFirst('SELECT machineuuid, locationid, macaddr, clientip, firstseen, lastseen, logintime, lastboot,' + $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', array('uuid' => $uuid)); + if ($client === false) { + Message::addError('unknown-machine', $uuid); + return; + } // Hack: Get raw collected data if (Request::get('raw', false)) { Header('Content-Type: text/plain; charset=utf-8'); die($client['data']); } + // Runmode + if (Module::isAvailable('runmode')) { + $data = RunMode::getRunMode($uuid, RunMode::DATA_STRINGS); + if ($data !== false) { + $client += $data; + } + } + if (!isset($client['isclient'])) { + $client['isclient'] = true; + } // Mangle fields $NOW = time(); - if ($client['lastboot'] == 0) { - $client['state_off'] = true; - } elseif ($client['logintime'] == 0) { - $client['state_idle'] = true; + if (!$client['isclient']) { + if ($client['state'] === 'IDLE') { + $client['state'] = 'OCCUPIED'; + } } else { - $client['state_occupied'] = true; - $this->fillSessionInfo($client); + if ($client['state'] === 'OCCUPIED') { + $this->fillSessionInfo($client); + } } + $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']); if ($client['lastboot'] == 0) { @@ -727,7 +807,7 @@ class Page_Statistics extends Page } else { $uptime = $NOW - $client['lastboot']; $client['lastboot_s'] = date('d.m.Y H:i', $client['lastboot']); - if (!isset($client['state_off']) || !$client['state_off']) { + if ($client['state'] === 'IDLE' || $client['state'] === 'OCCUPIED') { $client['lastboot_s'] .= ' (Up ' . floor($uptime / 86400) . 'd ' . gmdate('H:i', $uptime) . ')'; } } @@ -810,6 +890,8 @@ class Page_Statistics extends Page $last = false; $first = true; while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if (!$client['isclient'] && $row['typeid'] === '~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 $spans['graph'] .= '<div style="background:#444;left:0%;width:' . round((min($row['dateline'], $client['lastboot']) - $cutoff) * $scale, 2) . '%"> </div>'; @@ -832,7 +914,7 @@ class Page_Statistics extends Page $row['data'] -= ($cutoff - $row['dateline']); $row['dateline'] = $cutoff; } - $row['from'] = date('d.m. H:i', $row['dateline']); + $row['from'] = Util::prettyTime($row['dateline']); $row['duration'] = floor($row['data'] / 86400) . 'd ' . gmdate('H:i', $row['data']); if ($row['typeid'] === '~offline-length') { $row['glyph'] = 'off'; @@ -842,12 +924,17 @@ class Page_Statistics extends Page $color = '#e77'; } $spans['graph'] .= '<div style="background:' . $color . ';left:' . round(($row['dateline'] - $cutoff) * $scale, 2) . '%;width:' . round(($row['data']) * $scale, 2) . '%"> </div>'; - $spans['rows'][] = $row; + if ($client['isclient']) { + $spans['rows'][] = $row; + } $last = $row; } if ($first && $client['lastboot'] > $cutoff) { // Special case: offline before $spans['graph'] .= '<div style="background:#444;left:0%;width:' . round(($client['lastboot'] - $cutoff) * $scale, 2) . '%"> </div>'; + } elseif ($first) { + // Not seen in last two weeks + $spans['graph'] .= '<div style="background:#444;left:0%;width:100%"> </div>'; } 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) . '%"> </div>'; @@ -868,6 +955,7 @@ class Page_Statistics extends Page $spans['rows2'] = array_slice($spans['rows'], ceil(count($spans['rows']) / 2)); $spans['rows'] = array_slice($spans['rows'], 0, ceil(count($spans['rows']) / 2)); } + $spans['isclient'] = $client['isclient']; Render::addTemplate('machine-usage', $spans); // Any hdds? if (!empty($hdds['hdds'])) { @@ -877,21 +965,13 @@ class Page_Statistics extends Page if (Module::get('syslog') !== false) { $lres = Database::simpleQuery('SELECT logid, dateline, logtypeid, clientip, description, extra FROM clientlog' . ' WHERE machineuuid = :uuid ORDER BY logid DESC LIMIT 25', array('uuid' => $client['machineuuid'])); - $today = date('d.m.Y'); - $yesterday = date('d.m.Y', time() - 86400); $count = 0; $log = array(); while ($row = $lres->fetch(PDO::FETCH_ASSOC)) { if (substr($row['description'], -5) === 'on :0' && strpos($row['description'], 'root logged') === false) { continue; } - $day = date('d.m.Y', $row['dateline']); - if ($day === $today) { - $day = Dictionary::translate('lang_today'); - } elseif ($day === $yesterday) { - $day = Dictionary::translate('lang_yesterday'); - } - $row['date'] = $day . date(' H:i', $row['dateline']); + $row['date'] = Util::prettyTime($row['dateline']); $row['icon'] = $this->eventToIconName($row['logtypeid']); $log[] = $row; if (++$count === 10) { @@ -899,7 +979,7 @@ class Page_Statistics extends Page } } Render::addTemplate('syslog', array( - 'clientip' => $client['clientip'], + 'machineuuid' => $client['machineuuid'], 'list' => $log, )); } |