diff --git a/doc/Extensions/Applications.md b/doc/Extensions/Applications.md index 03ea365a9f..8fa5962509 100644 --- a/doc/Extensions/Applications.md +++ b/doc/Extensions/Applications.md @@ -33,6 +33,7 @@ Different applications support a variety of ways to collect data: by direct conn 1. [Postgres](#postgres) - SNMP extend 1. [PowerDNS](#powerdns) - Agent 1. [PowerDNS Recursor](#powerdns-recursor) - Direct, Agent +1. [PowerDNS dnsdist](#powerdns-dnsdist) - SNMP extend 1. [Proxmox](#proxmox) - SNMP extend 1. [Raspberry PI](#raspberry-pi) - SNMP extend 1. [SDFS info](#sdfs-info) - SNMP extend @@ -725,6 +726,23 @@ extend powerdns-recursor /etc/snmp/powerdns-recursor This script uses `rec_control get-all` to collect stats. +### PowerDNS-dnsdist + +###### SNMP Extend +1. Copy the BASH script to the desired host (the host must be added to LibreNMS devices) +``` +wget https://github.com/librenms/librenms-agent/raw/master/snmp/powerdns-dnsdist -O /etc/snmp/powerdns-dnsdist +``` + +2. Make the script executable (chmod +x /etc/snmp/powerdns-dnsdist) + +3. Edit your snmpd.conf file (usually /etc/snmp/snmpd.conf) and add: +``` +extend powerdns-dnsdist /etc/snmp/powerdns-dnsdist +``` + +4. Restart snmpd on your host. + ### Proxmox 1. For Proxmox 4.4+ install the libpve-apiclient-perl package `apt install libpve-apiclient-perl` diff --git a/html/includes/functions.inc.php b/html/includes/functions.inc.php index 545eb8b6d7..a5a4b51f13 100644 --- a/html/includes/functions.inc.php +++ b/html/includes/functions.inc.php @@ -96,6 +96,9 @@ function nicecase($item) case 'powerdns-recursor': return 'PowerDNS Recursor'; + case 'powerdns-dnsdist': + return 'PowerDNS dnsdist'; + case 'dhcp-stats': return 'DHCP Stats'; diff --git a/html/includes/graphs/application/powerdns-dnsdist_cache.inc.php b/html/includes/graphs/application/powerdns-dnsdist_cache.inc.php new file mode 100644 index 0000000000..251fe79906 --- /dev/null +++ b/html/includes/graphs/application/powerdns-dnsdist_cache.inc.php @@ -0,0 +1,49 @@ + +*/ + +require 'includes/graphs/common.inc.php'; + +$scale_min = 0; +$colours = 'mixed'; +$unit_text = 'Cache'; +$unitlen = 6; +$bigdescrlen = 25; +$smalldescrlen = 25; +$dostack = 0; +$printtotal = 0; +$addarea = 1; +$transparency = 33; +$rrd_filename = rrd_name($device['hostname'], array('app', $app['app_type'], $app['app_id'])); + +$array = array( + 'cache_hits' => array('descr' => 'Hits', 'colour' => '4CB24C',), + 'cache_miss' => array('descr' => 'Miss', 'colour' => 'BF3F3F',), +); + +$i = 0; + +if (rrdtool_check_rrd_exists($rrd_filename)) { + foreach ($array as $ds => $var) { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $var['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $var['colour']; + $i++; + } +} else { + echo "file missing: $rrd_filename"; +} + +require 'includes/graphs/generic_v3_multiline_float.inc.php'; diff --git a/html/includes/graphs/application/powerdns-dnsdist_downstream.inc.php b/html/includes/graphs/application/powerdns-dnsdist_downstream.inc.php new file mode 100644 index 0000000000..c70397613f --- /dev/null +++ b/html/includes/graphs/application/powerdns-dnsdist_downstream.inc.php @@ -0,0 +1,48 @@ + +*/ + +require 'includes/graphs/common.inc.php'; +$scale_min = 0; +$colours = 'mixed'; +$unit_text = 'Downstream servers'; +$unitlen = 18; +$bigdescrlen = 25; +$smalldescrlen = 25; +$dostack = 0; +$printtotal = 0; +$addarea = 1; +$transparency = 33; +$rrd_filename = rrd_name($device['hostname'], array('app', $app['app_type'], $app['app_id'])); + +$array = array( + 'downstream_timeout' => array('descr' => 'Timeout', 'colour' => 'BF3F7F',), + 'downstream_err' => array('descr' => 'Errors', 'colour' => 'BF3F3F',), +); + +$i = 0; + +if (rrdtool_check_rrd_exists($rrd_filename)) { + foreach ($array as $ds => $var) { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $var['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $var['colour']; + $i++; + } +} else { + echo "file missing: $rrd_filename"; +} + +require 'includes/graphs/generic_v3_multiline_float.inc.php'; diff --git a/html/includes/graphs/application/powerdns-dnsdist_dynamic_blocks.inc.php b/html/includes/graphs/application/powerdns-dnsdist_dynamic_blocks.inc.php new file mode 100644 index 0000000000..0fa2ba5b7c --- /dev/null +++ b/html/includes/graphs/application/powerdns-dnsdist_dynamic_blocks.inc.php @@ -0,0 +1,48 @@ + +*/ + +require 'includes/graphs/common.inc.php'; +$scale_min = 0; +$colours = 'mixed'; +$unit_text = 'Dynamic Blocks'; +$unitlen = 16; +$bigdescrlen = 25; +$smalldescrlen = 25; +$dostack = 0; +$printtotal = 0; +$addarea = 1; +$transparency = 33; +$rrd_filename = rrd_name($device['hostname'], array('app', $app['app_type'], $app['app_id'])); + +$array = array( + 'dynamic_blocked' => array('descr' => 'Dropped', 'colour' => 'BF3F7F',), + 'dynamic_block_size' => array('descr' => 'Size', 'colour' => '264C72',), +); + +$i = 0; + +if (rrdtool_check_rrd_exists($rrd_filename)) { + foreach ($array as $ds => $var) { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $var['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $var['colour']; + $i++; + } +} else { + echo "file missing: $rrd_filename"; +} + +require 'includes/graphs/generic_v3_multiline_float.inc.php'; diff --git a/html/includes/graphs/application/powerdns-dnsdist_latency.inc.php b/html/includes/graphs/application/powerdns-dnsdist_latency.inc.php new file mode 100644 index 0000000000..8566ea95d4 --- /dev/null +++ b/html/includes/graphs/application/powerdns-dnsdist_latency.inc.php @@ -0,0 +1,50 @@ + +*/ + +require 'includes/graphs/common.inc.php'; +$scale_min = 0; +$colours = 'mixed'; +$unit_text = 'Average latency'; +$unitlen = 16; +$bigdescrlen = 25; +$smalldescrlen = 25; +$dostack = 0; +$printtotal = 0; +$addarea = 1; +$transparency = 33; +$rrd_filename = rrd_name($device['hostname'], array('app', $app['app_type'], $app['app_id'])); + +$array = array( + 'latency_100' => array('descr' => 'Last 100 pkts', 'colour' => 'd29ba5',), + 'latency_1000' => array('descr' => 'Last 1000 pkts', 'colour' => 'b75e6e',), + 'latency_10000' => array('descr' => 'Last 10000 pkts', 'colour' => '732634',), + 'latency_1000000' => array('descr' => 'Last 1000000 pkts', 'colour' => '521b25',), +); + +$i = 0; + +if (rrdtool_check_rrd_exists($rrd_filename)) { + foreach ($array as $ds => $var) { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $var['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $var['colour']; + $i++; + } +} else { + echo "file missing: $rrd_filename"; +} + +require 'includes/graphs/generic_v3_multiline_float.inc.php'; diff --git a/html/includes/graphs/application/powerdns-dnsdist_queries_drop.inc.php b/html/includes/graphs/application/powerdns-dnsdist_queries_drop.inc.php new file mode 100644 index 0000000000..41145a4854 --- /dev/null +++ b/html/includes/graphs/application/powerdns-dnsdist_queries_drop.inc.php @@ -0,0 +1,52 @@ + +*/ + +require 'includes/graphs/common.inc.php'; +$scale_min = 0; +$colours = 'mixed'; +$unit_text = 'Queries drop'; +$unitlen = 16; +$bigdescrlen = 25; +$smalldescrlen = 25; +$dostack = 0; +$printtotal = 0; +$addarea = 1; +$transparency = 33; +$rrd_filename = rrd_name($device['hostname'], array('app', $app['app_type'], $app['app_id'])); + +$array = array( + 'queries_drop_no_policy' => array('descr' => 'No server', 'colour' => 'aa0635',), + 'queries_drop_nc' => array('descr' => 'Non-compliant', 'colour' => 'cc6985',), + 'queries_drop_nc_answer' => array('descr' => 'Non-compliant answer', 'colour' => '2d2d2d',), + 'queries_acl_drop' => array('descr' => 'ACL', 'colour' => '008442',), + 'queries_failure' => array('descr' => 'Failure', 'colour' => 'e55b38',), + 'queries_serv_fail' => array('descr' => 'Servfail', 'colour' => '9a3e3e',), +); + +$i = 0; + +if (rrdtool_check_rrd_exists($rrd_filename)) { + foreach ($array as $ds => $var) { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $var['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $var['colour']; + $i++; + } +} else { + echo "file missing: $rrd_filename"; +} + +require 'includes/graphs/generic_v3_multiline_float.inc.php'; diff --git a/html/includes/graphs/application/powerdns-dnsdist_queries_latency.inc.php b/html/includes/graphs/application/powerdns-dnsdist_queries_latency.inc.php new file mode 100644 index 0000000000..048c2b223b --- /dev/null +++ b/html/includes/graphs/application/powerdns-dnsdist_queries_latency.inc.php @@ -0,0 +1,52 @@ + +*/ + +require 'includes/graphs/common.inc.php'; +$scale_min = 0; +$colours = 'mixed'; +$unit_text = 'Queries answer latency'; +$unitlen = 6; +$bigdescrlen = 25; +$smalldescrlen = 25; +$dostack = 0; +$printtotal = 0; +$addarea = 1; +$transparency = 33; +$rrd_filename = rrd_name($device['hostname'], array('app', $app['app_type'], $app['app_id'])); + +$array = array( + 'latency_0_1' => array('descr' => '< 1ms', 'colour' => '58b146',), + 'latency_1_10' => array('descr' => '1-10 ms', 'colour' => '4f9f3f',), + 'latency_10_50' => array('descr' => '10-50 ms', 'colour' => '3d7b31',), + 'latency_50_100' => array('descr' => '50-100 ms', 'colour' => '23461c',), + 'latency_100_1000' => array('descr' => '100-1000 ms', 'colour' => '11230e',), + 'latency_slow' => array('descr' => '> 1 sec', 'colour' => '727F8C',), +); + +$i = 0; + +if (rrdtool_check_rrd_exists($rrd_filename)) { + foreach ($array as $ds => $var) { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $var['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $var['colour']; + $i++; + } +} else { + echo "file missing: $rrd_filename"; +} + +require 'includes/graphs/generic_v3_multiline_float.inc.php'; diff --git a/html/includes/graphs/application/powerdns-dnsdist_queries_stats.inc.php b/html/includes/graphs/application/powerdns-dnsdist_queries_stats.inc.php new file mode 100644 index 0000000000..4ac0efb9a2 --- /dev/null +++ b/html/includes/graphs/application/powerdns-dnsdist_queries_stats.inc.php @@ -0,0 +1,50 @@ + +*/ + +require 'includes/graphs/common.inc.php'; +$scale_min = 0; +$colours = 'mixed'; +$unit_text = 'Queries stats'; +$unitlen = 16; +$bigdescrlen = 25; +$smalldescrlen = 25; +$dostack = 0; +$printtotal = 0; +$addarea = 1; +$transparency = 33; +$rrd_filename = rrd_name($device['hostname'], array('app', $app['app_type'], $app['app_id'])); + +$array = array( + 'queries_count' => array('descr' => 'Total', 'colour' => '5aa492',), + 'queries_recursive' => array('descr' => 'Recursive', 'colour' => '3e7266',), + 'queries_empty' => array('descr' => 'Empty', 'colour' => 'aa0635',), + 'queries_self_answer' => array('descr' => 'Self answer', 'colour' => '81cdea',), +); + +$i = 0; + +if (rrdtool_check_rrd_exists($rrd_filename)) { + foreach ($array as $ds => $var) { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $var['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $var['colour']; + $i++; + } +} else { + echo "file missing: $rrd_filename"; +} + +require 'includes/graphs/generic_v3_multiline_float.inc.php'; diff --git a/html/includes/graphs/application/powerdns-dnsdist_rules_stats.inc.php b/html/includes/graphs/application/powerdns-dnsdist_rules_stats.inc.php new file mode 100644 index 0000000000..044f63ada2 --- /dev/null +++ b/html/includes/graphs/application/powerdns-dnsdist_rules_stats.inc.php @@ -0,0 +1,49 @@ + +*/ + +require 'includes/graphs/common.inc.php'; +$scale_min = 0; +$colours = 'mixed'; +$unit_text = 'Rule stats'; +$unitlen = 12; +$bigdescrlen = 25; +$smalldescrlen = 25; +$dostack = 0; +$printtotal = 0; +$addarea = 1; +$transparency = 33; +$rrd_filename = rrd_name($device['hostname'], array('app', $app['app_type'], $app['app_id'])); + +$array = array( + 'rule_drop' => array('descr' => 'Drop', 'colour' => '7a0d18',), + 'rule_nxdomain' => array('descr' => 'NXDomain', 'colour' => 'e0b7bb',), + 'rule_refused' => array('descr' => 'Refused', 'colour' => 'ad404b',), +); + +$i = 0; + +if (rrdtool_check_rrd_exists($rrd_filename)) { + foreach ($array as $ds => $var) { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $var['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $var['colour']; + $i++; + } +} else { + echo "file missing: $rrd_filename"; +} + +require 'includes/graphs/generic_v3_multiline_float.inc.php'; diff --git a/html/pages/apps.inc.php b/html/pages/apps.inc.php index d653d114fe..a3627765ab 100755 --- a/html/pages/apps.inc.php +++ b/html/pages/apps.inc.php @@ -297,6 +297,17 @@ $graphs['zfs'] = array( 'arc_cache_miss', ); +$graphs['powerdns-dnsdist'] = array( + 'cache', + 'downstream', + 'dynamic_blocks', + 'latency', + 'queries_latency', + 'queries_stats', + 'rules_stats', + 'queries_drop', +); + echo '
'; echo '
'; diff --git a/html/pages/device/apps/powerdns-dnsdist.inc.php b/html/pages/device/apps/powerdns-dnsdist.inc.php new file mode 100644 index 0000000000..bdfed4d467 --- /dev/null +++ b/html/pages/device/apps/powerdns-dnsdist.inc.php @@ -0,0 +1,47 @@ + +*/ + +global $config; + +$graphs = array( + 'powerdns-dnsdist_latency' => 'Latency', + 'powerdns-dnsdist_cache' => 'Cache', + 'powerdns-dnsdist_downstream' => 'Downstream servers', + 'powerdns-dnsdist_dynamic_blocks' => 'Dynamic blocks', + 'powerdns-dnsdist_rules_stats' => 'Rules stats', + 'powerdns-dnsdist_queries_stats' => 'Queries stats', + 'powerdns-dnsdist_queries_latency' => 'Queries latency', + 'powerdns-dnsdist_queries_drop' => 'Queries drop', +); + +foreach ($graphs as $key => $text) { + $graph_type = $key; + $graph_array['height'] = '100'; + $graph_array['width'] = '215'; + $graph_array['to'] = $config['time']['now']; + $graph_array['id'] = $app['app_id']; + $graph_array['type'] = 'application_'.$key; + + echo '
+
+

'.$text.'

+
+
+
'; + include 'includes/print-graphrow.inc.php'; + echo '
'; + echo '
'; + echo '
'; +} diff --git a/includes/polling/applications/powerdns-dnsdist.inc.php b/includes/polling/applications/powerdns-dnsdist.inc.php new file mode 100644 index 0000000000..28be286fe0 --- /dev/null +++ b/includes/polling/applications/powerdns-dnsdist.inc.php @@ -0,0 +1,107 @@ +. +* +* @package LibreNMS +* @link http://librenms.org +* @copyright 2017 LibreNMS +* @author Cercel Valentin +*/ + +use LibreNMS\RRD\RrdDefinition; + +$name = 'powerdns-dnsdist'; +$app_id = $app['app_id']; +$options = '-O qv'; +//NET-SNMP-EXTEND-MIB::nsExtendOutputFull."powerdns-dnsdist" +$oid = '.1.3.6.1.4.1.8072.1.3.2.3.1.2.16.112.111.119.101.114.100.110.115.45.100.110.115.100.105.115.116'; + +d_echo($name); + +$powerdns_dnsdist = snmp_walk($device, $oid, $options); + +if (is_string($powerdns_dnsdist)) { + list($cache_hits, $cache_miss, $downstream_err, $downstream_timeout, $dynamic_block_size, $dynamic_blocked, $queries_count, $queries_recursive, $queries_empty, $queries_drop_no_policy, $queries_drop_nc, $queries_drop_nc_answer, $queries_self_answer, $queries_serv_fail, $queries_failure, $queries_acl_drop, $rule_drop, $rule_nxdomain, $rule_refused, $latency_100, $latency_1000, $latency_10000, $latency_1000000, $latency_slow, $latency_0_1, $latency_1_10, $latency_10_50, $latency_50_100, $latency_100_1000) = explode("\n", $powerdns_dnsdist); + + $rrd_name = array('app', $name, $app_id); + + $rrd_def = RrdDefinition::make() + ->addDataset('cache_hits', 'COUNTER', 0) + ->addDataset('cache_miss', 'COUNTER', 0) + ->addDataset('downstream_err', 'COUNTER', 0) + ->addDataset('downstream_timeout', 'COUNTER', 0) + ->addDataset('dynamic_block_size', 'COUNTER', 0) + ->addDataset('dynamic_blocked', 'COUNTER', 0) + ->addDataset('queries_count', 'COUNTER', 0) + ->addDataset('queries_recursive', 'COUNTER', 0) + ->addDataset('queries_empty', 'COUNTER', 0) + ->addDataset('queries_drop_no_policy', 'COUNTER', 0) + ->addDataset('queries_drop_nc', 'COUNTER', 0) + ->addDataset('queries_drop_nc_answer', 'COUNTER', 0) + ->addDataset('queries_self_answer', 'COUNTER', 0) + ->addDataset('queries_serv_fail', 'COUNTER', 0) + ->addDataset('queries_failure', 'COUNTER', 0) + ->addDataset('queries_acl_drop', 'COUNTER', 0) + ->addDataset('rule_drop', 'COUNTER', 0) + ->addDataset('rule_nxdomain', 'COUNTER', 0) + ->addDataset('rule_refused', 'COUNTER', 0) + ->addDataset('latency_100', 'GAUGE', 0) + ->addDataset('latency_1000', 'GAUGE', 0) + ->addDataset('latency_10000', 'GAUGE', 0) + ->addDataset('latency_1000000', 'GAUGE', 0) + ->addDataset('latency_slow', 'COUNTER', 0) + ->addDataset('latency_0_1', 'COUNTER', 0) + ->addDataset('latency_1_10', 'COUNTER', 0) + ->addDataset('latency_10_50', 'COUNTER', 0) + ->addDataset('latency_50_100', 'COUNTER', 0) + ->addDataset('latency_100_1000', 'COUNTER', 0); + + + $fields = array( + 'cache_hits' => $cache_hits, + 'cache_miss' => $cache_miss, + 'downstream_err' => $downstream_err, + 'downstream_timeout' => $downstream_timeout, + 'dynamic_block_size' => $dynamic_block_size, + 'dynamic_blocked' => $dynamic_blocked, + 'queries_count' => $queries_count, + 'queries_recursive' => $queries_recursive, + 'queries_empty' => $queries_empty, + 'queries_self_answer' => $queries_self_answer, + 'queries_drop_no_policy' => $queries_drop_no_policy, + 'queries_drop_nc' => $queries_drop_nc, + 'queries_drop_nc_answer' => $queries_drop_nc_answer, + 'queries_failure' => $queries_failure, + 'queries_acl_drop' => $queries_acl_drop, + 'queries_serv_fail' => $queries_serv_fail, + 'rule_drop' => $rule_drop, + 'rule_nxdomain' => $rule_nxdomain, + 'rule_refused' => $rule_refused, + 'latency_100' => $latency_100, + 'latency_1000' => $latency_1000, + 'latency_10000' => $latency_10000, + 'latency_1000000' => $latency_1000000, + 'latency_slow' => $latency_slow, + 'latency_0_1' => $latency_0_1, + 'latency_1_10' => $latency_1_10, + 'latency_10_50' => $latency_10_50, + 'latency_50_100' => $latency_50_100, + 'latency_100_1000' => $latency_100_1000, + ); + + $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, $powerdns_dnsdist, $fields); +} +unset($powerdns_dnsdist);