Merge pull request #11661 from SourceDoctor/app_dhcp_enhancement

Application DHCP Upgrade
This commit is contained in:
Tony Murray
2020-06-16 17:03:45 -05:00
committed by GitHub
14 changed files with 412 additions and 27 deletions

View File

@@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AlterMetricColumn extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('application_metrics', function (Blueprint $table) {
$table->string('metric', 64)->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('application_metrics', function (Blueprint $table) {
$table->string('metric', 32)->change();
});
}
}

View File

@@ -428,25 +428,38 @@ Extend` heading top of page.
# DHCP Stats
A small shell script that reports current DHCP leases stats.
A small python3 script that reports current DHCP leases stats and pool usage.
Also you have to install the dhcpd-pools Package.
Under Ubuntu/Debian just run `apt install dhcpd-pools`
## SNMP Extend
1: Copy the shell script to the desired host.
```
wget https://github.com/librenms/librenms-agent/raw/master/snmp/dhcp-status.sh -O /etc/snmp/dhcp-status.sh
wget https://github.com/librenms/librenms-agent/raw/master/snmp/dhcp.py -O /etc/snmp/dhcp.py
```
2: Run `chmod +x /etc/snmp/dhcp-status.sh`
2: Run `chmod +x /etc/snmp/dhcp.py`
3: Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:
3: edit a config file:
Content of an example /etc/snmp/dhcp.json . Please edit with your own settings.
```
{"leasefile": "/var/lib/dhcp/dhcpd.leases"
}
```
Key 'leasefile' specifies the path to your lease file.
4: Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add:
```
extend dhcpstats /etc/snmp/dhcp-status.sh
extend dhcpstats /etc/snmp/dhcp.py
```
4: Restart snmpd on your host
5: Restart snmpd on your host
The application should be auto-discovered as described at the top of
the page. If it is not, please follow the steps set out under `SNMP

View File

@@ -1279,6 +1279,7 @@ function get_postgres_databases($device_id)
function get_arrays_with_application($device, $app_id, $app_name, $category = null)
{
$entries = array();
$separator = '-';
if ($category) {
$pattern = sprintf('%s/%s-%s-%s-%s-*.rrd', get_rrd_dir($device['hostname']), 'app', $app_name, $app_id, $category);
@@ -1286,10 +1287,13 @@ function get_arrays_with_application($device, $app_id, $app_name, $category = nu
$pattern = sprintf('%s/%s-%s-%s-*.rrd', get_rrd_dir($device['hostname']), 'app', $app_name, $app_id);
}
# app_name contains a separator character? consider it
$offset = substr_count($app_name, $separator);
foreach (glob($pattern) as $rrd) {
$filename = basename($rrd, '.rrd');
list(,,, $entry) = explode("-", $filename, 4);
$entry = explode($separator, $filename, 4 + $offset)[3 + $offset];
if ($entry) {
array_push($entries, $entry);

View File

@@ -0,0 +1,36 @@
<?php
$unit_text = 'Current';
$unitlen = 20;
$bigdescrlen = 20;
$smalldescrlen = 20;
$category = 'networks';
$rrdVar = 'current';
$name = 'dhcp-stats';
$app_id = $app['app_id'];
$colours = 'mega';
$dostack = 0;
$printtotal = 0;
$addarea = 1;
$transparency = 15;
$arrays = get_arrays_with_application($device, $app_id, $name, $category);
$int=0;
while (isset($arrays[$int])) {
$array = $arrays[$int];
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app_id, $array));
if (rrdtool_check_rrd_exists($rrd_filename)) {
list($net, $subnet) = explode('_', str_replace($category.'-', '', $array));
$rrd_list[] = array(
'filename' => $rrd_filename,
'descr' => $net.'/'.$subnet,
'ds' => $rrdVar,
);
}
$int++;
}
require 'includes/html/graphs/generic_multi_line_exact_numbers.inc.php';

View File

@@ -0,0 +1,36 @@
<?php
$unit_text = 'Max';
$unitlen = 20;
$bigdescrlen = 20;
$smalldescrlen = 20;
$category = 'networks';
$rrdVar = 'max';
$name = 'dhcp-stats';
$app_id = $app['app_id'];
$colours = 'mega';
$dostack = 0;
$printtotal = 0;
$addarea = 1;
$transparency = 15;
$arrays = get_arrays_with_application($device, $app_id, $name, $category);
$int=0;
while (isset($arrays[$int])) {
$array = $arrays[$int];
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app_id, $array));
if (rrdtool_check_rrd_exists($rrd_filename)) {
list($net, $subnet) = explode('_', str_replace($category.'-', '', $array));
$rrd_list[] = array(
'filename' => $rrd_filename,
'descr' => $net.'/'.$subnet,
'ds' => $rrdVar,
);
}
$int++;
}
require 'includes/html/graphs/generic_multi_line_exact_numbers.inc.php';

