Do not purge alert_log table entries that have a matching active alert in alerts table (#10744)

* https://github.com/librenms/librenms/issues/10686

* Do not purge alert_logs table when there is a matching active alert in alerts table

* Do not purge alert_log table when there is a matching active alert in alerts table

* Do not purge alert_log table entries that has a matching active alert in alerts table

* Update daily.php

* Do not purge alert_log table entries that has a matching active alert in alerts table

* Do not purge alert_log table entries that has a matching active alert in alerts table

* Update functions.php

Missing }

* Do not purge alert_log table entries that has a matching active alert in alerts table

* Do not purge alert_log table entries that has a matching active alert in alerts table

* Do not purge alert_log table entries that has a matching active alert in alerts table

* Add deleting history of active alert_logs more than ? days

* Commit to replay CI

* Commit to replay CI
This commit is contained in:
louis-oui 2019-11-05 14:49:09 +01:00 committed by PipoCanaja
parent 55750cebb4
commit 0b01daa84c
2 changed files with 84 additions and 28 deletions

View File

@ -204,39 +204,65 @@ if ($options['f'] === 'notifications') {
}
if ($options['f'] === 'bill_data') {
try {
if (Config::get('distributed_poller')) {
MemcacheLock::lock('syslog_purge', 0, 86000);
}
$billing_data_purge = Config::get('billing_data_purge');
if (is_numeric($billing_data_purge) && $billing_data_purge > 0) {
# Deletes data older than XX months before the start of the last complete billing period
echo "Deleting billing data more than $billing_data_purge month before the last completed billing cycle\n";
$sql = "DELETE bill_data
FROM bill_data
INNER JOIN (SELECT bill_id,
SUBDATE(
SUBDATE(
ADDDATE(
subdate(curdate(), (day(curdate())-1)), # Start of this month
bill_day - 1), # Billing anniversary
INTERVAL IF(bill_day > DAY(curdate()), 1, 0) MONTH), # Deal with anniversary not yet happened this month
INTERVAL ? MONTH) AS threshold # Adjust based on config threshold
FROM bills) q
ON bill_data.bill_id = q.bill_id AND bill_data.timestamp < q.threshold;";
dbQuery($sql, array($billing_data_purge));
}
} catch (LockException $e) {
echo $e->getMessage() . PHP_EOL;
exit(-1);
}
# Deletes data older than XX months before the start of the last complete billing period
$msg = "Deleting billing data more than %d month before the last completed billing cycle\n";
$table = 'bill_data';
$sql = "DELETE bill_data
FROM bill_data
INNER JOIN (SELECT bill_id,
SUBDATE(
SUBDATE(
ADDDATE(
subdate(curdate(), (day(curdate())-1)), # Start of this month
bill_day - 1), # Billing anniversary
INTERVAL IF(bill_day > DAY(curdate()), 1, 0) MONTH), # Deal with anniversary not yet happened this month
INTERVAL ? MONTH) AS threshold # Adjust based on config threshold
FROM bills) q
ON bill_data.bill_id = q.bill_id AND bill_data.timestamp < q.threshold;";
lock_and_purge_query($table, $sql, $msg);
}
if ($options['f'] === 'alert_log') {
$ret = lock_and_purge('alert_log', 'time_logged < DATE_SUB(NOW(),INTERVAL ? DAY)');
exit($ret);
$msg = "Deleting alert_logs more than %d days that are not active\n";
$table = 'alert_log';
$sql = "DELETE alert_log
FROM alert_log
INNER JOIN alerts
ON alerts.device_id=alert_log.device_id AND alerts.rule_id=alert_log.rule_id
WHERE alerts.state=0 AND alert_log.time_logged < DATE_SUB(NOW(),INTERVAL ? DAY)
";
lock_and_purge_query($table, $sql, $msg);
# alert_log older than $config['alert_log_purge'] days match now only the alert_log of active alerts
# in case of flapping of an alert, many entries are kept in alert_log
# we want only to keep the last alert_log that contains the alert details
$msg = "Deleting history of active alert_logs more than %d days\n";
$sql = "DELETE
FROM alert_log
WHERE id IN(
SELECT id FROM(
SELECT id
FROM alert_log a1
WHERE
time_logged < DATE_SUB(NOW(),INTERVAL ? DAY)
AND (device_id, rule_id, time_logged) NOT IN (
SELECT device_id, rule_id, max(time_logged)
FROM alert_log a2 WHERE a1.device_id = a2.device_id AND a1.rule_id = a2.rule_id
AND a2.time_logged < DATE_SUB(NOW(),INTERVAL ? DAY)
)
) as c
)
";
$purge_duration = Config::get('alert_log_purge');
if (!(is_numeric($purge_duration) && $purge_duration > 0)) {
return -2;
}
$sql = str_replace("?", strval($purge_duration), $sql);
lock_and_purge_query($table, $sql, $msg);
}
if ($options['f'] === 'purgeusers') {
try {
if (Config::get('distributed_poller')) {

View File

@ -2526,6 +2526,36 @@ function lock_and_purge($table, $sql)
}
}
/**
* If Distributed, create a lock, then purge the mysql table according to the sql query
*
* @param string $table
* @param string $sql
* @param string $msg
* @return int exit code
*/
function lock_and_purge_query($table, $sql, $msg)
{
$purge_name = $table . '_purge';
if (Config::get('distributed_poller')) {
MemcacheLock::lock($purge_name, 0, 86000);
}
$purge_duration = Config::get($purge_name);
if (!(is_numeric($purge_duration) && $purge_duration > 0)) {
return -2;
}
try {
if (dbQuery($sql, array($purge_duration))) {
printf($msg, $purge_duration);
}
} catch (LockException $e) {
echo $e->getMessage() . PHP_EOL;
return -1;
}
return 0;
}
/**
* Convert space separated hex OID content to character
*