From 0ec8f18459bb282389b0dffa02764f3da4eb466f Mon Sep 17 00:00:00 2001 From: Tony Murray Date: Fri, 26 Oct 2018 15:04:30 -0500 Subject: [PATCH] Graph of overall poller performance (#9381) * Graph definitions * Stacked. * Add display * remove old poll-log, add redirect * Handle undefined data in graphs * Standard pollers * Change doc to send to the global poller module page. * remove test code :) * Link parent menu --- LibreNMS/Validations/Poller.php | 4 +- app/Checks.php | 2 +- doc/Support/Performance.md | 3 +- .../graphs/global/poller_modules_perf.inc.php | 72 +++++++++++++++++++ .../graphs/global/poller_perf.inc.php | 50 +++++++++++++ html/includes/print-menubar.php | 7 +- html/pages/poll-log.inc.php | 44 ------------ html/pages/pollers.inc.php | 37 ++++++---- html/pages/pollers/groups.inc.php | 2 + html/pages/pollers/log.inc.php | 68 ++++++++++++++++++ html/pages/pollers/performance.inc.php | 37 ++++++++++ html/pages/pollers/pollers.inc.php | 26 +++++-- resources/views/layouts/menu.blade.php | 9 +-- routes/web.php | 5 ++ 14 files changed, 290 insertions(+), 76 deletions(-) create mode 100644 html/includes/graphs/global/poller_modules_perf.inc.php create mode 100644 html/includes/graphs/global/poller_perf.inc.php delete mode 100644 html/pages/poll-log.inc.php create mode 100644 html/pages/pollers/log.inc.php create mode 100644 html/pages/pollers/performance.inc.php diff --git a/LibreNMS/Validations/Poller.php b/LibreNMS/Validations/Poller.php index 0e61a6b66e..04e6242d74 100644 --- a/LibreNMS/Validations/Poller.php +++ b/LibreNMS/Validations/Poller.php @@ -116,7 +116,7 @@ class Poller extends BaseValidation $result->setFix('Check your poll log and see: http://docs.librenms.org/Support/Performance/'); } else { $base_url = $validator->getBaseURL(); - $result->setFix("Check $base_url/poll-log/ and see: http://docs.librenms.org/Support/Performance/"); + $result->setFix("Check $base_url/pollers/tab=log and see: http://docs.librenms.org/Support/Performance/"); } $validator->result($result); @@ -135,7 +135,7 @@ class Poller extends BaseValidation $result->setFix('Check your poll log and see: http://docs.librenms.org/Support/Performance/'); } else { $base_url = $validator->getBaseURL(); - $result->setFix("Check $base_url/poll-log/ and see: http://docs.librenms.org/Support/Performance/"); + $result->setFix("Check $base_url/pollers/tab=log/ and see: http://docs.librenms.org/Support/Performance/"); } $validator->result($result); diff --git a/app/Checks.php b/app/Checks.php index 0e08879d20..81c21049d8 100644 --- a/app/Checks.php +++ b/app/Checks.php @@ -83,7 +83,7 @@ class Checks } if (Device::isUp()->where('last_polled', '<=', Carbon::now()->subMinutes(15))->exists()) { - Toastr::warning('It appears as though you have some devices that haven\'t completed polling within the last 15 minutes, you may want to check that out :)', 'Devices unpolled'); + Toastr::warning('It appears as though you have some devices that haven\'t completed polling within the last 15 minutes, you may want to check that out :)', 'Devices unpolled'); } // Directory access checks diff --git a/doc/Support/Performance.md b/doc/Support/Performance.md index 0829732ed5..81aaff843f 100644 --- a/doc/Support/Performance.md +++ b/doc/Support/Performance.md @@ -27,7 +27,8 @@ MySQL crashes or your server does but it provides an amazing difference in IO us ### Polling modules -Review the graph of poller module time take under device > graphs > poller to see what modules are consuming poller time. +Review the graph of poller module time take under gear > pollers > performance to see what modules are consuming poller time. +This data is shown per device under device > graphs > poller. Disable polling (and discovery) modules that you do not need. You can do this globally in `config.php` like: diff --git a/html/includes/graphs/global/poller_modules_perf.inc.php b/html/includes/graphs/global/poller_modules_perf.inc.php new file mode 100644 index 0000000000..735d3c7cd7 --- /dev/null +++ b/html/includes/graphs/global/poller_modules_perf.inc.php @@ -0,0 +1,72 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2018 Tony Murray + * @author Tony Murray + */ + +use App\Models\Device; +use LibreNMS\Config; + +$scale_min = '0'; +$colors = Config::get('graph_colours.manycolours'); + +require 'includes/graphs/common.inc.php'; + +$hostnames = Device::pluck('hostname'); +$modules = array_keys(Config::get('poller_modules')); +sort($modules); + +foreach ($modules as $module_index => $module) { + $cdef = []; + $suffix = ''; + + foreach ($hostnames as $index => $hostname) { + $rrd_filename = rrd_name($hostname, ['poller-perf', $module]); + if (rrdtool_check_rrd_exists($rrd_filename)) { + $rrd_options .= " DEF:{$module}Raw$index=$rrd_filename:poller:AVERAGE"; + // change undefined to 0 + $rrd_options .= " CDEF:$module$index={$module}Raw$index,UN,0,{$module}Raw$index,IF"; + + $cdef[] = $module . $index . $suffix; + $suffix = ',+'; + } + } + + if (empty($cdef)) { + //remove the module so we don't print it in the legend + unset($modules[$module_index]); + } else { + // have data for this module, display it + $rrd_options .= " CDEF:$module=" . implode(',', $cdef); + } +} + +$rrd_options .= " 'COMMENT:Seconds Cur Min Max Avg\\n'"; + +foreach ($modules as $index => $module) { + $color = $colors[$index % count($colors)]; + + $rrd_options .= " AREA:$module#$color:'" . rrdtool_escape($module, 16) ."':STACK"; + + $rrd_options .= " GPRINT:$module:LAST:%6.2lf GPRINT:$module:MIN:%6.2lf"; + $rrd_options .= " GPRINT:$module:MAX:%6.2lf 'GPRINT:$module:AVERAGE:%6.2lf\\n'"; +} diff --git a/html/includes/graphs/global/poller_perf.inc.php b/html/includes/graphs/global/poller_perf.inc.php new file mode 100644 index 0000000000..bd26e207c2 --- /dev/null +++ b/html/includes/graphs/global/poller_perf.inc.php @@ -0,0 +1,50 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2018 Tony Murray + * @author Tony Murray + */ + +use App\Models\Device; + +$scale_min = '0'; + +require 'includes/graphs/common.inc.php'; + +$cdef = []; +$suffix = ''; + +foreach (Device::pluck('hostname') as $index => $hostname) { + $rrd_filename = rrd_name($hostname, 'poller-perf'); + if (rrdtool_check_rrd_exists($rrd_filename)) { + $rrd_options .= " DEF:pollerRaw$index=$rrd_filename:poller:AVERAGE"; + // change undefined to 0 + $rrd_options .= " CDEF:poller$index=pollerRaw$index,UN,0,pollerRaw$index,IF"; + $cdef[] = 'poller' . $index . $suffix; + $suffix = ',+'; + } +} + +$rrd_options .= " CDEF:poller=" . implode(',', $cdef); +$rrd_options .= " 'COMMENT:Seconds Cur Min Max Avg\\n'"; +$rrd_options .= ' LINE1.25:poller#36393D:Poller'; +$rrd_options .= ' GPRINT:poller:LAST:%6.2lf GPRINT:poller:MIN:%6.2lf'; +$rrd_options .= " GPRINT:poller:MAX:%6.2lf 'GPRINT:poller:AVERAGE:%6.2lf\\n'"; diff --git a/html/includes/print-menubar.php b/html/includes/print-menubar.php index c288cd4273..5931e06909 100644 --- a/html/includes/print-menubar.php +++ b/html/includes/print-menubar.php @@ -691,15 +691,16 @@ if (Auth::user()->hasGlobalAdmin()) { '); echo(' diff --git a/html/pages/poll-log.inc.php b/html/pages/poll-log.inc.php deleted file mode 100644 index 138aaf16b9..0000000000 --- a/html/pages/poll-log.inc.php +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - -
HostnameLast PolledPoller GroupPolling Duration (Seconds)
- - diff --git a/html/pages/pollers.inc.php b/html/pages/pollers.inc.php index 633f643d03..3be294ff4a 100644 --- a/html/pages/pollers.inc.php +++ b/html/pages/pollers.inc.php @@ -14,33 +14,42 @@ $no_refresh = true; + echo ''; -if (isset($vars['tab'])) { - include_once 'pages/pollers/'.mres($vars['tab']).'.inc.php'; -} +include_once 'pages/pollers/'.$current_tab.'.inc.php'; diff --git a/html/pages/pollers/groups.inc.php b/html/pages/pollers/groups.inc.php index a914650ae2..835d80a706 100644 --- a/html/pages/pollers/groups.inc.php +++ b/html/pages/pollers/groups.inc.php @@ -12,6 +12,8 @@ * the source code distribution for details. */ +$pagetitle[] = 'Poller Groups'; + require_once 'includes/modal/poller_groups.inc.php'; ?> diff --git a/html/pages/pollers/log.inc.php b/html/pages/pollers/log.inc.php new file mode 100644 index 0000000000..43080ceb47 --- /dev/null +++ b/html/pages/pollers/log.inc.php @@ -0,0 +1,68 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2018 Tony Murray + * @author Tony Murray + */ + +$no_refresh = true; +$pagetitle[] = 'Poll Log'; +if (isset($vars['filter'])) { + $type = $vars['filter']; +} +?> + + + + + + + + + +
HostnameLast PolledPoller GroupPolling Duration (Seconds)
+ + diff --git a/html/pages/pollers/performance.inc.php b/html/pages/pollers/performance.inc.php new file mode 100644 index 0000000000..7533c2c701 --- /dev/null +++ b/html/pages/pollers/performance.inc.php @@ -0,0 +1,37 @@ + +
+
+
+

Total Poller Time

+
+
+ 'global_poller_perf', + 'legend' => 'yes', + 'height' => 100, + ]; + require 'includes/print-graphrow.inc.php'; + ?> +
+
+
+
+

