Use one sql query to fetch device alert rules (#8391)

* Use one sql query to fetch device alert rules
Rename $device to $device_id to avoid confusion.  I didn't see any variable collisions.

* don't return disabled rules

* remove semi-colin
This commit is contained in:
Tony Murray
2018-03-15 11:03:45 -05:00
committed by Neil Lathwood
parent aec567f890
commit 72752fa2d0
2 changed files with 28 additions and 29 deletions

View File

@@ -130,20 +130,18 @@ function RunMacros($rule, $x = 1)
/** /**
* Get Alert-Rules for Devices * Get Alert-Rules for Devices
* @param int $device Device-ID * @param int $device_id Device-ID
* @return array * @return array
*/ */
function GetRules($device) function GetRules($device_id)
{ {
$groups = GetGroupsFromDevice($device); $query = "SELECT DISTINCT a.* FROM alert_rules a
$params = array($device, $device); LEFT JOIN alert_device_map d ON a.id=d.rule_id
$where = ""; LEFT JOIN alert_group_map g ON a.id=g.rule_id
foreach ($groups as $group) { LEFT JOIN device_group_device dg ON g.group_id=dg.device_group_id
$where .= " || group_id = ?"; WHERE a.disabled = 0 AND ((d.device_id IS NULL AND g.group_id IS NULL) OR d.device_id=? OR dg.device_id=?)";
$params[] = $group;
}
$query = "SELECT DISTINCT a.* FROM alert_rules a LEFT JOIN alert_device_map d ON a.id=d.rule_id LEFT JOIN alert_group_map g ON a.id=g.rule_id WHERE a.disabled = 0 AND ((d.device_id=? OR d.device_id IS NULL) $where)"; $params = [$device_id, $device_id];
return dbFetchRows($query, $params); return dbFetchRows($query, $params);
} }
@@ -165,16 +163,16 @@ function IsMaintenance($device)
} }
/** /**
* Run all rules for a device * Run all rules for a device
* @param int $device Device-ID * @param int $device_id Device-ID
* @return void * @return void
*/ */
function RunRules($device) function RunRules($device_id)
{ {
if (IsMaintenance($device) > 0) { if (IsMaintenance($device_id) > 0) {
echo "Under Maintenance, Skipping alerts.\r\n"; echo "Under Maintenance, Skipping alerts.\r\n";
return false; return false;
} }
foreach (GetRules($device) as $rule) { foreach (GetRules($device_id) as $rule) {
c_echo('Rule %p#'.$rule['id'].' (' . $rule['name'] . '):%n '); c_echo('Rule %p#'.$rule['id'].' (' . $rule['name'] . '):%n ');
$extra = json_decode($rule['extra'], true); $extra = json_decode($rule['extra'], true);
if (isset($extra['invert'])) { if (isset($extra['invert'])) {
@@ -183,12 +181,12 @@ function RunRules($device)
$inv = false; $inv = false;
} }
d_echo(PHP_EOL); d_echo(PHP_EOL);
$chk = dbFetchRow("SELECT state FROM alerts WHERE rule_id = ? && device_id = ? ORDER BY id DESC LIMIT 1", array($rule['id'], $device)); $chk = dbFetchRow("SELECT state FROM alerts WHERE rule_id = ? && device_id = ? ORDER BY id DESC LIMIT 1", array($rule['id'], $device_id));
if (empty($rule['query'])) { if (empty($rule['query'])) {
$rule['query'] = GenSQL($rule['rule'], $rule['builder']); $rule['query'] = GenSQL($rule['rule'], $rule['builder']);
} }
$sql = $rule['query']; $sql = $rule['query'];
$qry = dbFetchRows($sql, array($device)); $qry = dbFetchRows($sql, array($device_id));
$cnt = count($qry); $cnt = count($qry);
for ($i = 0; $i < $cnt; $i++) { for ($i = 0; $i < $cnt; $i++) {
if (isset($qry[$i]['ip'])) { if (isset($qry[$i]['ip'])) {
@@ -212,7 +210,7 @@ function RunRules($device)
c_echo('Status: %bNOCHG'); c_echo('Status: %bNOCHG');
// NOCHG here doesn't mean no change full stop. It means no change to the alert state // NOCHG here doesn't mean no change full stop. It means no change to the alert state
// So we update the details column with any fresh changes to the alert output we might have. // So we update the details column with any fresh changes to the alert output we might have.
$alert_log = dbFetchRow('SELECT alert_log.id, alert_log.details FROM alert_log,alert_rules WHERE alert_log.rule_id = alert_rules.id && alert_log.device_id = ? && alert_log.rule_id = ? && alert_rules.disabled = 0 ORDER BY alert_log.id DESC LIMIT 1', array($device, $rule['id'])); $alert_log = dbFetchRow('SELECT alert_log.id, alert_log.details FROM alert_log,alert_rules WHERE alert_log.rule_id = alert_rules.id && alert_log.device_id = ? && alert_log.rule_id = ? && alert_rules.disabled = 0 ORDER BY alert_log.id DESC LIMIT 1', array($device_id, $rule['id']));
$details = json_decode(gzuncompress($alert_log['details']), true); $details = json_decode(gzuncompress($alert_log['details']), true);
$details['contacts'] = GetContacts($qry); $details['contacts'] = GetContacts($qry);
$details['rule'] = $qry; $details['rule'] = $qry;
@@ -220,9 +218,9 @@ function RunRules($device)
dbUpdate(array('details' => $details), 'alert_log', 'id = ?', array($alert_log['id'])); dbUpdate(array('details' => $details), 'alert_log', 'id = ?', array($alert_log['id']));
} else { } else {
$extra = gzcompress(json_encode(array('contacts' => GetContacts($qry), 'rule'=>$qry)), 9); $extra = gzcompress(json_encode(array('contacts' => GetContacts($qry), 'rule'=>$qry)), 9);
if (dbInsert(array('state' => 1, 'device_id' => $device, 'rule_id' => $rule['id'], 'details' => $extra), 'alert_log')) { if (dbInsert(array('state' => 1, 'device_id' => $device_id, 'rule_id' => $rule['id'], 'details' => $extra), 'alert_log')) {
if (!dbUpdate(array('state' => 1, 'open' => 1), 'alerts', 'device_id = ? && rule_id = ?', array($device,$rule['id']))) { if (!dbUpdate(array('state' => 1, 'open' => 1), 'alerts', 'device_id = ? && rule_id = ?', array($device_id,$rule['id']))) {
dbInsert(array('state' => 1, 'device_id' => $device, 'rule_id' => $rule['id'], 'open' => 1,'alerted' => 0), 'alerts'); dbInsert(array('state' => 1, 'device_id' => $device_id, 'rule_id' => $rule['id'], 'open' => 1,'alerted' => 0), 'alerts');
} }
c_echo(PHP_EOL . 'Status: %rALERT'); c_echo(PHP_EOL . 'Status: %rALERT');
} }
@@ -231,9 +229,9 @@ function RunRules($device)
if ($chk['state'] === "0") { if ($chk['state'] === "0") {
c_echo('Status: %bNOCHG'); c_echo('Status: %bNOCHG');
} else { } else {
if (dbInsert(array('state' => 0, 'device_id' => $device, 'rule_id' => $rule['id']), 'alert_log')) { if (dbInsert(array('state' => 0, 'device_id' => $device_id, 'rule_id' => $rule['id']), 'alert_log')) {
if (!dbUpdate(array('state' => 0, 'open' => 1), 'alerts', 'device_id = ? && rule_id = ?', array($device,$rule['id']))) { if (!dbUpdate(array('state' => 0, 'open' => 1), 'alerts', 'device_id = ? && rule_id = ?', array($device_id,$rule['id']))) {
dbInsert(array('state' => 0, 'device_id' => $device, 'rule_id' => $rule['id'], 'open' => 1, 'alerted' => 0), 'alerts'); dbInsert(array('state' => 0, 'device_id' => $device_id, 'rule_id' => $rule['id'], 'open' => 1, 'alerted' => 0), 'alerts');
} }
c_echo(PHP_EOL . 'Status: %gOK'); c_echo(PHP_EOL . 'Status: %gOK');
} }
@@ -613,20 +611,20 @@ function ClearStaleAlerts()
/** /**
* Re-Validate Rule-Mappings * Re-Validate Rule-Mappings
* @param integer $device Device-ID * @param integer $device_id Device-ID
* @param integer $rule Rule-ID * @param integer $rule Rule-ID
* @return boolean * @return boolean
*/ */
function IsRuleValid($device, $rule) function IsRuleValid($device_id, $rule)
{ {
global $rulescache; global $rulescache;
if (empty($rulescache[$device]) || !isset($rulescache[$device])) { if (empty($rulescache[$device_id]) || !isset($rulescache[$device_id])) {
foreach (GetRules($device) as $chk) { foreach (GetRules($device_id) as $chk) {
$rulescache[$device][$chk['id']] = true; $rulescache[$device_id][$chk['id']] = true;
} }
} }
if ($rulescache[$device][$rule] === true) { if ($rulescache[$device_id][$rule] === true) {
return true; return true;
} }

View File

@@ -101,6 +101,7 @@ function dbQuery($sql, $parameters = array())
$fullSql = dbMakeQuery($sql, $parameters); $fullSql = dbMakeQuery($sql, $parameters);
if ($debug) { if ($debug) {
if (php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR'])) { if (php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR'])) {
$fullSql = str_replace(PHP_EOL, '', $fullSql);
if (preg_match('/(INSERT INTO `alert_log`).*(details)/i', $fullSql)) { if (preg_match('/(INSERT INTO `alert_log`).*(details)/i', $fullSql)) {
echo "\nINSERT INTO `alert_log` entry masked due to binary data\n"; echo "\nINSERT INTO `alert_log` entry masked due to binary data\n";
} else { } else {