Skip to content

Commit

Permalink
Deprecate poller.php
Browse files Browse the repository at this point in the history
  • Loading branch information
murrant committed Oct 4, 2023
1 parent 723c51b commit bda5fd5
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 333 deletions.
220 changes: 0 additions & 220 deletions includes/polling/functions.inc.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
<?php

use App\Models\DeviceGraph;
use Illuminate\Support\Str;
use LibreNMS\Config;
use LibreNMS\Enum\Severity;
use LibreNMS\Exceptions\JsonAppBase64DecodeException;
use LibreNMS\Exceptions\JsonAppBlankJsonException;
Expand Down Expand Up @@ -242,224 +240,6 @@ function record_sensor_data($device, $all_sensors)
}
}

/**
* @param array $device The device to poll
* @param bool $force_module Ignore device module overrides
* @return bool
*/
function poll_device($device, $force_module = false)
{
global $device, $graphs;

$device_start = microtime(true);

$deviceModel = DeviceCache::getPrimary();
$device['attribs'] = $deviceModel->getAttribs();

$os = \LibreNMS\OS::make($device);

unset($array);

// Start counting device poll time
echo 'Hostname: ' . $device['hostname'] . PHP_EOL;
echo 'Device ID: ' . $device['device_id'] . PHP_EOL;
echo 'OS: ' . $device['os'] . PHP_EOL;

if (empty($device['overwrite_ip'])) {
$ip = dnslookup($device);
} else {
$ip = $device['overwrite_ip'];
}

$db_ip = null;
if (! empty($ip)) {
if (empty($device['overwrite_ip'])) {
echo 'Resolved IP: ' . $ip . PHP_EOL;
} else {
echo 'Assigned IP: ' . $ip . PHP_EOL;
}
$db_ip = inet_pton($ip);
}

if (! empty($db_ip) && inet6_ntop($db_ip) != inet6_ntop($device['ip'])) {
log_event('Device IP changed to ' . $ip, $device, 'system', 3);
dbUpdate(['ip' => $db_ip], 'devices', 'device_id=?', [$device['device_id']]);
}

if ($os_group = Config::get("os.{$device['os']}.group")) {
$device['os_group'] = $os_group;
echo ' (' . $device['os_group'] . ')';
}

echo PHP_EOL . PHP_EOL;

unset($poll_update);
unset($poll_update_query);
unset($poll_separator);
$poll_update_array = [];
$update_array = [];

$host_rrd = Rrd::name($device['hostname'], '', '');
if (Config::get('norrd') !== true && ! is_dir($host_rrd)) {
mkdir($host_rrd);
echo "Created directory : $host_rrd\n";
}

$helper = new \LibreNMS\Polling\ConnectivityHelper($deviceModel);
$helper->saveMetrics();

if ($helper->isUp()) {
if ($device['snmp_disable']) {
// only non-snmp modules
Config::set('poller_modules', array_intersect_key(Config::get('poller_modules'), [
'availability' => true,
'ipmi' => true,
'unix-agent' => true,
]));
} else {
// we always want the core module to be included, prepend it
Config::set('poller_modules', ['core' => true] + Config::get('poller_modules'));
}

// update $device array status
$device['status'] = $deviceModel->status;
$device['status_reason'] = $deviceModel->status_reason;

/** @var \App\Polling\Measure\MeasurementManager $measurements */
$measurements = app(\App\Polling\Measure\MeasurementManager::class);
$measurements->checkpoint(); // don't count previous stats

foreach (Config::get('poller_modules') as $module => $module_status) {
if (! is_file("includes/polling/$module.inc.php")) {
echo "Module $module does not exist, please remove it from your configuration";

continue;
}

$os_module_status = Config::get("os.{$device['os']}.poller_modules.$module");
d_echo('Modules status: Global' . (isset($module_status) ? ($module_status ? '+ ' : '- ') : ' '));
d_echo('OS' . (isset($os_module_status) ? ($os_module_status ? '+ ' : '- ') : ' '));
d_echo('Device' . (isset($device['attribs']['poll_' . $module]) ? ($device['attribs']['poll_' . $module] ? '+ ' : '- ') : ' '));
if ($force_module === true ||
! empty($device['attribs']['poll_' . $module]) ||
($os_module_status && ! isset($device['attribs']['poll_' . $module])) ||
($module_status && ! isset($os_module_status) && ! isset($device['attribs']['poll_' . $module]))) {
$start_memory = memory_get_usage();
$module_start = microtime(true);
echo "\n#### Load poller module $module ####\n";

try {
include "includes/polling/$module.inc.php";
} catch (Throwable $e) {
// isolate module exceptions so they don't disrupt the polling process
Log::error("%rError polling $module module for {$device['hostname']}.%n $e", ['color' => true]);
\App\Models\Eventlog::log("Error polling $module module. Check log file for more details.", $device['device_id'], 'poller', Severity::Error);
report($e);

// Re-throw exception if we're in CI
if (getenv('CI') == true) {
throw $e;
}
}

$module_time = microtime(true) - $module_start;
$module_mem = (memory_get_usage() - $start_memory);
printf("\n>> Runtime for poller module '%s': %.4f seconds with %s bytes\n", $module, $module_time, $module_mem);
$measurements->printChangedStats();
echo "#### Unload poller module $module ####\n\n";

// save per-module poller stats
$tags = [
'module' => $module,
'rrd_def' => RrdDefinition::make()->addDataset('poller', 'GAUGE', 0),
'rrd_name' => ['poller-perf', $module],
];
$fields = [
'poller' => $module_time,
];
data_update($device, 'poller-perf', $tags, $fields);
$os->enableGraph('poller_perf');

// remove old rrd
$oldrrd = Rrd::name($device['hostname'], ['poller', $module, 'perf']);
if (is_file($oldrrd)) {
unlink($oldrrd);
}
unset($tags, $fields, $oldrrd);
} elseif (isset($device['attribs']['poll_' . $module]) && $device['attribs']['poll_' . $module] == '0') {
echo "Module [ $module ] disabled on host.\n\n";
} elseif (isset($os_module_status) && $os_module_status == '0') {
echo "Module [ $module ] disabled on os.\n\n";
} else {
echo "Module [ $module ] disabled globally.\n\n";
}
}

// Ping response
if ($helper->canPing()) {
$os->enableGraph('ping_perf');
}

$device_time = round(microtime(true) - $device_start, 3);

// Poller performance
if (! empty($device_time)) {
$tags = [
'rrd_def' => RrdDefinition::make()->addDataset('poller', 'GAUGE', 0),
'module' => 'ALL',
];
$fields = [
'poller' => $device_time,
];

data_update($device, 'poller-perf', $tags, $fields);
$os->enableGraph('poller_modules_perf');
}

if (! $force_module) {
// don't update last_polled time if we are forcing a specific module to be polled
$update_array['last_polled'] = ['NOW()'];
$update_array['last_polled_timetaken'] = $device_time;

echo 'Enabling graphs: ';
DeviceGraph::deleted(function ($graph) {
echo '-';
});
DeviceGraph::created(function ($graph) {
echo '+';
});

$os->persistGraphs();
echo PHP_EOL;
}

$updated = false;
if (! empty($update_array)) {
$updated = dbUpdate($update_array, 'devices', '`device_id` = ?', [$device['device_id']]);
}
if ($updated) {
d_echo('Updating ' . $device['hostname'] . PHP_EOL);
}

echo "\nPolled in $device_time seconds\n";

// check if the poll took to long and log an event
if ($device_time > Config::get('rrd.step')) {
log_event('Polling took longer than ' . round(Config::get('rrd.step') / 60, 2) .
' minutes! This will cause gaps in graphs.', $device, 'system', 5);
}

unset($storage_cache);
// Clear cache of hrStorage ** MAYBE FIXME? **
unset($cache);
// Clear cache (unify all things here?)

return true; // device was polled
}

return false; // device not polled
}//end poll_device()

