From 54a516de8a49bdcdd2b95ecbfe2a365a860adaf4 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 21 Jan 2019 14:49:54 +0100 Subject: [statistics] Log if client seems to have crashed Log when we reset a client's state in the cron job, as well as if we receive a poweron event even though the state in the DB is still IDLE or OCCUPIED. --- modules-available/statistics/api.inc.php | 17 +++++++++++++++++ modules-available/statistics/hooks/cron.inc.php | 13 +++++++++++++ 2 files changed, 30 insertions(+) diff --git a/modules-available/statistics/api.inc.php b/modules-available/statistics/api.inc.php index 8f5e9fd0..674cc48d 100644 --- a/modules-available/statistics/api.inc.php +++ b/modules-available/statistics/api.inc.php @@ -161,6 +161,11 @@ if ($type{0} === '~') { // Check for suspicious hardware changes if ($old !== false) { checkHardwareChange($old, $new); + + // 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']); + } } // Write statistics data @@ -403,6 +408,18 @@ function writeStatisticLog($type, $username, $data) )); } +function writeClientLog($type, $description) +{ + global $ip, $uuid; + Database::exec('INSERT INTO clientlog (dateline, logtypeid, clientip, machineuuid, description, extra) VALUES (UNIX_TIMESTAMP(), :type, :client, :uuid, :description, :longdesc)', array( + 'type' => $type, + 'client' => $ip, + 'description' => $description, + 'longdesc' => '', + 'uuid' => $uuid, + )); +} + // For backwards compat, we require the . prefix if ($type{0} === '.') { diff --git a/modules-available/statistics/hooks/cron.inc.php b/modules-available/statistics/hooks/cron.inc.php index 4df7b0d4..f05762bc 100644 --- a/modules-available/statistics/hooks/cron.inc.php +++ b/modules-available/statistics/hooks/cron.inc.php @@ -23,6 +23,19 @@ function state_cleanup() // Fix online state of machines that crashed $standby = time() - 86400 * 2; // Reset standby machines after two 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'"); + 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'], + 'longdesc' => '', + 'uuid' => $row['machineuuid'], + )); + } + // 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'"); } -- cgit v1.2.3-55-g7522