mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
feature: Save application metrics to db for alerting (#7828)
* feature: save application metrics to db for alerting However, alerting will not work because ResolveGlues() is broken. Can add workaround after state_translations alerting is merged Does not update all applications yet, not sure if that should be done here or in another PR. Introduces two handy functions dbDeleteOrphans() and array_by_column(). Will replace those in other locations after this is merged or separate them out if this is not merged. * remove accidental inclusions * Add db schema
This commit is contained in:
committed by
Neil Lathwood
parent
edf26c1106
commit
4a03e7838e
@@ -1866,3 +1866,15 @@ function check_file_permissions($file, $mask)
|
||||
|
||||
return ($perms & $mask) === $mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Index an array by a column
|
||||
*
|
||||
* @param array $array
|
||||
* @param string|int $column
|
||||
* @return array
|
||||
*/
|
||||
function array_by_column($array, $column)
|
||||
{
|
||||
return array_combine(array_column($array, $column), $array);
|
||||
}
|
||||
|
@@ -292,6 +292,33 @@ function dbDelete($table, $where = null, $parameters = array())
|
||||
}//end dbDelete()
|
||||
|
||||
|
||||
/**
|
||||
* Delete orphaned entries from a table that no longer have a parent in parent_table
|
||||
*
|
||||
* @param string $parent_table
|
||||
* @param string $child_table
|
||||
* @param string $id_column
|
||||
* @return bool|int
|
||||
*/
|
||||
function dbDeleteOrphans($parent_table, $child_table, $id_column)
|
||||
{
|
||||
global $database_link;
|
||||
$time_start = microtime(true);
|
||||
|
||||
$sql = "DELETE C FROM `$child_table` C";
|
||||
$sql .= " LEFT JOIN `$parent_table` P USING (`$id_column`)";
|
||||
$sql .= " WHERE P.`$id_column` IS NULL";
|
||||
|
||||
$result = dbQuery($sql, array());
|
||||
|
||||
recordDbStatistic('delete', $time_start);
|
||||
if ($result) {
|
||||
return mysqli_affected_rows($database_link);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetches all of the rows (associatively) from the last performed query.
|
||||
* Most other retrieval functions build off this
|
||||
|
@@ -105,6 +105,9 @@ if ($num > 0) {
|
||||
}
|
||||
}
|
||||
|
||||
// clean application_metrics
|
||||
dbDeleteOrphans('applications', 'application_metrics', 'app_id');
|
||||
|
||||
echo PHP_EOL;
|
||||
|
||||
unset(
|
||||
|
@@ -11,7 +11,6 @@ if (!empty($agent_data['app'][$name])) {
|
||||
$nginx = snmp_get($device, '.1.3.6.1.4.1.8072.1.3.2.3.1.2.5.110.103.105.110.120', '-Ovq');
|
||||
}
|
||||
$nginx = trim($nginx, '"');
|
||||
update_application($app, $nginx);
|
||||
|
||||
echo ' nginx';
|
||||
|
||||
@@ -36,6 +35,7 @@ $fields = array(
|
||||
|
||||
$tags = compact('name', 'app_id', 'rrd_name', 'rrd_def');
|
||||
data_update($device, 'app', $tags, $fields);
|
||||
update_application($app, $nginx, '', $fields);
|
||||
|
||||
// Unset the variables we set here
|
||||
unset($nginx, $active, $reading, $writing, $waiting, $req, $rrd_name, $rrd_def, $tags);
|
||||
|
@@ -574,9 +574,10 @@ function location_to_latlng($device)
|
||||
*
|
||||
* @param array $app app from the db, including app_id
|
||||
* @param string $response This should be the full output
|
||||
* @param string $current This is the current value we store in rrd for graphing
|
||||
* @param string $status This is the current value for alerting
|
||||
* @param array $metrics an array of additional metrics to store in the database for alerting
|
||||
*/
|
||||
function update_application($app, $response, $current = '')
|
||||
function update_application($app, $response, $status = '', $metrics = array())
|
||||
{
|
||||
if (!is_numeric($app['app_id'])) {
|
||||
d_echo('$app does not contain app_id, could not update');
|
||||
@@ -585,7 +586,7 @@ function update_application($app, $response, $current = '')
|
||||
|
||||
$data = array(
|
||||
'app_state' => 'UNKNOWN',
|
||||
'app_status' => $current,
|
||||
'app_status' => $status,
|
||||
'timestamp' => array('NOW()'),
|
||||
);
|
||||
|
||||
@@ -603,6 +604,53 @@ function update_application($app, $response, $current = '')
|
||||
$data['app_state_prev'] = $app['app_state'];
|
||||
}
|
||||
dbUpdate($data, 'applications', '`app_id` = ?', array($app['app_id']));
|
||||
|
||||
// update metrics
|
||||
if (!empty($metrics)) {
|
||||
$db_metrics = dbFetchRows('SELECT * FROM `application_metrics` WHERE app_id=?', array($app['app_id']));
|
||||
$db_metrics = array_by_column($db_metrics, 'metric');
|
||||
|
||||
echo ': ';
|
||||
foreach ($metrics as $metric_name => $value) {
|
||||
if (!isset($db_metrics[$metric_name])) {
|
||||
// insert new metric
|
||||
dbInsert(
|
||||
array(
|
||||
'app_id' => $app['app_id'],
|
||||
'metric' => $metric_name,
|
||||
'value' => $value,
|
||||
),
|
||||
'application_metrics'
|
||||
);
|
||||
echo '+';
|
||||
} elseif ($value != $db_metrics[$metric_name]['value']) {
|
||||
dbUpdate(
|
||||
array(
|
||||
'value' => $value,
|
||||
'value_prev' => $db_metrics[$metric_name]['value'],
|
||||
),
|
||||
'application_metrics',
|
||||
'app_id=? && metric=?',
|
||||
array($app['app_id'], $metric_name)
|
||||
);
|
||||
echo 'U';
|
||||
} else {
|
||||
echo '.';
|
||||
}
|
||||
|
||||
unset($db_metrics[$metric_name]);
|
||||
}
|
||||
|
||||
// remove no longer existing metrics (generally should not happen
|
||||
foreach ($db_metrics as $db_metric) {
|
||||
dbDelete(
|
||||
'application_metrics',
|
||||
'app_id=? && metric=?',
|
||||
array($app['app_id'], $db_metric['metric'])
|
||||
);
|
||||
echo '-';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function convert_to_celsius($value)
|
||||
|
@@ -133,6 +133,14 @@ applications:
|
||||
Indexes:
|
||||
PRIMARY: { Name: PRIMARY, Columns: [app_id], Unique: true, Type: BTREE }
|
||||
unique_index: { Name: unique_index, Columns: [device_id, app_type], Unique: true, Type: BTREE }
|
||||
application_metrics:
|
||||
Columns:
|
||||
- { Field: app_id, Type: int(11), 'Null': false, Extra: '' }
|
||||
- { Field: metric, Type: varchar(18), 'Null': false, Extra: '' }
|
||||
- { Field: value, Type: int(11), 'Null': true, Extra: '' }
|
||||
- { Field: value_prev, Type: int(11), 'Null': true, Extra: '' }
|
||||
Indexes:
|
||||
application_metrics_app_id_metric_uindex: { Name: application_metrics_app_id_metric_uindex, Columns: [app_id, metric], Unique: true, Type: BTREE }
|
||||
authlog:
|
||||
Columns:
|
||||
- { Field: id, Type: int(11), 'Null': false, Extra: auto_increment }
|
||||
|
2
sql-schema/219.sql
Normal file
2
sql-schema/219.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
CREATE TABLE application_metrics (app_id INT(11) NOT NULL, metric VARCHAR(18) NOT NULL, value INT(11), value_prev INT(11));
|
||||
CREATE UNIQUE INDEX application_metrics_app_id_metric_uindex ON application_metrics (app_id, metric);
|
Reference in New Issue
Block a user