View File

@@ -0,0 +1,36 @@
<?php
$unit_text = 'Percent';
$unitlen = 20;
$bigdescrlen = 20;
$smalldescrlen = 20;
$category = 'networks';
$rrdVar = 'percent';
$name = 'dhcp-stats';
$app_id = $app['app_id'];
$colours = 'mega';
$dostack = 0;
$printtotal = 0;
$addarea = 1;
$transparency = 15;
$arrays = get_arrays_with_application($device, $app_id, $name, $category);
$int=0;
while (isset($arrays[$int])) {
$array = $arrays[$int];
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app_id, $array));
if (rrdtool_check_rrd_exists($rrd_filename)) {
list($net, $subnet) = explode('_', str_replace($category.'-', '', $array));
$rrd_list[] = array(
'filename' => $rrd_filename,
'descr' => $net.'/'.$subnet,
'ds' => $rrdVar,
);
}
$int++;
}
require 'includes/html/graphs/generic_multi_line_exact_numbers.inc.php';

View File

@@ -0,0 +1,37 @@
<?php
$unit_text = 'Current';
$unitlen = 33;
$bigdescrlen = 33;
$smalldescrlen = 33;
$category = 'pools';
$rrdVar = 'current';
$name = 'dhcp-stats';
$app_id = $app['app_id'];
$colours = 'mega';
$dostack = 0;
$printtotal = 0;
$addarea = 1;
$transparency = 15;
$arrays = get_arrays_with_application($device, $app_id, $name, $category);
$int=0;
while (isset($arrays[$int])) {
$array = $arrays[$int];
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app_id, $array));
if (rrdtool_check_rrd_exists($rrd_filename)) {
$rrd_list[] = array(
'filename' => $rrd_filename,
'descr' => str_replace($category.'-', '', $array),
'ds' => $rrdVar,
);
}
$int++;
}
require 'includes/html/graphs/generic_multi_line_exact_numbers.inc.php';

View File

@@ -0,0 +1,36 @@
<?php
$unit_text = 'Max';
$unitlen = 33;
$bigdescrlen = 33;
$smalldescrlen = 33;
$category = 'pools';
$rrdVar = 'max';
$name = 'dhcp-stats';
$app_id = $app['app_id'];
$colours = 'mega';
$dostack = 0;
$printtotal = 0;
$addarea = 1;
$transparency = 15;
$arrays = get_arrays_with_application($device, $app_id, $name, $category);
$int=0;
while (isset($arrays[$int])) {
$array = $arrays[$int];
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app_id, $array));
if (rrdtool_check_rrd_exists($rrd_filename)) {
$rrd_list[] = array(
'filename' => $rrd_filename,
'descr' => str_replace($category.'-', '', $array),
'ds' => $rrdVar,
);
}
$int++;
}
require 'includes/html/graphs/generic_multi_line_exact_numbers.inc.php';

View File

@@ -0,0 +1,37 @@
<?php
$unit_text = 'Percent';
$unitlen = 33;
$bigdescrlen = 33;
$smalldescrlen = 33;
$category = 'pools';
$rrdVar = 'percent';
$name = 'dhcp-stats';
$app_id = $app['app_id'];
$colours = 'mega';
$dostack = 0;
$printtotal = 0;
$addarea = 1;
$transparency = 15;
$arrays = get_arrays_with_application($device, $app_id, $name, $category);
$int=0;
while (isset($arrays[$int])) {
$array = $arrays[$int];
$rrd_filename = rrd_name($device['hostname'], array('app', $name, $app_id, $array));
if (rrdtool_check_rrd_exists($rrd_filename)) {
$rrd_list[] = array(
'filename' => $rrd_filename,
'descr' => str_replace($category.'-', '', $array),
'ds' => $rrdVar,
);
}
$int++;
}
require 'includes/html/graphs/generic_multi_line_exact_numbers.inc.php';

