Files
librenms-librenms/includes/polling/functions.inc.php

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

537 lines
21 KiB
PHP
Raw Normal View History

<?php
use Illuminate\Support\Str;
use LibreNMS\Enum\Severity;
use LibreNMS\Exceptions\JsonAppBase64DecodeException;
use LibreNMS\Exceptions\JsonAppBlankJsonException;
use LibreNMS\Exceptions\JsonAppExtendErroredException;
use LibreNMS\Exceptions\JsonAppGzipDecodeException;
use LibreNMS\Exceptions\JsonAppMissingKeysException;
use LibreNMS\Exceptions\JsonAppParsingFailedException;
use LibreNMS\Exceptions\JsonAppPollingFailedException;
use LibreNMS\Exceptions\JsonAppWrongVersionException;
use LibreNMS\RRD\RrdDefinition;
use LibreNMS\Util\Debug;
use LibreNMS\Util\Number;
use LibreNMS\Util\UserFuncHelper;
function bulk_sensor_snmpget($device, $sensors)
{
$oid_per_pdu = get_device_oid_limit($device);
$sensors = array_chunk($sensors, $oid_per_pdu);
$cache = [];
foreach ($sensors as $chunk) {
$oids = array_map(function ($data) {
return $data['sensor_oid'];
}, $chunk);
$oids = implode(' ', $oids);
$multi_response = snmp_get_multi_oid($device, $oids, '-OUQntea');
$cache = array_merge($cache, $multi_response);
}
2020-09-21 15:43:38 +02:00
return $cache;
}
/**
* @param $device
2021-09-08 23:35:56 +02:00
* @param string $type type/class of sensor
* @return array
*/
function sensor_precache($device, $type)
{
$sensor_cache = [];
if (file_exists('includes/polling/sensors/pre-cache/' . $device['os'] . '.inc.php')) {
include 'includes/polling/sensors/pre-cache/' . $device['os'] . '.inc.php';
}
2020-09-21 15:43:38 +02:00
return $sensor_cache;
}
function poll_sensor($device, $class)
{
global $agent_sensors;
2015-07-13 20:10:26 +02:00
$sensors = [];
$misc_sensors = [];
$all_sensors = [];
foreach (dbFetchRows('SELECT * FROM `sensors` WHERE `sensor_class` = ? AND `device_id` = ?', [$class, $device['device_id']]) as $sensor) {
if ($sensor['poller_type'] == 'agent') {
// Agent sensors are polled in the unix-agent
} elseif ($sensor['poller_type'] == 'ipmi') {
$misc_sensors[] = $sensor;
} else {
$sensors[] = $sensor;
}
}
$snmp_data = bulk_sensor_snmpget($device, $sensors);
$sensor_cache = sensor_precache($device, $class);
foreach ($sensors as $sensor) {
echo 'Checking (' . $sensor['poller_type'] . ") $class " . $sensor['sensor_descr'] . '... ' . PHP_EOL;
2015-07-13 20:10:26 +02:00
if ($sensor['poller_type'] == 'snmp') {
$mibdir = null;
2016-08-07 11:40:37 +02:00
$sensor_value = trim(str_replace('"', '', $snmp_data[$sensor['sensor_oid']] ?? ''));
if (file_exists('includes/polling/sensors/' . $class . '/' . $device['os'] . '.inc.php')) {
require 'includes/polling/sensors/' . $class . '/' . $device['os'] . '.inc.php';
} elseif (isset($device['os_group']) && file_exists('includes/polling/sensors/' . $class . '/' . $device['os_group'] . '.inc.php')) {
require 'includes/polling/sensors/' . $class . '/' . $device['os_group'] . '.inc.php';
}
if ($class == 'state') {
if (! is_numeric($sensor_value)) {
$state_value = dbFetchCell(
add app for getting status of TCP connections for specified services (#8090) * add the poller for portactivity * add the ability to get monitor ports for portactivity * add the graphs for displaying stuff for the portactivity app * add the portactivity app page * update the docs for Portactivity * remove extra line * minor doc update for Portactivity * add update_application line * convert to use json_app_get * convert curly brackets to square * style fix * remote error, errorString, and version after they stop being important so they are not processed * add alert rule examples * add the poller for portactivity * add the ability to get monitor ports for portactivity * add the graphs for displaying stuff for the portactivity app * add the portactivity app page * update the docs for Portactivity * remove extra line * minor doc update for Portactivity * add update_application line * convert to use json_app_get * convert curly brackets to square * style fix * remote error, errorString, and version after they stop being important so they are not processed * add alert rule examples * remove dump of get_portactivity_ports function added during rebase * update to the current json_app_get * add portactivity snmprec * add the portactivity test data * whoops bad merge when rebasing... fix * minor formatting cleanup and add a missing comma * fix some odditities with what one of the tests is doing * whoops... include the use for the exception * set the response to okay * attempt to make snmpsim array check happy again * the json now lints * more making metric testing happy * one more update to make travis-ci happy * now flattens arrays also add array_flatten * rename array_flatten to data_flatten as pre-commit chokes on it as laravel has something similarly named * go through and properly add all the metrics * tested with the newest one and it works * whoops, clean up json and remove prototype that was used when putting it together * doh! make it happy with laravel now * see if a minor changing in formatting for the numbers makes the polling unit test happy * order them properly * remove a comma * a few more minor fixes
2018-11-22 09:05:38 -06:00
'SELECT `state_value`
FROM `state_translations` LEFT JOIN `sensors_to_state_indexes`
ON `state_translations`.`state_index_id` = `sensors_to_state_indexes`.`state_index_id`
WHERE `sensors_to_state_indexes`.`sensor_id` = ?
AND `state_translations`.`state_descr` LIKE ?',
[$sensor['sensor_id'], $sensor_value]
);
d_echo('State value of ' . $sensor_value . ' is ' . $state_value . "\n");
if (is_numeric($state_value)) {
$sensor_value = $state_value;
}
}
2015-07-13 20:10:26 +02:00
}//end if
unset($mib);
2016-08-07 11:40:37 +02:00
unset($mibdir);
$sensor['new_value'] = $sensor_value;
$all_sensors[] = $sensor;
}
}
foreach ($misc_sensors as $sensor) {
if ($sensor['poller_type'] == 'agent') {
if (isset($agent_sensors)) {
$sensor_value = $agent_sensors[$class][$sensor['sensor_type']][$sensor['sensor_index']]['current'];
$sensor['new_value'] = $sensor_value;
$all_sensors[] = $sensor;
} else {
echo "no agent data!\n";
continue;
2015-07-13 20:10:26 +02:00
}
} elseif ($sensor['poller_type'] == 'ipmi') {
echo " already polled.\n";
// ipmi should probably move here from the ipmi poller file (FIXME)
continue;
} else {
echo "unknown poller type!\n";
continue;
2015-07-13 20:10:26 +02:00
}//end if
}
record_sensor_data($device, $all_sensors);
}//end poll_sensor()
/**
* @param $device
* @param $all_sensors
*/
function record_sensor_data($device, $all_sensors)
{
$supported_sensors = [
'airflow' => 'cfm',
'ber' => '',
'bitrate' => 'bps',
'charge' => '%',
'chromatic_dispersion' => 'ps/nm',
'cooling' => 'W',
'count' => '',
'current' => 'A',
'delay' => 's',
'dbm' => 'dBm',
'eer' => 'eer',
'fanspeed' => 'rpm',
'frequency' => 'Hz',
'humidity' => '%',
'load' => '%',
'loss' => '%',
'percent' => '%',
'power' => 'W',
'power_consumed' => 'kWh',
'power_factor' => '',
'pressure' => 'kPa',
'quality_factor' => 'dB',
'runtime' => 'Min',
'signal' => 'dBm',
'snr' => 'SNR',
'state' => '#',
'temperature' => 'C',
'tv_signal' => 'dBmV',
'voltage' => 'V',
'waterflow' => 'l/m',
];
2015-07-13 20:10:26 +02:00
foreach ($all_sensors as $sensor) {
$class = ucfirst($sensor['sensor_class']);
$unit = $supported_sensors[$sensor['sensor_class']];
$sensor_value = Number::extract($sensor['new_value']);
$prev_sensor_value = $sensor['sensor_current'];
if ($sensor_value == -32768 || is_nan($sensor_value)) {
echo 'Invalid (-32768 or NaN)';
$sensor_value = 0;
2015-04-11 19:47:56 +01:00
}
if ($sensor['sensor_divisor'] && $sensor_value !== 0) {
$sensor_value = ($sensor_value / $sensor['sensor_divisor']);
}
if ($sensor['sensor_multiplier']) {
$sensor_value = ($sensor_value * $sensor['sensor_multiplier']);
}
if (isset($sensor['user_func'])) {
if (is_callable($sensor['user_func'])) {
$sensor_value = $sensor['user_func']($sensor_value);
} else {
$sensor_value = (new UserFuncHelper($sensor_value, $sensor['new_value'], $sensor))->{$sensor['user_func']}();
}
}
$rrd_name = get_sensor_rrd_name($device, $sensor);
$rrd_def = RrdDefinition::make()->addDataset('sensor', $sensor['rrd_type']);
echo "$sensor_value $unit\n";
$fields = [
'sensor' => $sensor_value,
];
$tags = [
'sensor_class' => $sensor['sensor_class'],
'sensor_type' => $sensor['sensor_type'],
'sensor_descr' => $sensor['sensor_descr'],
'sensor_index' => $sensor['sensor_index'],
'rrd_name' => $rrd_name,
'rrd_def' => $rrd_def,
];
data_update($device, 'sensor', $tags, $fields);
2015-08-19 20:58:02 +00:00
// FIXME also warn when crossing WARN level!
if ($sensor['sensor_limit_low'] != '' && $prev_sensor_value > $sensor['sensor_limit_low'] && $sensor_value < $sensor['sensor_limit_low'] && $sensor['sensor_alert'] == 1) {
echo 'Alerting for ' . $device['hostname'] . ' ' . $sensor['sensor_descr'] . "\n";
log_event("$class under threshold: $sensor_value $unit (< {$sensor['sensor_limit_low']} $unit)", $device, $sensor['sensor_class'], 4, $sensor['sensor_id']);
} elseif ($sensor['sensor_limit'] != '' && $prev_sensor_value < $sensor['sensor_limit'] && $sensor_value > $sensor['sensor_limit'] && $sensor['sensor_alert'] == 1) {
echo 'Alerting for ' . $device['hostname'] . ' ' . $sensor['sensor_descr'] . "\n";
log_event("$class above threshold: $sensor_value $unit (> {$sensor['sensor_limit']} $unit)", $device, $sensor['sensor_class'], 4, $sensor['sensor_id']);
}
if ($sensor['sensor_class'] == 'state' && $prev_sensor_value != $sensor_value) {
$trans = array_column(
dbFetchRows(
'SELECT `state_translations`.`state_value`, `state_translations`.`state_descr` FROM `sensors_to_state_indexes` LEFT JOIN `state_translations` USING (`state_index_id`) WHERE `sensors_to_state_indexes`.`sensor_id`=? AND `state_translations`.`state_value` IN (?,?)',
[$sensor['sensor_id'], $sensor_value, $prev_sensor_value]
),
'state_descr',
'state_value'
);
log_event("$class sensor {$sensor['sensor_descr']} has changed from {$trans[$prev_sensor_value]} ($prev_sensor_value) to {$trans[$sensor_value]} ($sensor_value)", $device, $class, 3, $sensor['sensor_id']);
}
if ($sensor_value != $prev_sensor_value) {
dbUpdate(['sensor_current' => $sensor_value, 'sensor_prev' => $prev_sensor_value, 'lastupdate' => ['NOW()']], 'sensors', '`sensor_class` = ? AND `sensor_id` = ?', [$sensor['sensor_class'], $sensor['sensor_id']]);
}
}
}
/**
* Update the application status and output in the database.
*
* Metric values should have key for of the matching name.
* If you have multiple groups of metrics, you can group them with multiple sub arrays
* The group name (key) will be prepended to each metric in that group, separated by an underscore
* The special group "none" will not be prefixed.
*
add the ability for storing app data to prevent spamming of the event log via via component usage (#14087) * initial work on add the ability to save/fetch app data * update to use get_app_data for ZFS * update the poller for the new app_data stuff * ZFS now logs changes to pools * add schema update for app_data stuff * small formatting fix * add a missing \ * now adds a column * sql-schema is no longer used, so remove the file that was added here * misc cleanups * rename the method in database/migrations/2022_07_03_1947_add_app_data.php * hopefully fix the migration bit * add the column to misc/db_schema.yaml * more misc small DB fixes * update the test as the json column uses collat of utf8mb4_bin * revert the last change and try manually setting it to what is expected * remove a extra ; * update suricata as well * correct the instance -> instances in one location to prevent the old instance list from being stomped * remove a extra ; * update fail2ban to use it as well * remove two unused functions as suricata and fail2ban no longer use components * style cleanup * postgres poller updated to use it * update html side of the postgres bits * chronyd now uses app data bits now as well * portactivity now uses it as well * style fix * sort the returned arrays from app_data * correct log message for port activity * collocation change * try re-ordering it * add in the new data column to the tests * remove a extra , * hmm... ->collate('utf8mb4_unicode_ci') is not usable as apparently collate does not exist * change the column type from json to longtext * mv chronyd stuff while I sort out the rest of the tests... damn thing is always buggy * hmm... fix a missing line then likely move stuff back * style fix * add fillable * add the expexcted data for fail2ban json * escape a " I missed * add data for portactivity * add suricata app data * add app data to zfs legacy test * put the moved tests back into place and update zfs-v1 test * add app data for chronyd test * add app data for fail2ban legacy test * update zfs v1 app data * add some notes on application dev work * add Developing/Application-Notes.md to mkdocs.yml * add data column to it * added various suggestions from bennet-esyoil * convert from isset to sizeof * type fix * fully remove the old save app data function and move it into a helper function... the other still needs cleaned up prior to removal * update docs * get_app_data is fully removed now as well * a few style fixes * add $casts * update chronyd test * attempt to fix the data * more doc cleanup and try changing the cast * style fix * revert the changes to the chronyd test * apply a few of murrant's suggestions * document working with ->data as json and non-josn * remove two no-longer used in this PR exceptions * ->data now operates transparently * style fix * update data tests * fix json * test fix * update the app notes to reflect how app data now works * app test fix * app data fix for linux_lsi * json fix * minor doc cleanup * remove duplicate querty and use json_decode instead * style fix * modelize the app poller * use a anon func instead of foreach * test update * style cleanup * style cleanup * another test cleanup * more test cleanup * reverse the test changes and add in some more glue code * revert one of the test changes * another small test fix * Make things use models Left some array access, but those will still work just fine. * missed chronyd and portactivity * rename poll to avoid make it any confusion * Remove extra save and fix timestamp * save any changes made to app->data * nope, that was not it * What are magic methods and how do they work? * fix two typos * update linux_lsi test * change quote type Co-authored-by: Tony Murray <murraytony@gmail.com>
2022-07-22 16:01:55 -05:00
* @param \App\Models\Application $app app from the db, including app_id
2021-09-08 23:35:56 +02:00
* @param string $response This should be the return state of Application polling
* @param array $metrics an array of additional metrics to store in the database for alerting
* @param string $status This is the current value for alerting
*/
function update_application($app, $response, $metrics = [], $status = '')
{
add the ability for storing app data to prevent spamming of the event log via via component usage (#14087) * initial work on add the ability to save/fetch app data * update to use get_app_data for ZFS * update the poller for the new app_data stuff * ZFS now logs changes to pools * add schema update for app_data stuff * small formatting fix * add a missing \ * now adds a column * sql-schema is no longer used, so remove the file that was added here * misc cleanups * rename the method in database/migrations/2022_07_03_1947_add_app_data.php * hopefully fix the migration bit * add the column to misc/db_schema.yaml * more misc small DB fixes * update the test as the json column uses collat of utf8mb4_bin * revert the last change and try manually setting it to what is expected * remove a extra ; * update suricata as well * correct the instance -> instances in one location to prevent the old instance list from being stomped * remove a extra ; * update fail2ban to use it as well * remove two unused functions as suricata and fail2ban no longer use components * style cleanup * postgres poller updated to use it * update html side of the postgres bits * chronyd now uses app data bits now as well * portactivity now uses it as well * style fix * sort the returned arrays from app_data * correct log message for port activity * collocation change * try re-ordering it * add in the new data column to the tests * remove a extra , * hmm... ->collate('utf8mb4_unicode_ci') is not usable as apparently collate does not exist * change the column type from json to longtext * mv chronyd stuff while I sort out the rest of the tests... damn thing is always buggy * hmm... fix a missing line then likely move stuff back * style fix * add fillable * add the expexcted data for fail2ban json * escape a " I missed * add data for portactivity * add suricata app data * add app data to zfs legacy test * put the moved tests back into place and update zfs-v1 test * add app data for chronyd test * add app data for fail2ban legacy test * update zfs v1 app data * add some notes on application dev work * add Developing/Application-Notes.md to mkdocs.yml * add data column to it * added various suggestions from bennet-esyoil * convert from isset to sizeof * type fix * fully remove the old save app data function and move it into a helper function... the other still needs cleaned up prior to removal * update docs * get_app_data is fully removed now as well * a few style fixes * add $casts * update chronyd test * attempt to fix the data * more doc cleanup and try changing the cast * style fix * revert the changes to the chronyd test * apply a few of murrant's suggestions * document working with ->data as json and non-josn * remove two no-longer used in this PR exceptions * ->data now operates transparently * style fix * update data tests * fix json * test fix * update the app notes to reflect how app data now works * app test fix * app data fix for linux_lsi * json fix * minor doc cleanup * remove duplicate querty and use json_decode instead * style fix * modelize the app poller * use a anon func instead of foreach * test update * style cleanup * style cleanup * another test cleanup * more test cleanup * reverse the test changes and add in some more glue code * revert one of the test changes * another small test fix * Make things use models Left some array access, but those will still work just fine. * missed chronyd and portactivity * rename poll to avoid make it any confusion * Remove extra save and fix timestamp * save any changes made to app->data * nope, that was not it * What are magic methods and how do they work? * fix two typos * update linux_lsi test * change quote type Co-authored-by: Tony Murray <murraytony@gmail.com>
2022-07-22 16:01:55 -05:00
if (! $app) {
d_echo('$app does not exist, could not update');
2020-09-21 15:43:38 +02:00
return;
}
add the ability for storing app data to prevent spamming of the event log via via component usage (#14087) * initial work on add the ability to save/fetch app data * update to use get_app_data for ZFS * update the poller for the new app_data stuff * ZFS now logs changes to pools * add schema update for app_data stuff * small formatting fix * add a missing \ * now adds a column * sql-schema is no longer used, so remove the file that was added here * misc cleanups * rename the method in database/migrations/2022_07_03_1947_add_app_data.php * hopefully fix the migration bit * add the column to misc/db_schema.yaml * more misc small DB fixes * update the test as the json column uses collat of utf8mb4_bin * revert the last change and try manually setting it to what is expected * remove a extra ; * update suricata as well * correct the instance -> instances in one location to prevent the old instance list from being stomped * remove a extra ; * update fail2ban to use it as well * remove two unused functions as suricata and fail2ban no longer use components * style cleanup * postgres poller updated to use it * update html side of the postgres bits * chronyd now uses app data bits now as well * portactivity now uses it as well * style fix * sort the returned arrays from app_data * correct log message for port activity * collocation change * try re-ordering it * add in the new data column to the tests * remove a extra , * hmm... ->collate('utf8mb4_unicode_ci') is not usable as apparently collate does not exist * change the column type from json to longtext * mv chronyd stuff while I sort out the rest of the tests... damn thing is always buggy * hmm... fix a missing line then likely move stuff back * style fix * add fillable * add the expexcted data for fail2ban json * escape a " I missed * add data for portactivity * add suricata app data * add app data to zfs legacy test * put the moved tests back into place and update zfs-v1 test * add app data for chronyd test * add app data for fail2ban legacy test * update zfs v1 app data * add some notes on application dev work * add Developing/Application-Notes.md to mkdocs.yml * add data column to it * added various suggestions from bennet-esyoil * convert from isset to sizeof * type fix * fully remove the old save app data function and move it into a helper function... the other still needs cleaned up prior to removal * update docs * get_app_data is fully removed now as well * a few style fixes * add $casts * update chronyd test * attempt to fix the data * more doc cleanup and try changing the cast * style fix * revert the changes to the chronyd test * apply a few of murrant's suggestions * document working with ->data as json and non-josn * remove two no-longer used in this PR exceptions * ->data now operates transparently * style fix * update data tests * fix json * test fix * update the app notes to reflect how app data now works * app test fix * app data fix for linux_lsi * json fix * minor doc cleanup * remove duplicate querty and use json_decode instead * style fix * modelize the app poller * use a anon func instead of foreach * test update * style cleanup * style cleanup * another test cleanup * more test cleanup * reverse the test changes and add in some more glue code * revert one of the test changes * another small test fix * Make things use models Left some array access, but those will still work just fine. * missed chronyd and portactivity * rename poll to avoid make it any confusion * Remove extra save and fix timestamp * save any changes made to app->data * nope, that was not it * What are magic methods and how do they work? * fix two typos * update linux_lsi test * change quote type Co-authored-by: Tony Murray <murraytony@gmail.com>
2022-07-22 16:01:55 -05:00
$app->app_state = 'UNKNOWN';
$app->app_status = $status;
$app->timestamp = DB::raw('NOW()');
if ($response != '' && $response !== false) {
// if the response indicates an error, set it and set app_status to the raw response
if (Str::contains($response, [
'Traceback (most recent call last):',
])) {
add the ability for storing app data to prevent spamming of the event log via via component usage (#14087) * initial work on add the ability to save/fetch app data * update to use get_app_data for ZFS * update the poller for the new app_data stuff * ZFS now logs changes to pools * add schema update for app_data stuff * small formatting fix * add a missing \ * now adds a column * sql-schema is no longer used, so remove the file that was added here * misc cleanups * rename the method in database/migrations/2022_07_03_1947_add_app_data.php * hopefully fix the migration bit * add the column to misc/db_schema.yaml * more misc small DB fixes * update the test as the json column uses collat of utf8mb4_bin * revert the last change and try manually setting it to what is expected * remove a extra ; * update suricata as well * correct the instance -> instances in one location to prevent the old instance list from being stomped * remove a extra ; * update fail2ban to use it as well * remove two unused functions as suricata and fail2ban no longer use components * style cleanup * postgres poller updated to use it * update html side of the postgres bits * chronyd now uses app data bits now as well * portactivity now uses it as well * style fix * sort the returned arrays from app_data * correct log message for port activity * collocation change * try re-ordering it * add in the new data column to the tests * remove a extra , * hmm... ->collate('utf8mb4_unicode_ci') is not usable as apparently collate does not exist * change the column type from json to longtext * mv chronyd stuff while I sort out the rest of the tests... damn thing is always buggy * hmm... fix a missing line then likely move stuff back * style fix * add fillable * add the expexcted data for fail2ban json * escape a " I missed * add data for portactivity * add suricata app data * add app data to zfs legacy test * put the moved tests back into place and update zfs-v1 test * add app data for chronyd test * add app data for fail2ban legacy test * update zfs v1 app data * add some notes on application dev work * add Developing/Application-Notes.md to mkdocs.yml * add data column to it * added various suggestions from bennet-esyoil * convert from isset to sizeof * type fix * fully remove the old save app data function and move it into a helper function... the other still needs cleaned up prior to removal * update docs * get_app_data is fully removed now as well * a few style fixes * add $casts * update chronyd test * attempt to fix the data * more doc cleanup and try changing the cast * style fix * revert the changes to the chronyd test * apply a few of murrant's suggestions * document working with ->data as json and non-josn * remove two no-longer used in this PR exceptions * ->data now operates transparently * style fix * update data tests * fix json * test fix * update the app notes to reflect how app data now works * app test fix * app data fix for linux_lsi * json fix * minor doc cleanup * remove duplicate querty and use json_decode instead * style fix * modelize the app poller * use a anon func instead of foreach * test update * style cleanup * style cleanup * another test cleanup * more test cleanup * reverse the test changes and add in some more glue code * revert one of the test changes * another small test fix * Make things use models Left some array access, but those will still work just fine. * missed chronyd and portactivity * rename poll to avoid make it any confusion * Remove extra save and fix timestamp * save any changes made to app->data * nope, that was not it * What are magic methods and how do they work? * fix two typos * update linux_lsi test * change quote type Co-authored-by: Tony Murray <murraytony@gmail.com>
2022-07-22 16:01:55 -05:00
$app->app_state = 'ERROR';
$app->app_status = $response;
} elseif (preg_match('/^(ERROR|LEGACY|UNSUPPORTED)/', $response, $matches)) {
add the ability for storing app data to prevent spamming of the event log via via component usage (#14087) * initial work on add the ability to save/fetch app data * update to use get_app_data for ZFS * update the poller for the new app_data stuff * ZFS now logs changes to pools * add schema update for app_data stuff * small formatting fix * add a missing \ * now adds a column * sql-schema is no longer used, so remove the file that was added here * misc cleanups * rename the method in database/migrations/2022_07_03_1947_add_app_data.php * hopefully fix the migration bit * add the column to misc/db_schema.yaml * more misc small DB fixes * update the test as the json column uses collat of utf8mb4_bin * revert the last change and try manually setting it to what is expected * remove a extra ; * update suricata as well * correct the instance -> instances in one location to prevent the old instance list from being stomped * remove a extra ; * update fail2ban to use it as well * remove two unused functions as suricata and fail2ban no longer use components * style cleanup * postgres poller updated to use it * update html side of the postgres bits * chronyd now uses app data bits now as well * portactivity now uses it as well * style fix * sort the returned arrays from app_data * correct log message for port activity * collocation change * try re-ordering it * add in the new data column to the tests * remove a extra , * hmm... ->collate('utf8mb4_unicode_ci') is not usable as apparently collate does not exist * change the column type from json to longtext * mv chronyd stuff while I sort out the rest of the tests... damn thing is always buggy * hmm... fix a missing line then likely move stuff back * style fix * add fillable * add the expexcted data for fail2ban json * escape a " I missed * add data for portactivity * add suricata app data * add app data to zfs legacy test * put the moved tests back into place and update zfs-v1 test * add app data for chronyd test * add app data for fail2ban legacy test * update zfs v1 app data * add some notes on application dev work * add Developing/Application-Notes.md to mkdocs.yml * add data column to it * added various suggestions from bennet-esyoil * convert from isset to sizeof * type fix * fully remove the old save app data function and move it into a helper function... the other still needs cleaned up prior to removal * update docs * get_app_data is fully removed now as well * a few style fixes * add $casts * update chronyd test * attempt to fix the data * more doc cleanup and try changing the cast * style fix * revert the changes to the chronyd test * apply a few of murrant's suggestions * document working with ->data as json and non-josn * remove two no-longer used in this PR exceptions * ->data now operates transparently * style fix * update data tests * fix json * test fix * update the app notes to reflect how app data now works * app test fix * app data fix for linux_lsi * json fix * minor doc cleanup * remove duplicate querty and use json_decode instead * style fix * modelize the app poller * use a anon func instead of foreach * test update * style cleanup * style cleanup * another test cleanup * more test cleanup * reverse the test changes and add in some more glue code * revert one of the test changes * another small test fix * Make things use models Left some array access, but those will still work just fine. * missed chronyd and portactivity * rename poll to avoid make it any confusion * Remove extra save and fix timestamp * save any changes made to app->data * nope, that was not it * What are magic methods and how do they work? * fix two typos * update linux_lsi test * change quote type Co-authored-by: Tony Murray <murraytony@gmail.com>
2022-07-22 16:01:55 -05:00
$app->app_state = $matches[1];
$app->app_status = $response;
} else {
2020-05-20 02:21:02 +02:00
// should maybe be 'unknown' as state
add the ability for storing app data to prevent spamming of the event log via via component usage (#14087) * initial work on add the ability to save/fetch app data * update to use get_app_data for ZFS * update the poller for the new app_data stuff * ZFS now logs changes to pools * add schema update for app_data stuff * small formatting fix * add a missing \ * now adds a column * sql-schema is no longer used, so remove the file that was added here * misc cleanups * rename the method in database/migrations/2022_07_03_1947_add_app_data.php * hopefully fix the migration bit * add the column to misc/db_schema.yaml * more misc small DB fixes * update the test as the json column uses collat of utf8mb4_bin * revert the last change and try manually setting it to what is expected * remove a extra ; * update suricata as well * correct the instance -> instances in one location to prevent the old instance list from being stomped * remove a extra ; * update fail2ban to use it as well * remove two unused functions as suricata and fail2ban no longer use components * style cleanup * postgres poller updated to use it * update html side of the postgres bits * chronyd now uses app data bits now as well * portactivity now uses it as well * style fix * sort the returned arrays from app_data * correct log message for port activity * collocation change * try re-ordering it * add in the new data column to the tests * remove a extra , * hmm... ->collate('utf8mb4_unicode_ci') is not usable as apparently collate does not exist * change the column type from json to longtext * mv chronyd stuff while I sort out the rest of the tests... damn thing is always buggy * hmm... fix a missing line then likely move stuff back * style fix * add fillable * add the expexcted data for fail2ban json * escape a " I missed * add data for portactivity * add suricata app data * add app data to zfs legacy test * put the moved tests back into place and update zfs-v1 test * add app data for chronyd test * add app data for fail2ban legacy test * update zfs v1 app data * add some notes on application dev work * add Developing/Application-Notes.md to mkdocs.yml * add data column to it * added various suggestions from bennet-esyoil * convert from isset to sizeof * type fix * fully remove the old save app data function and move it into a helper function... the other still needs cleaned up prior to removal * update docs * get_app_data is fully removed now as well * a few style fixes * add $casts * update chronyd test * attempt to fix the data * more doc cleanup and try changing the cast * style fix * revert the changes to the chronyd test * apply a few of murrant's suggestions * document working with ->data as json and non-josn * remove two no-longer used in this PR exceptions * ->data now operates transparently * style fix * update data tests * fix json * test fix * update the app notes to reflect how app data now works * app test fix * app data fix for linux_lsi * json fix * minor doc cleanup * remove duplicate querty and use json_decode instead * style fix * modelize the app poller * use a anon func instead of foreach * test update * style cleanup * style cleanup * another test cleanup * more test cleanup * reverse the test changes and add in some more glue code * revert one of the test changes * another small test fix * Make things use models Left some array access, but those will still work just fine. * missed chronyd and portactivity * rename poll to avoid make it any confusion * Remove extra save and fix timestamp * save any changes made to app->data * nope, that was not it * What are magic methods and how do they work? * fix two typos * update linux_lsi test * change quote type Co-authored-by: Tony Murray <murraytony@gmail.com>
2022-07-22 16:01:55 -05:00
$app->app_state = 'OK';
}
}
add the ability for storing app data to prevent spamming of the event log via via component usage (#14087) * initial work on add the ability to save/fetch app data * update to use get_app_data for ZFS * update the poller for the new app_data stuff * ZFS now logs changes to pools * add schema update for app_data stuff * small formatting fix * add a missing \ * now adds a column * sql-schema is no longer used, so remove the file that was added here * misc cleanups * rename the method in database/migrations/2022_07_03_1947_add_app_data.php * hopefully fix the migration bit * add the column to misc/db_schema.yaml * more misc small DB fixes * update the test as the json column uses collat of utf8mb4_bin * revert the last change and try manually setting it to what is expected * remove a extra ; * update suricata as well * correct the instance -> instances in one location to prevent the old instance list from being stomped * remove a extra ; * update fail2ban to use it as well * remove two unused functions as suricata and fail2ban no longer use components * style cleanup * postgres poller updated to use it * update html side of the postgres bits * chronyd now uses app data bits now as well * portactivity now uses it as well * style fix * sort the returned arrays from app_data * correct log message for port activity * collocation change * try re-ordering it * add in the new data column to the tests * remove a extra , * hmm... ->collate('utf8mb4_unicode_ci') is not usable as apparently collate does not exist * change the column type from json to longtext * mv chronyd stuff while I sort out the rest of the tests... damn thing is always buggy * hmm... fix a missing line then likely move stuff back * style fix * add fillable * add the expexcted data for fail2ban json * escape a " I missed * add data for portactivity * add suricata app data * add app data to zfs legacy test * put the moved tests back into place and update zfs-v1 test * add app data for chronyd test * add app data for fail2ban legacy test * update zfs v1 app data * add some notes on application dev work * add Developing/Application-Notes.md to mkdocs.yml * add data column to it * added various suggestions from bennet-esyoil * convert from isset to sizeof * type fix * fully remove the old save app data function and move it into a helper function... the other still needs cleaned up prior to removal * update docs * get_app_data is fully removed now as well * a few style fixes * add $casts * update chronyd test * attempt to fix the data * more doc cleanup and try changing the cast * style fix * revert the changes to the chronyd test * apply a few of murrant's suggestions * document working with ->data as json and non-josn * remove two no-longer used in this PR exceptions * ->data now operates transparently * style fix * update data tests * fix json * test fix * update the app notes to reflect how app data now works * app test fix * app data fix for linux_lsi * json fix * minor doc cleanup * remove duplicate querty and use json_decode instead * style fix * modelize the app poller * use a anon func instead of foreach * test update * style cleanup * style cleanup * another test cleanup * more test cleanup * reverse the test changes and add in some more glue code * revert one of the test changes * another small test fix * Make things use models Left some array access, but those will still work just fine. * missed chronyd and portactivity * rename poll to avoid make it any confusion * Remove extra save and fix timestamp * save any changes made to app->data * nope, that was not it * What are magic methods and how do they work? * fix two typos * update linux_lsi test * change quote type Co-authored-by: Tony Murray <murraytony@gmail.com>
2022-07-22 16:01:55 -05:00
if ($app->isDirty('app_state')) {
$app->app_state_prev = $app->getOriginal('app_state');
2020-05-20 02:21:02 +02:00
add the ability for storing app data to prevent spamming of the event log via via component usage (#14087) * initial work on add the ability to save/fetch app data * update to use get_app_data for ZFS * update the poller for the new app_data stuff * ZFS now logs changes to pools * add schema update for app_data stuff * small formatting fix * add a missing \ * now adds a column * sql-schema is no longer used, so remove the file that was added here * misc cleanups * rename the method in database/migrations/2022_07_03_1947_add_app_data.php * hopefully fix the migration bit * add the column to misc/db_schema.yaml * more misc small DB fixes * update the test as the json column uses collat of utf8mb4_bin * revert the last change and try manually setting it to what is expected * remove a extra ; * update suricata as well * correct the instance -> instances in one location to prevent the old instance list from being stomped * remove a extra ; * update fail2ban to use it as well * remove two unused functions as suricata and fail2ban no longer use components * style cleanup * postgres poller updated to use it * update html side of the postgres bits * chronyd now uses app data bits now as well * portactivity now uses it as well * style fix * sort the returned arrays from app_data * correct log message for port activity * collocation change * try re-ordering it * add in the new data column to the tests * remove a extra , * hmm... ->collate('utf8mb4_unicode_ci') is not usable as apparently collate does not exist * change the column type from json to longtext * mv chronyd stuff while I sort out the rest of the tests... damn thing is always buggy * hmm... fix a missing line then likely move stuff back * style fix * add fillable * add the expexcted data for fail2ban json * escape a " I missed * add data for portactivity * add suricata app data * add app data to zfs legacy test * put the moved tests back into place and update zfs-v1 test * add app data for chronyd test * add app data for fail2ban legacy test * update zfs v1 app data * add some notes on application dev work * add Developing/Application-Notes.md to mkdocs.yml * add data column to it * added various suggestions from bennet-esyoil * convert from isset to sizeof * type fix * fully remove the old save app data function and move it into a helper function... the other still needs cleaned up prior to removal * update docs * get_app_data is fully removed now as well * a few style fixes * add $casts * update chronyd test * attempt to fix the data * more doc cleanup and try changing the cast * style fix * revert the changes to the chronyd test * apply a few of murrant's suggestions * document working with ->data as json and non-josn * remove two no-longer used in this PR exceptions * ->data now operates transparently * style fix * update data tests * fix json * test fix * update the app notes to reflect how app data now works * app test fix * app data fix for linux_lsi * json fix * minor doc cleanup * remove duplicate querty and use json_decode instead * style fix * modelize the app poller * use a anon func instead of foreach * test update * style cleanup * style cleanup * another test cleanup * more test cleanup * reverse the test changes and add in some more glue code * revert one of the test changes * another small test fix * Make things use models Left some array access, but those will still work just fine. * missed chronyd and portactivity * rename poll to avoid make it any confusion * Remove extra save and fix timestamp * save any changes made to app->data * nope, that was not it * What are magic methods and how do they work? * fix two typos * update linux_lsi test * change quote type Co-authored-by: Tony Murray <murraytony@gmail.com>
2022-07-22 16:01:55 -05:00
switch ($app->app_state) {
2020-05-20 02:21:02 +02:00
case 'OK':
$severity = Severity::Ok;
2020-05-20 02:21:02 +02:00
$event_msg = 'changed to OK';
break;
case 'ERROR':
$severity = Severity::Error;
2020-05-20 02:21:02 +02:00
$event_msg = 'ends with ERROR';
break;
case 'LEGACY':
$severity = Severity::Warning;
2020-05-20 02:21:02 +02:00
$event_msg = 'Client Agent is deprecated';
break;
case 'UNSUPPORTED':
$severity = Severity::Error;
2020-05-20 02:21:02 +02:00
$event_msg = 'Client Agent Version is not supported';
break;
default:
$severity = Severity::Unknown;
2020-05-20 02:21:02 +02:00
$event_msg = 'has UNKNOWN state';
break;
}
\App\Models\Eventlog::log('Application ' . $app->displayName() . ' ' . $event_msg, DeviceCache::getPrimary(), 'application', $severity);
}
add the ability for storing app data to prevent spamming of the event log via via component usage (#14087) * initial work on add the ability to save/fetch app data * update to use get_app_data for ZFS * update the poller for the new app_data stuff * ZFS now logs changes to pools * add schema update for app_data stuff * small formatting fix * add a missing \ * now adds a column * sql-schema is no longer used, so remove the file that was added here * misc cleanups * rename the method in database/migrations/2022_07_03_1947_add_app_data.php * hopefully fix the migration bit * add the column to misc/db_schema.yaml * more misc small DB fixes * update the test as the json column uses collat of utf8mb4_bin * revert the last change and try manually setting it to what is expected * remove a extra ; * update suricata as well * correct the instance -> instances in one location to prevent the old instance list from being stomped * remove a extra ; * update fail2ban to use it as well * remove two unused functions as suricata and fail2ban no longer use components * style cleanup * postgres poller updated to use it * update html side of the postgres bits * chronyd now uses app data bits now as well * portactivity now uses it as well * style fix * sort the returned arrays from app_data * correct log message for port activity * collocation change * try re-ordering it * add in the new data column to the tests * remove a extra , * hmm... ->collate('utf8mb4_unicode_ci') is not usable as apparently collate does not exist * change the column type from json to longtext * mv chronyd stuff while I sort out the rest of the tests... damn thing is always buggy * hmm... fix a missing line then likely move stuff back * style fix * add fillable * add the expexcted data for fail2ban json * escape a " I missed * add data for portactivity * add suricata app data * add app data to zfs legacy test * put the moved tests back into place and update zfs-v1 test * add app data for chronyd test * add app data for fail2ban legacy test * update zfs v1 app data * add some notes on application dev work * add Developing/Application-Notes.md to mkdocs.yml * add data column to it * added various suggestions from bennet-esyoil * convert from isset to sizeof * type fix * fully remove the old save app data function and move it into a helper function... the other still needs cleaned up prior to removal * update docs * get_app_data is fully removed now as well * a few style fixes * add $casts * update chronyd test * attempt to fix the data * more doc cleanup and try changing the cast * style fix * revert the changes to the chronyd test * apply a few of murrant's suggestions * document working with ->data as json and non-josn * remove two no-longer used in this PR exceptions * ->data now operates transparently * style fix * update data tests * fix json * test fix * update the app notes to reflect how app data now works * app test fix * app data fix for linux_lsi * json fix * minor doc cleanup * remove duplicate querty and use json_decode instead * style fix * modelize the app poller * use a anon func instead of foreach * test update * style cleanup * style cleanup * another test cleanup * more test cleanup * reverse the test changes and add in some more glue code * revert one of the test changes * another small test fix * Make things use models Left some array access, but those will still work just fine. * missed chronyd and portactivity * rename poll to avoid make it any confusion * Remove extra save and fix timestamp * save any changes made to app->data * nope, that was not it * What are magic methods and how do they work? * fix two typos * update linux_lsi test * change quote type Co-authored-by: Tony Murray <murraytony@gmail.com>
2022-07-22 16:01:55 -05:00
$app->save();
// update metrics
if (! empty($metrics)) {
$db_metrics = dbFetchRows('SELECT * FROM `application_metrics` WHERE app_id=?', [$app['app_id']]);
$db_metrics = array_by_column($db_metrics, 'metric');
// allow two level metrics arrays, flatten them and prepend the group name
if (is_array(current($metrics))) {
$metrics = array_reduce(
array_keys($metrics),
function ($carry, $metric_group) use ($metrics) {
if ($metric_group == 'none') {
$prefix = '';
} else {
$prefix = $metric_group . '_';
}
foreach ($metrics[$metric_group] as $metric_name => $value) {
$carry[$prefix . $metric_name] = $value;
}
2020-09-21 15:43:38 +02:00
return $carry;
},
2020-09-21 15:43:38 +02:00
[]
);
}
echo ': ';
foreach ($metrics as $metric_name => $value) {
$value = (float) $value; // cast
if (! isset($db_metrics[$metric_name])) {
// insert new metric
dbInsert(
2020-09-21 15:43:38 +02:00
[
'app_id' => $app['app_id'],
'metric' => $metric_name,
'value' => $value,
],
'application_metrics'
);
echo '+';
} elseif ($value != $db_metrics[$metric_name]['value']) {
dbUpdate(
2020-09-21 15:43:38 +02:00
[
'value' => $value,
'value_prev' => $db_metrics[$metric_name]['value'],
],
'application_metrics',
'app_id=? && metric=?',
[$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=?',
[$app['app_id'], $db_metric['metric']]
);
echo '-';
}
echo PHP_EOL;
}
}
/**
* This is to make it easier polling apps. Also to help standardize around JSON.
*
* If the data has is in base64, it will be converted and then gunzipped.
* https://github.com/librenms/librenms-agent/blob/master/utils/lnms_return_optimizer
* May be used to convert output from extends to that via piping it through it.
*
* The required keys for the returned JSON are as below.
* version - The version of the snmp extend script. Should be numeric and at least 1.
* error - Error code from the snmp extend script. Should be > 0 (0 will be ignored and negatives are reserved)
* errorString - Text to describe the error.
* data - An key with an array with the data to be used.
*
* If the app returns an error, an exception will be raised.
* Positive numbers will be errors returned by the extend script.
*
* Possible parsing related errors:
* -2 : Failed to fetch data from the device
* -3 : Could not decode the JSON.
* -4 : Empty JSON parsed, meaning blank JSON was returned.
* -5 : Valid json, but missing required keys
* -6 : Returned version is less than the min version.
* -7 : Base64 decode failure.
* -8 : Gzip decode failure.
*
* Error checking may also be done via checking the exceptions listed below.
* JsonAppPollingFailedException, -2 : Empty return from SNMP.
* JsonAppParsingFailedException, -3 : Could not parse the JSON.
* JsonAppBlankJsonException, -4 : Blank JSON.
* JsonAppMissingKeysException, -5 : Missing required keys.
* JsonAppWrongVersionException , -6 : Older version than supported.
* JsonAppExtendErroredException : Polling and parsing was good, but the returned data has an error set.
* This may be checked via $e->getParsedJson() and then checking the
* keys error and errorString.
* JsonAppPollingBase64DecodeException , -7 : Base64 decoding failed.
* JsonAppPollingGzipDecodeException , -8 : Gzip decoding failed.
* The error value can be accessed via $e->getCode()
* The output can be accessed via $->getOutput() Only returned for code -3 or lower.
* The parsed JSON can be access via $e->getParsedJson()
*
* All of the exceptions extend JsonAppException.
*
* If the error is less than -1, you can assume it is a legacy snmp extend script.
*
2021-09-08 23:35:56 +02:00
* @param array $device
* @param string $extend the extend name. For example, if 'zfs' is passed it will be converted to 'nsExtendOutputFull.3.122.102.115'.
* @param int $min_version the minimum version to accept for the returned JSON. default: 1
* @return array The json output data parsed into an array
2021-09-10 20:09:53 +02:00
*
* @throws JsonAppBlankJsonException
* @throws JsonAppExtendErroredException
* @throws JsonAppMissingKeysException
* @throws JsonAppParsingFailedException
* @throws JsonAppPollingFailedException
* @throws JsonAppWrongVersionException
*/
function json_app_get($device, $extend, $min_version = 1)
{
$output = snmp_get($device, 'nsExtendOutputFull.' . \LibreNMS\Util\Oid::ofString($extend), '-Oqv', 'NET-SNMP-EXTEND-MIB');
// save for returning if not JSON
$orig_output = $output;
// make sure we actually get something back
if (empty($output)) {
throw new JsonAppPollingFailedException('Empty return from snmp_get.', -2);
}
// checks for base64 decoding and converts it to non-base64 so it can gunzip
if (preg_match('/^[A-Za-z0-9\/\+\n]+\=*\n*$/', $output) && ! preg_match('/^[0-9]+\n/', $output)) {
$output = base64_decode($output);
if (! $output) {
if (Debug::isEnabled()) {
echo "Decoding Base64 Failed...\n\n";
}
throw new JsonAppBase64DecodeException('Base64 decode failed.', $orig_output, -7);
}
$output = gzdecode($output);
if (! $output) {
if (Debug::isEnabled()) {
echo "Decoding GZip failed...\n\n";
}
throw new JsonAppGzipDecodeException('Gzip decode failed.', $orig_output, -8);
}
if (Debug::isVerbose()) {
echo 'Decoded Base64+GZip Output: ' . $output . "\n\n";
}
}
// turn the JSON into a array
$parsed_json = json_decode(stripslashes($output), true);
// improper JSON or something else was returned. Populate the variable with an error.
if (json_last_error() !== JSON_ERROR_NONE) {
throw new JsonAppParsingFailedException('Invalid JSON', $orig_output, -3);
}
// There no keys in the array, meaning '{}' was was returned
if (empty($parsed_json)) {
throw new JsonAppBlankJsonException('Blank JSON returned.', $output, -4);
}
// It is a legacy JSON app extend, meaning these are not set
if (! isset($parsed_json['error'], $parsed_json['data'], $parsed_json['errorString'], $parsed_json['version'])) {
throw new JsonAppMissingKeysException('Legacy script or extend error, missing one or more required keys.', $output, $parsed_json, -5);
}
if ($parsed_json['version'] < $min_version) {
throw new JsonAppWrongVersionException("Script,'" . $parsed_json['version'] . "', older than required version of '$min_version'", $output, $parsed_json, -6);
}
if ($parsed_json['error'] != 0) {
throw new JsonAppExtendErroredException("Script returned exception: {$parsed_json['errorString']}", $output, $parsed_json, $parsed_json['error']);
}
return $parsed_json;
}
add app for getting status of TCP connections for specified services (#8090) * add the poller for portactivity * add the ability to get monitor ports for portactivity * add the graphs for displaying stuff for the portactivity app * add the portactivity app page * update the docs for Portactivity * remove extra line * minor doc update for Portactivity * add update_application line * convert to use json_app_get * convert curly brackets to square * style fix * remote error, errorString, and version after they stop being important so they are not processed * add alert rule examples * add the poller for portactivity * add the ability to get monitor ports for portactivity * add the graphs for displaying stuff for the portactivity app * add the portactivity app page * update the docs for Portactivity * remove extra line * minor doc update for Portactivity * add update_application line * convert to use json_app_get * convert curly brackets to square * style fix * remote error, errorString, and version after they stop being important so they are not processed * add alert rule examples * remove dump of get_portactivity_ports function added during rebase * update to the current json_app_get * add portactivity snmprec * add the portactivity test data * whoops bad merge when rebasing... fix * minor formatting cleanup and add a missing comma * fix some odditities with what one of the tests is doing * whoops... include the use for the exception * set the response to okay * attempt to make snmpsim array check happy again * the json now lints * more making metric testing happy * one more update to make travis-ci happy * now flattens arrays also add array_flatten * rename array_flatten to data_flatten as pre-commit chokes on it as laravel has something similarly named * go through and properly add all the metrics * tested with the newest one and it works * whoops, clean up json and remove prototype that was used when putting it together * doh! make it happy with laravel now * see if a minor changing in formatting for the numbers makes the polling unit test happy * order them properly * remove a comma * a few more minor fixes
2018-11-22 09:05:38 -06:00
/**
* Some data arrays returned with json_app_get are deeper than
* update_application likes. This recurses through the array
* and flattens it out so it can nicely be inserted into the
* database.
*
* One argument is taken and that is the array to flatten.
*
2021-09-08 23:35:56 +02:00
* @param array $array
* @param string $prefix What to prefix to the name. Defaults to '', nothing.
* @param string $joiner The string to join the prefix, if set to something other
* than '', and array keys with.
add app for getting status of TCP connections for specified services (#8090) * add the poller for portactivity * add the ability to get monitor ports for portactivity * add the graphs for displaying stuff for the portactivity app * add the portactivity app page * update the docs for Portactivity * remove extra line * minor doc update for Portactivity * add update_application line * convert to use json_app_get * convert curly brackets to square * style fix * remote error, errorString, and version after they stop being important so they are not processed * add alert rule examples * add the poller for portactivity * add the ability to get monitor ports for portactivity * add the graphs for displaying stuff for the portactivity app * add the portactivity app page * update the docs for Portactivity * remove extra line * minor doc update for Portactivity * add update_application line * convert to use json_app_get * convert curly brackets to square * style fix * remote error, errorString, and version after they stop being important so they are not processed * add alert rule examples * remove dump of get_portactivity_ports function added during rebase * update to the current json_app_get * add portactivity snmprec * add the portactivity test data * whoops bad merge when rebasing... fix * minor formatting cleanup and add a missing comma * fix some odditities with what one of the tests is doing * whoops... include the use for the exception * set the response to okay * attempt to make snmpsim array check happy again * the json now lints * more making metric testing happy * one more update to make travis-ci happy * now flattens arrays also add array_flatten * rename array_flatten to data_flatten as pre-commit chokes on it as laravel has something similarly named * go through and properly add all the metrics * tested with the newest one and it works * whoops, clean up json and remove prototype that was used when putting it together * doh! make it happy with laravel now * see if a minor changing in formatting for the numbers makes the polling unit test happy * order them properly * remove a comma * a few more minor fixes
2018-11-22 09:05:38 -06:00
* @return array The flattened array.
*/
function data_flatten($array, $prefix = '', $joiner = '_')
{
$return = [];
foreach ($array as $key => $value) {
if (is_array($value)) {
if (strcmp($prefix, '')) {
$key = $prefix . $joiner . $key;
}
$return = array_merge($return, data_flatten($value, $key, $joiner));
} else {
if (strcmp($prefix, '')) {
$key = $prefix . $joiner . $key;
}
$return[$key] = $value;
}
}
return $return;
}