Total Poller Time Per Module

+
+
+ 'global_poller_modules_perf', + 'legend' => 'yes', + 'height' => 100, + ]; + require 'includes/print-graphrow.inc.php'; + ?> +
+
diff --git a/html/pages/pollers/pollers.inc.php b/html/pages/pollers/pollers.inc.php index bf05930dcf..740850b97b 100644 --- a/html/pages/pollers/pollers.inc.php +++ b/html/pages/pollers/pollers.inc.php @@ -14,6 +14,8 @@ use LibreNMS\Config; +$pagetitle[] = 'Pollers'; + require_once 'includes/modal/delete_poller.inc.php'; ?> @@ -25,8 +27,11 @@ $rows = dbFetchRows($query); if (count($rows) !== 0) { echo ' -

Standard Distributed Pollers

- +
+
+

Standard Pollers

+
+
@@ -68,7 +73,9 @@ if (count($rows) !== 0) { echo '
-
'; +
+
+'; } $query = 'SELECT *,UNIX_TIMESTAMP(NOW()) AS `now`, UNIX_TIMESTAMP(`last_report`) AS `then` FROM `poller_cluster` ORDER BY poller_name'; @@ -76,8 +83,11 @@ $rows = dbFetchRows($query); if (count($rows) !== 0) { echo ' -

Poller Cluster Health

- +
+
+

Poller Cluster Health

+
+
@@ -157,7 +167,9 @@ if (count($rows) !== 0) { Worker seconds indicates the maximum polling throughput a node can achieve in perfect conditions. If the consumed is close to the maximum, consider adding more threads, or better tuning your groups.
If there are devices pending but consumed worker seconds is low, your hardware is not sufficient for the number of devices and the poller cannot reach maximum throughput. -
- '; + + + +'; } ?> diff --git a/resources/views/layouts/menu.blade.php b/resources/views/layouts/menu.blade.php index fec8d19ab4..3a93d6a5f4 100644 --- a/resources/views/layouts/menu.blade.php +++ b/resources/views/layouts/menu.blade.php @@ -364,13 +364,14 @@
  • Auth History
  • diff --git a/routes/web.php b/routes/web.php index fc98a955cc..bd58bddfb2 100644 --- a/routes/web.php +++ b/routes/web.php @@ -21,6 +21,11 @@ Route::group(['middleware' => ['auth', '2fa'], 'guard' => 'auth'], function () { return view('laravel'); }); + // old route redirects + Route::get('poll-log', function () { + return redirect('pollers/tab=log/'); + }); + // Two Factor Auth Route::get('2fa', 'TwoFactorController@showTwoFactorForm')->name('2fa.form'); Route::post('2fa', 'TwoFactorController@verifyTwoFactor')->name('2fa.verify');