View File

@@ -124,6 +124,12 @@ $graphs['os-updates'] = array(
);
$graphs['dhcp-stats'] = array(
'stats',
'pools_percent',
'pools_current',
'pools_max',
'networks_percent',
'networks_current',
'networks_max',
);
$graphs['fail2ban'] = array(
'banned',

View File

@@ -1,14 +1,20 @@
<?php
$graphs = array(
'dhcp-stats_stats' => 'DHCP Stats',
'dhcp-stats_stats' => 'Stats',
'dhcp-stats_pools_percent' => 'Pools Percent',
'dhcp-stats_pools_current' => 'Pools Current',
'dhcp-stats_pools_max' => 'Pools Max',
'dhcp-stats_networks_percent' => 'Networks Percent',
'dhcp-stats_networks_current' => 'Networks Current',
'dhcp-stats_networks_max' => 'Networks Max',
);
foreach ($graphs as $key => $text) {
$graph_type = $key;
$graph_array['height'] = '100';
$graph_array['width'] = '215';
$graph_array['to'] = \LibreNMS\Config::get('time.now');
$graph_array['to'] = time();
$graph_array['id'] = $app['app_id'];
$graph_array['type'] = 'application_'.$key;

View File

@@ -1,15 +1,57 @@
<?php
use LibreNMS\Exceptions\JsonAppMissingKeysException;
use LibreNMS\Exceptions\JsonAppException;
use LibreNMS\RRD\RrdDefinition;
$snmp_extend_name = 'dhcpstats';
$name = 'dhcp-stats';
$app_id = $app['app_id'];
$options = '-Oqv';
$mib = 'NET-SNMP-EXTEND-MIB';
$oid = '.1.3.6.1.4.1.8072.1.3.2.4.1.2.9.100.104.99.112.115.116.97.116.115';
$dhcpstats = snmp_walk($device, $oid, $options, $mib);
list($dhcp_total,$dhcp_active,$dhcp_expired,$dhcp_released,$dhcp_abandoned,$dhcp_reset,$dhcp_bootp,$dhcp_backup,$dhcp_free) = explode("\n", $dhcpstats);
$version = 1;
$output = 'OK';
try {
$dhcp_data = json_app_get($device, $snmp_extend_name, 1);
$dhcpstats = $dhcp_data['data'];
$version = $dhcp_data['version'];
} catch (JsonAppMissingKeysException $e) {
$dhcpstats = $e->getParsedJson();
$output = 'ERROR';
} catch (JsonAppException $e) {
$dhcpstats = snmp_walk($device, $oid, $options, $mib);
}
$version = intval($version);
if ($version == 1) {
$output = 'LEGACY';
} elseif ($version == 2) {
$output = 'OK';
} else {
$output = 'UNSUPPORTED';
}
$metrics = array();
$category = 'stats';
if (intval($version) == 1) {
list($dhcp_total, $dhcp_active, $dhcp_expired, $dhcp_released, $dhcp_abandoned, $dhcp_reset, $dhcp_bootp, $dhcp_backup, $dhcp_free) = explode("\n", $dhcpstats);
} elseif ($version == 2) {
$lease_data = $dhcpstats['leases'];
$dhcp_total = $lease_data['total'];
$dhcp_active = $lease_data['active'];
$dhcp_expired = $lease_data['expired'];
$dhcp_released = $lease_data['released'];
$dhcp_abandoned = $lease_data['abandoned'];
$dhcp_reset = $lease_data['reset'];
$dhcp_bootp = $lease_data['bootp'];
$dhcp_backup = $lease_data['backup'];
$dhcp_free = $lease_data['free'];
}
$rrd_name = array('app', $name, $app_id);
$rrd_def = RrdDefinition::make()
@@ -24,17 +66,81 @@ $rrd_def = RrdDefinition::make()
->addDataset('dhcp_free', 'GAUGE', 0);
$fields = array(
'dhcp_total' => $dhcp_total,
'dhcp_active' => $dhcp_active,
'dhcp_expired' => $dhcp_expired,
'dhcp_released' => $dhcp_released,
'dhcp_total' => $dhcp_total,
'dhcp_active' => $dhcp_active,
'dhcp_expired' => $dhcp_expired,
'dhcp_released' => $dhcp_released,
'dhcp_abandoned' => $dhcp_abandoned,
'dhcp_reset' => $dhcp_reset,
'dhcp_bootp' => $dhcp_bootp,
'dhcp_backup' => $dhcp_backup,
'dhcp_free' => $dhcp_free,
'dhcp_reset' => $dhcp_reset,
'dhcp_bootp' => $dhcp_bootp,
'dhcp_backup' => $dhcp_backup,
'dhcp_free' => $dhcp_free,
);
$metrics[$name . '_' . $category] = $fields;
$tags = array('name' => $name, 'app_id' => $app_id, 'rrd_def' => $rrd_def, 'rrd_name' => $rrd_name);
data_update($device, 'app', $tags, $fields);
update_application($app, $dhcpstats, $fields);
if ($version == 2) {
$category = 'pools';
$pool_data = $dhcpstats['pools'];
$rrd_def = RrdDefinition::make()
->addDataset('current', 'GAUGE', 0)
->addDataset('max', 'GAUGE', 0)
->addDataset('percent', 'GAUGE', 0);
foreach ($pool_data as $data) {
$dhcp_pool_name = $data['first_ip'].'_-_'.$data['last_ip'];
$dhcp_current = $data['cur'];
$dhcp_max = $data['max'];
$dhcp_percent = $data['percent'];
$rrd_name = array('app', $name, $app_id, $category, $dhcp_pool_name);
$fields = array(
'current' => $dhcp_current,
'max' => $dhcp_max,
'percent' => $dhcp_percent,
);
$metrics[$dhcp_pool_name.'_'.$category] = $fields;
$tags = array('name' => $dhcp_pool_name, 'app_id' => $app_id, 'rrd_def' => $rrd_def, 'rrd_name' => $rrd_name);
data_update($device, 'app', $tags, $fields);
}
$category = 'networks';
$network_data = $dhcpstats['networks'];
$rrd_def = RrdDefinition::make()
->addDataset('current', 'GAUGE', 0)
->addDataset('max', 'GAUGE', 0)
->addDataset('percent', 'GAUGE', 0);
foreach ($network_data as $data) {
$dhcp_network_name = str_replace('/', '_', $data['network']);
$dhcp_current = $data['cur'];
$dhcp_max = $data['max'];
$dhcp_percent = $data['percent'] == 'nan' ? '0' : $data['percent'];
$rrd_name = array('app', $name, $app_id, $category, $dhcp_network_name);
$fields = array(
'current' => $dhcp_current,
'max' => $dhcp_max,
'percent' => $dhcp_percent,
);
$metrics[$dhcp_network_name.'_'.$category] = $fields;
$tags = array('name' => $dhcp_network_name, 'app_id' => $app_id, 'rrd_def' => $rrd_def, 'rrd_name' => $rrd_name);
data_update($device, 'app', $tags, $fields);
}
}
if ($version == 1) {
$app_state = $dhcp_active . '/' . $dhcp_total;
} else {
$app_state = $dhcpstats['all_networks']['cur'] . '/' . $dhcpstats['all_networks']['max'];
}
update_application($app, $output, $metrics, $app_state);

View File

@@ -175,7 +175,7 @@ applications:
application_metrics:
Columns:
- { Field: app_id, Type: 'int unsigned', 'Null': false, Extra: '' }
- { Field: metric, Type: varchar(32), 'Null': false, Extra: '' }
- { Field: metric, Type: varchar(64), 'Null': false, Extra: '' }
- { Field: value, Type: double, 'Null': true, Extra: '' }
- { Field: value_prev, Type: double, 'Null': true, Extra: '' }
Indexes:

View File

@@ -118,8 +118,8 @@
"app_type": "seafile"
},
{
"metric": "test_user_1_acc_trashed_librarie",
"value": 0,
"metric": "test_user_1_acc_trashed_libraries",
"value": 0.0,
"value_prev": null,
"app_type": "seafile"
},
@@ -142,8 +142,8 @@
"app_type": "seafile"
},
{
"metric": "test_user_2_acc_trashed_librarie",
"value": 0,
"metric": "test_user_2_acc_trashed_libraries",
"value": 0.0,
"value_prev": null,
"app_type": "seafile"
},
@@ -166,8 +166,8 @@
"app_type": "seafile"
},
{
"metric": "test_user_3_acc_trashed_librarie",
"value": 0,
"metric": "test_user_3_acc_trashed_libraries",
"value": 0.0,
"value_prev": null,
"app_type": "seafile"
}