From caa63fb08ec97f660487286ec878d991a475dd90 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 12 Sep 2022 09:58:19 +0200 Subject: [eventlog] Add machine data to collected notification samples --- modules-available/eventlog/hooks/cron.inc.php | 38 ++++++++++++++++++++++ .../eventlog/inc/filterruleprocessor.inc.php | 20 +++++++----- modules-available/eventlog/install.inc.php | 24 +++++++++++--- 3 files changed, 69 insertions(+), 13 deletions(-) (limited to 'modules-available/eventlog') diff --git a/modules-available/eventlog/hooks/cron.inc.php b/modules-available/eventlog/hooks/cron.inc.php index bf7ced17..72aa4f76 100644 --- a/modules-available/eventlog/hooks/cron.inc.php +++ b/modules-available/eventlog/hooks/cron.inc.php @@ -27,3 +27,41 @@ if (mt_rand(1, 10) === 1) { } } } + +// Add missing/virtual columns to sample data +$todo = Database::simpleQuery("SELECT sampleid, data FROM notification_sample WHERE extended = 0 LIMIT 10"); +foreach ($todo as $sample) { + $data = json_decode($sample['data'], true); + // First, add all the machine columns + if (isset($data['machineuuid'])) { + $row = Database::queryFirst("SELECT " . implode(',', FilterRuleProcessor::MACHINE_COLUMNS) + . " FROM machine WHERE machineuuid = :uuid", ['uuid' => $data['machineuuid']]); + } elseif (isset($data['clientip'])) { + $row = Database::queryFirst("SELECT " . implode(',', FilterRuleProcessor::MACHINE_COLUMNS) + . " FROM machine WHERE clientip = :ip ORDER BY lastseen DESC LIMIT 1", ['ip' => $data['clientip']]); + } else { + $row = false; + } + if ($row !== false) { + $data += $row; + } + // Add virtual statistics columns + if (isset($data['machineuuid']) && Module::isAvailable('statistics')) { + foreach (FilterRuleProcessor::HW_QUERIES as $key => $elem) { + if (isset($data[$key])) + continue; // Already present... + $q = new HardwareQuery($elem[0], $data['machineuuid']); + $q->addColumn($elem[2], $elem[1]); + $res = $q->query(); + if ($res !== false) { + $row = $res->fetch(); + if ($row !== false && $row[$elem[1]] !== null) { + $data[$key] = $row[$elem[1]]; + } + } + } + } + // Finally, update entry + Database::exec("UPDATE notification_sample SET extended = 1, data = :data WHERE sampleid = :id", + ['id' => $sample['sampleid'], 'data' => json_encode($data)]); +} \ No newline at end of file diff --git a/modules-available/eventlog/inc/filterruleprocessor.inc.php b/modules-available/eventlog/inc/filterruleprocessor.inc.php index bd829b26..2eb0c252 100644 --- a/modules-available/eventlog/inc/filterruleprocessor.inc.php +++ b/modules-available/eventlog/inc/filterruleprocessor.inc.php @@ -181,8 +181,6 @@ class FilterRuleProcessor $pathElement = array_shift($path); // Get everything on this level if ($pathElement === '*') { - if (!is_array($data)) - return []; $return = []; if (empty($path)) { // End, everything needs to be primitive types @@ -201,11 +199,13 @@ class FilterRuleProcessor } return $return; } + if (!array_key_exists($pathElement, $data) && (isset($data['clientip']) || isset($data['machineuuid']))) { // An unknown key was requested, but we have clientip or machineuuid.... - if (in_array($pathElement, self::MACHINE_COLUMNS)) { - // Key matches a column from machine table, try to fetch it + if (in_array($pathElement, self::MACHINE_COLUMNS) || !isset($data['machineuuid'])) { + // Key matches a column from machine table, OR we don't have machineuuid but clientip + // try to fetch it. Second condition is in case we have a HW_QUERIES virtual column. if ($pathElement !== 'machineuuid' && isset($data['machineuuid'])) { $row = Database::queryFirst("SELECT " . implode(',', self::MACHINE_COLUMNS) . " FROM machine WHERE machineuuid = :uuid", ['uuid' => $data['machineuuid']]); @@ -216,27 +216,29 @@ class FilterRuleProcessor $row = false; } if ($row !== false) { - error_log('Additional client data fetched on the fly'); $data += $row; } - } elseif (isset($data['machineuuid']) + } + if (isset($data['machineuuid']) && isset(self::HW_QUERIES[$pathElement]) && Module::isAvailable('statistics')) { // Key matches a predefined hwinfo property, resolve.... $q = new HardwareQuery(self::HW_QUERIES[$pathElement][0], $data['machineuuid']); $q->addColumn(self::HW_QUERIES[$pathElement][2], self::HW_QUERIES[$pathElement][1]); $res = $q->query(); if ($res !== false) { - $row = $res->fetch(); - if ($row !== false) { - $data[$pathElement] = $row[self::HW_QUERIES[$pathElement][1]]; + foreach ($res as $row) { + $data[$pathElement][] = $row[self::HW_QUERIES[$pathElement][1]]; } } } } + if (!array_key_exists($pathElement, $data)) return []; if (empty($path) && !is_array($data[$pathElement])) return [$data[$pathElement]]; + if (empty($path) && ArrayUtil::isOnlyPrimitiveTypes($data[$pathElement])) + return $data[$pathElement]; if (is_array($data[$pathElement])) return self::get($path, $data[$pathElement]); return []; // No match diff --git a/modules-available/eventlog/install.inc.php b/modules-available/eventlog/install.inc.php index f6057d23..def608aa 100644 --- a/modules-available/eventlog/install.inc.php +++ b/modules-available/eventlog/install.inc.php @@ -41,12 +41,16 @@ $res[] = tableCreate('notification_rule_x_transport', ' KEY (`transportid`) '); -$res[] = tableCreate('notification_sample', ' - `type` varchar(40) CHARACTER SET ascii NOT NULL, +$res[] = tableCreate('notification_sample', " + `sampleid` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `dateline` int(10) UNSIGNED NOT NULL, + `extended` tinyint(1) NOT NULL DEFAULT '0', + `type` varchar(40) CHARACTER SET ascii NOT NULL, `data` mediumblob, - KEY (`type`, `dateline`) -'); + KEY (`type`, `dateline`), + KEY (`extended`), + PRIMARY KEY (`sampleid`) +"); // Update path @@ -63,6 +67,18 @@ $res[] = tableAddConstraint('notification_rule_x_transport', 'ruleid', $res[] = tableAddConstraint('notification_rule_x_transport', 'transportid', 'notification_backend', 'transportid', 'ON UPDATE CASCADE ON DELETE CASCADE'); +// 2022-07-20: Add flag to see if notification_sample has been extended +if (!tableHasColumn('notification_sample', 'extended')) { + if (Database::exec("ALTER TABLE notification_sample + ADD COLUMN `extended` tinyint(1) NOT NULL DEFAULT '0', + ADD KEY (`extended`), + ADD COLUMN `sampleid` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, + ADD PRIMARY KEY (`sampleid`)") === false) { + finalResponse(UPDATE_FAILED, 'Could not add extended flag to notification_sample: ' . Database::lastError()); + } + $res[] = UPDATE_DONE; +} + // Create response for browser if (in_array(UPDATE_DONE, $res)) { -- cgit v1.2.3-55-g7522