Files
librenms-librenms/includes/polling/applications/systemd.inc.php
Zane C. Bowers-Hadley 3491f3d704 fix path related issues for ss and systemd applications (#16045)
* fix path related issues for ss and systemd

* ensure / is before include

* re-order use order
2024-05-21 07:33:02 -05:00

172 lines
5.0 KiB
PHP

<?php
use LibreNMS\Config;
use LibreNMS\Exceptions\JsonAppException;
use LibreNMS\Exceptions\JsonAppMissingKeysException;
use LibreNMS\RRD\RrdDefinition;
require_once Config::get('install_dir') . '/includes/systemd-shared.inc.php';
$name = 'systemd';
$output = 'OK';
$polling_type = 'app';
$metrics = [];
// FIXME sigh
if (! function_exists('systemd_data_update_helper')) {
/**
* Performs a data update and returns the updated metrics.
*
* @param class $device
* @param string $app_id
* @param array $fields
* @param array $metrics
* @param string $name
* @param string $polling_type
* @param class $rrd_def
* @param string $state_type
* @return $metrics
*/
function systemd_data_update_helper(
$device,
$app_id,
$fields,
$metrics,
$name,
$polling_type,
$rrd_def,
$state_type,
$rrd_flattened_name
) {
$rrd_flattened_name = is_null($rrd_flattened_name)
? $state_type
: $rrd_flattened_name;
$rrd_name = [$polling_type, $name, $app_id, $rrd_flattened_name];
// This if block allows metric names to be kept consistent
// regardless of whether the metric is stored in an shared
// or individual RRD.
if (isset($metrics[$state_type])) {
$metrics[$state_type] = array_merge($metrics[$state_type], $fields);
} else {
$metrics[$state_type] = $fields;
}
$tags = [
'name' => $name,
'app_id' => $app_id,
'type' => $state_type,
'rrd_def' => $rrd_def,
'rrd_name' => $rrd_name,
];
data_update($device, $polling_type, $tags, $fields);
return $metrics;
}
}
// Grab systemd json data.
try {
$systemd_data = json_app_get($device, $name, 1)['data'];
} catch (JsonAppMissingKeysException $e) {
$systemd_data = $e->getParsedJson();
} catch (JsonAppException $e) {
echo PHP_EOL .
$name .
':' .
$e->getCode() .
':' .
$e->getMessage() .
PHP_EOL;
update_application($app, $e->getCode() . ':' . $e->getMessage(), $metrics);
return;
}
// Use the mapping variable in systemd-shared.inc.php to parse
// the json data received from the systemd.py script.
foreach ($systemd_mapper as $state_type => $state_statuses) {
$shared_rrd_def = RrdDefinition::make();
$shared_fields = [];
$sub_state_type = null;
$flattened_type = $state_type;
// Ternary-depth systemd type check.
if (preg_match('/^(.+)_(.+)$/', $state_type, $regex_matches)) {
if (! in_array($regex_matches[1], $state_type_ternary_depth)) {
continue;
}
$state_type = $regex_matches[1];
$sub_state_type = $regex_matches[2];
}
// Iterate through unit state type's statuses.
foreach ($state_statuses as $state_status => $rrd_location) {
$field_value = null;
$field_name = $state_status;
if (is_null($sub_state_type)) {
$field_value = $systemd_data[$state_type][$state_status] ?? null;
} else {
$field_value =
$systemd_data[$state_type][$sub_state_type][$state_status] ??
null;
}
// Verify data passed by application script is valid.
if (! is_int($field_value) && ! is_null($field_value)) {
$log_message =
'Systemd Polling Warning: Invalid data returned by application for systemd unit ' .
$flattened_type .
' state with' .
$state_status .
' state status: ' .
$field_value;
log_event($log_message, $device, 'application');
continue;
}
// New metrics MUST use the 'individual' type because
// it is not possible to automatically update 'shared'
// RRDs with new metrics.
if ($rrd_location === 'individual') {
$individual_fields = [];
$individual_rrd_def = RrdDefinition::make();
$individual_fields[$field_name] = $field_value;
$individual_rrd_def->addDataset($field_name, 'GAUGE', 0);
$rrd_flattened_type = $flattened_type . '-' . $field_name;
$metrics = systemd_data_update_helper(
$device,
$app->app_id,
$individual_fields,
$metrics,
$name,
$polling_type,
$individual_rrd_def,
$flattened_type,
$rrd_flattened_type
);
continue;
}
// Update shared_fields and rrd definition.
$shared_fields[$field_name] = $field_value;
$shared_rrd_def->addDataset($field_name, 'GAUGE', 0);
}
$metrics = systemd_data_update_helper(
$device,
$app->app_id,
$shared_fields,
$metrics,
$name,
$polling_type,
$shared_rrd_def,
$flattened_type,
null
);
}
update_application($app, $output, $metrics);