/**
* Update the application status and output in the database.
*
Expand Down
131 changes: 18 additions & 113 deletions poller.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,143 +24,48 @@
* @author Heath Barnhart <[email protected]>
*/

use App\Action;
use App\Actions\Device\UpdateDeviceGroupsAction;
use LibreNMS\Alert\AlertRules;
use LibreNMS\Config;
use LibreNMS\Data\Store\Datastore;
use LibreNMS\Util\Debug;

$init_modules = ['polling', 'alerts', 'laravel'];
require __DIR__ . '/includes/init.php';

$poller_start = microtime(true);
Log::setDefaultDriver('console');
echo Config::get('project_name') . " Poller\n";

$options = getopt('h:m:i:n:r::d::v::a::f::q');

if (isset($options['h'])) {
if ($options['h'] == 'odd') {
$options['n'] = '1';
$options['i'] = '2';
} elseif ($options['h'] == 'even') {
$options['n'] = '0';
$options['i'] = '2';
} elseif ($options['h'] == 'all') {
$where = ' ';
$doing = 'all';
} elseif ($options['h']) {
if (is_numeric($options['h'])) {
$where = 'AND `device_id` = ' . $options['h'];
$doing = $options['h'];
} else {
if (preg_match('/\*/', $options['h'])) {
$where = "AND `hostname` LIKE '" . str_replace('*', '%', $options['h']) . "'";
} else {
$where = "AND `hostname` = '" . $options['h'] . "'";
}
$doing = $options['h'];
}
}
}
$options = getopt('h:rfpdvm:q');

if (isset($options['i']) && $options['i'] && isset($options['n'])) {
$where = true;
// FIXME
$query = 'SELECT * FROM (SELECT @rownum :=0) r,
(
SELECT @rownum := @rownum +1 AS rownum, `devices`.*
FROM `devices`
WHERE `disabled` = 0
ORDER BY `device_id` ASC
) temp
WHERE MOD(temp.rownum, ' . $options['i'] . ') = ' . $options['n'] . ';';
$doing = $options['n'] . '/' . $options['i'];
}
c_echo('%RWarning: poller.php is deprecated!%n Use %9lnms device:poll%n instead.' . PHP_EOL . PHP_EOL);

if (empty($where)) {
if (empty($options['h'])) {
echo "-h <device id> | <device hostname wildcard> Poll single device\n";
echo "-h odd Poll odd numbered devices (same as -i 2 -n 0)\n";
echo "-h even Poll even numbered devices (same as -i 2 -n 1)\n";
echo "-h odd Poll odd numbered devices\n";
echo "-h even Poll even numbered devices\n";
echo "-h all Poll all devices\n\n";
echo "-i <instances> -n <number> Poll as instance <number> of <instances>\n";
echo " Instances start at 0. 0-3 for -n 4\n\n";
echo "Debugging and testing options:\n";
echo "-r Do not create or update RRDs\n";
echo "-f Do not insert data into InfluxDB\n";
echo "-p Do not insert data into Prometheus\n";
echo "-d Enable debugging output\n";
echo "-v Enable verbose debugging output\n";
echo "-m Specify module(s) to be run. Comma separate modules, submodules may be added with /\n";
echo "-q Quiet, minimal output /\n";
echo "\n";
echo "No polling type specified!\n";
exit;
}

if (Debug::set(isset($options['d']), false) || isset($options['v'])) {
echo \LibreNMS\Util\Version::get()->header();

echo "DEBUG!\n";
if (isset($options['v'])) {
Debug::setVerbose();
}
\LibreNMS\Util\OS::updateCache(true); // Force update of OS Cache
}

// If we've specified modules with -m, use them
$module_override = parse_modules('poller', $options);
$arguments = [
'device spec' => $options['h'],
'--verbose' => isset($options['v']) ? 3 : (isset($options['d']) ? 2 : 1)
];

$datastore = Datastore::init($options);

echo "Starting polling run:\n\n";
$polled_devices = 0;
$unreachable_devices = 0;
if (! isset($query)) {
$query = "SELECT * FROM `devices` WHERE `disabled` = 0 $where ORDER BY `device_id` ASC";
if (isset($options['m'])) {
$arguments['--modules'] = $options['m'];
}

foreach (dbFetch($query) as $device) {
DeviceCache::setPrimary($device['device_id']);

if (! poll_device($device, $module_override)) {
$unreachable_devices++;
}

// Update device_groups
echo "### Start Device Groups ###\n";
$dg_start = microtime(true);
$group_changes = Action::execute(UpdateDeviceGroupsAction::class);
d_echo('Groups Added: ' . implode(',', $group_changes['attached']) . PHP_EOL);
d_echo('Groups Removed: ' . implode(',', $group_changes['detached']) . PHP_EOL);
echo '### End Device Groups, runtime: ' . round(microtime(true) - $dg_start, 4) . "s ### \n\n";

echo "#### Start Alerts ####\n";
$rules = new AlertRules();
$rules->runRules($device['device_id']);
echo "#### End Alerts ####\r\n";
$polled_devices++;
if (isset($options['q'])) {
$arguments['--quiet'] = true;
}

$poller_end = microtime(true);
$poller_run = ($poller_end - $poller_start);
$poller_time = substr($poller_run, 0, 5);

$string = $argv[0] . " $doing " . date(Config::get('dateformat.compact')) . " - $polled_devices devices polled in $poller_time secs";
d_echo("$string\n");

if (! isset($options['q'])) {
echo PHP_EOL;
app(\App\Polling\Measure\MeasurementManager::class)->printStats();
if (isset($options['r']) || isset($options['f']) || isset($options['p'])) {
$arguments['--no-data'] = true;
}

logfile($string);
Datastore::terminate();
// Remove this for testing
// print_r(get_defined_vars());

if ($polled_devices === $unreachable_devices) {
exit(6);
}
$return = Artisan::call('device:poll', $arguments);

exit(0);
exit($return);

0 comments on commit bda5fd5

Please sign in to comment.