diff --git a/html/includes/graphs/application/powerdns-recursor.inc.php b/html/includes/graphs/application/powerdns-recursor.inc.php new file mode 100644 index 0000000000..72a6221cd8 --- /dev/null +++ b/html/includes/graphs/application/powerdns-recursor.inc.php @@ -0,0 +1,30 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2016 Tony Murray + * @author Tony Murray + */ + +$rrd = rrd_name($device['hostname'], array('app', 'powerdns-recursor', $app['app_id'])); +if (is_file($rrd)) { + $rrd_filename = $rrd; +} +$simple_rrd = true; diff --git a/html/includes/graphs/application/powerdns-recursor_answers.inc.php b/html/includes/graphs/application/powerdns-recursor_answers.inc.php new file mode 100644 index 0000000000..cdeb327db0 --- /dev/null +++ b/html/includes/graphs/application/powerdns-recursor_answers.inc.php @@ -0,0 +1,64 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2016 Tony Murray + * @author Tony Murray + */ + +include 'powerdns-recursor.inc.php'; + +$colours = 'oranges'; +$unit_text = 'Answers/sec'; +$print_total = true; + +if (is_file($rrd_filename)) { + $rrd_list = array( + array( + 'ds' => 'answers0-1', + 'filename' => $rrd_filename, + 'descr' => '0-1ms', + ), + array( + 'ds' => 'answers1-10', + 'filename' => $rrd_filename, + 'descr' => '1-10ms', + ), + array( + 'ds' => 'answers10-100', + 'filename' => $rrd_filename, + 'descr' => '10-100ms', + ), + array( + 'ds' => 'answers100-1000', + 'filename' => $rrd_filename, + 'descr' => '100-1000ms', + ), + array( + 'ds' => 'answers-slow', + 'filename' => $rrd_filename, + 'descr' => '>1s', + ), + ); +} else { + echo "file missing: $rrd_filename"; +} + +require 'includes/graphs/generic_multi.inc.php'; \ No newline at end of file diff --git a/html/includes/graphs/application/powerdns-recursor_cache_performance.inc.php b/html/includes/graphs/application/powerdns-recursor_cache_performance.inc.php new file mode 100644 index 0000000000..5676f62f84 --- /dev/null +++ b/html/includes/graphs/application/powerdns-recursor_cache_performance.inc.php @@ -0,0 +1,65 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2016 Tony Murray + * @author Tony Murray + */ +include 'powerdns-recursor.inc.php'; + +$colours = 'mixed'; +$unit_text = 'Packets/sec'; + +if (is_file($rrd_filename)) { + $rrd_list = array( + array( + 'filename' => $rrd_filename, + 'ds' => 'cache-hits', + 'descr' => 'Query Cache Hits', + 'colour' => '297159', + 'area' => true, + ), + array( + 'filename' => $rrd_filename, + 'ds' => 'cache-misses', + 'descr' => 'Query Cache Misses', + 'colour' => '73AC61', + 'area' => true, + ), + array( + 'filename' => $rrd_filename, + 'ds' => 'packetcache-hits', + 'descr' => 'Packet Cache Hits', + 'colour' => 'BC7049', + 'area' => true, + ), + array( + 'filename' => $rrd_filename, + 'ds' => 'packetcache-misses', + 'descr' => 'Packet Cache Misses', + 'colour' => 'C98F45', + 'area' => true, + ) + ); +} else { + echo "file missing: $rrd_filename"; +} + +require 'includes/graphs/generic_multi_line.inc.php'; \ No newline at end of file diff --git a/html/includes/graphs/application/powerdns-recursor_cache_size.inc.php b/html/includes/graphs/application/powerdns-recursor_cache_size.inc.php new file mode 100644 index 0000000000..dc46388b73 --- /dev/null +++ b/html/includes/graphs/application/powerdns-recursor_cache_size.inc.php @@ -0,0 +1,50 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2016 Tony Murray + * @author Tony Murray + */ + +include 'powerdns-recursor.inc.php'; + +$colours = 'purples'; +$unit_text = 'Entries'; + +if (is_file($rrd_filename)) { + $rrd_list = array( + array( + 'filename' => $rrd_filename, + 'ds' => 'cache-entries', + 'descr' => 'Query Cache', + 'colour' => '202048', + ), + array( + 'filename' => $rrd_filename, + 'ds' => 'packetcache-entries', + 'descr' => 'Packet Cache', + 'colour' => 'CC7CCC', + ) + ); +} else { + echo "file missing: $rrd_filename"; +} + +require 'includes/graphs/generic_multi_line.inc.php'; diff --git a/html/includes/graphs/application/powerdns-recursor_outqueries.inc.php b/html/includes/graphs/application/powerdns-recursor_outqueries.inc.php new file mode 100644 index 0000000000..aa6281fd10 --- /dev/null +++ b/html/includes/graphs/application/powerdns-recursor_outqueries.inc.php @@ -0,0 +1,68 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2016 Tony Murray + * @author Tony Murray + */ + +include 'powerdns-recursor.inc.php'; + +$colours = 'mixed'; +$unit_text = 'Queries/sec'; + +if (is_file($rrd_filename)) { + $rrd_list = array( + array( + 'filename' => $rrd_filename, + 'ds' => 'all-outqueries', + 'descr' => 'Total', + 'area' => true, + ), + array( + 'filename' => $rrd_filename, + 'ds' => 'ipv6-outqueries', + 'descr' => 'IPv6', + 'area' => true, + ), + array( + 'filename' => $rrd_filename, + 'ds' => 'tcp-outqueries', + 'descr' => 'TCP', + 'area' => true, + ), + array( + 'filename' => $rrd_filename, + 'ds' => 'throttled-out', + 'descr' => 'Throttled', + 'area' => true, + ), + array( + 'filename' => $rrd_filename, + 'ds' => 'outgoing-timeouts', + 'descr' => 'Timeouts', + 'area' => true, + ) + ); +} else { + echo "file missing: $rrd_filename"; +} + +require 'includes/graphs/generic_multi_line.inc.php'; \ No newline at end of file diff --git a/html/includes/graphs/application/powerdns-recursor_questions.inc.php b/html/includes/graphs/application/powerdns-recursor_questions.inc.php new file mode 100644 index 0000000000..6ef78fd441 --- /dev/null +++ b/html/includes/graphs/application/powerdns-recursor_questions.inc.php @@ -0,0 +1,68 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2016 Tony Murray + * @author Tony Murray + */ + +include 'powerdns-recursor.inc.php'; + +$colours = 'mixed'; +$unit_text = 'Questions/sec'; + +if (is_file($rrd_filename)) { + $rrd_list = array( + array( + 'filename' => $rrd_filename, + 'ds' => 'questions', + 'descr' => 'Total Questions', + 'area' => true, + ), + array( + 'filename' => $rrd_filename, + 'ds' => 'ipv6-questions', + 'descr' => 'IPv6 Questions', + 'area' => true, + ), + array( + 'filename' => $rrd_filename, + 'ds' => 'tcp-questions', + 'descr' => 'TCP Questions', + 'area' => true, + ), + array( + 'filename' => $rrd_filename, + 'ds' => 'over-capacity-drops', + 'descr' => 'Over Capacity Drops', + 'area' => true, + ), + array( + 'filename' => $rrd_filename, + 'ds' => 'policy-drops', + 'descr' => 'Policy Drops', + 'area' => true, + ) + ); +} else { + echo "file missing: $rrd_filename"; +} + +require 'includes/graphs/generic_multi_line.inc.php'; \ No newline at end of file diff --git a/html/includes/graphs/generic_multi.inc.php b/html/includes/graphs/generic_multi.inc.php index 6d7f78a1c0..5100fce0b3 100644 --- a/html/includes/graphs/generic_multi.inc.php +++ b/html/includes/graphs/generic_multi.inc.php @@ -1,5 +1,20 @@ '500') { @@ -29,20 +44,26 @@ else { $i = 0; $iter = 0; +$ids = array(); foreach ($rrd_list as $rrd) { - if (!$config['graph_colours'][$colours][$iter]) { - $iter = 0; + // get the color for this data set + if(isset($rrd['colour'])) { + $colour = $rrd['colour']; + } else { + if (!$config['graph_colours'][$colours][$iter]) { + $iter = 0; + } + $colour = $config['graph_colours'][$colours][$iter]; + $iter++; } - $colour = $config['graph_colours'][$colours][$iter]; - $ds = $rrd['ds']; $filename = $rrd['filename']; $descr = rrdtool_escape($rrd['descr'], $descr_len); - $id = 'ds'.$i; + $ids[] = ($id = 'ds'.$i); $rrd_options .= ' DEF:'.$id."=$filename:$ds:AVERAGE"; @@ -69,10 +90,26 @@ foreach ($rrd_list as $rrd) { $bstack = ':STACK'; } + + + $i++; - $iter++; }//end foreach +if ($print_total) { + $tot = $ids; + for ($i=1; $i '500') { @@ -31,11 +48,17 @@ $i = 0; $iter = 0; foreach ($rrd_list as $rrd) { - if (!$config['graph_colours'][$colours][$iter]) { - $iter = 0; + // get the color for this data set + if(isset($rrd['colour'])) { + $colour = $rrd['colour']; + } else { + if (!$config['graph_colours'][$colours][$iter]) { + $iter = 0; + } + $colour = $config['graph_colours'][$colours][$iter]; + $iter++; } - $colour = $config['graph_colours'][$colours][$iter]; if (!empty($rrd['area']) && empty($rrd['areacolour'])) { $rrd['areacolour'] = $colour."20"; } @@ -76,7 +99,6 @@ foreach ($rrd_list as $rrd) { $rrd_optionsb .= ' GPRINT:'.$id.'max:MAX:%5.2lf%s'.$units.' GPRINT:'.$id.":AVERAGE:'%5.2lf%s$units\\n'"; $i++; - $iter++; }//end foreach $rrd_options .= $rrd_optionsb; diff --git a/html/pages/apps.inc.php b/html/pages/apps.inc.php index e0843279b6..855de431c7 100644 --- a/html/pages/apps.inc.php +++ b/html/pages/apps.inc.php @@ -33,6 +33,13 @@ $graphs['nginx'] = array( 'req', ); +$graphs['powerdns-recursor'] = array( + 'questions', + 'answers', + 'cache_performance', + 'outqueries' +); + $graphs['rrdcached'] = array( 'queue_length', 'events', diff --git a/html/pages/device/apps/powerdns-recursor.inc.php b/html/pages/device/apps/powerdns-recursor.inc.php new file mode 100644 index 0000000000..421bc3f74d --- /dev/null +++ b/html/pages/device/apps/powerdns-recursor.inc.php @@ -0,0 +1,53 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2016 Tony Murray + * @author Tony Murray + */ + +global $config; + +$graphs = array( + 'powerdns-recursor_questions' => 'Questions', + 'powerdns-recursor_answers' => 'Answers', + 'powerdns-recursor_cache_performance' => 'Cache Performance', + 'powerdns-recursor_cache_size' => 'Cache Size', + 'powerdns-recursor_outqueries' => 'Outbound Queries', +); + +foreach ($graphs as $key => $text) { + $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 '
'; +} \ No newline at end of file diff --git a/includes/polling/applications/powerdns-recursor.inc.php b/includes/polling/applications/powerdns-recursor.inc.php new file mode 100644 index 0000000000..3307a5d6db --- /dev/null +++ b/includes/polling/applications/powerdns-recursor.inc.php @@ -0,0 +1,126 @@ +. + * + * @package LibreNMS + * @link http://librenms.org + * @copyright 2016 Tony Murray + * @author Tony Murray + */ + +echo ' powerdns-recrusor'; + +global $config; +$data = ''; + +$name = 'powerdns-recursor'; +$app_id = $app['app_id']; +if ($agent_data['app'][$name]) { + $data = $agent_data['app'][$name]; +} elseif (isset($config['apps'][$name]['api-key'])) { + d_echo("\nNo Agent Data. Attempting to connect directly to the powerdns-recursor server " . $device['hostname'] . ":8082\n"); + $context = stream_context_create(array('http' => array('header' => 'X-API-Key: ' . $config['apps'][$name]['api-key']))); + $data = file_get_contents('http://' . $device['hostname'] . ':8082/servers/localhost/statistics', false, $context); +} + +if (!empty($data)) { + $rrd_def = array( + 'all-outqueries' => 'DS:all-outqueries:COUNTER:600:0:U', + 'answers-slow' => 'DS:answers-slow:COUNTER:600:0:U', + 'answers0-1' => 'DS:answers0-1:COUNTER:600:0:U', + 'answers1-10' => 'DS:answers1-10:COUNTER:600:0:U', + 'answers10-100' => 'DS:answers10-100:COUNTER:600:0:U', + 'answers100-1000' => 'DS:answers100-1000:COUNTER:600:0:U', + 'cache-entries' => 'DS:cache-entries:GAUGE:600:0:U', + 'cache-hits' => 'DS:cache-hits:COUNTER:600:0:U', + 'cache-misses' => 'DS:cache-misses:COUNTER:600:0:U', + 'case-mismatches' => 'DS:case-mismatches:COUNTER:600:0:U', + 'chain-resends' => 'DS:chain-resends:COUNTER:600:0:U', + 'client-parse-errors' => 'DS:client-parse-errors:COUNTER:600:0:U', + 'concurrent-queries' => 'DS:concurrent-queries:GAUGE:600:0:U', + 'dlg-only-drops' => 'DS:dlg-only-drops:COUNTER:600:0:U', + 'dont-outqueries' => 'DS:dont-outqueries:COUNTER:600:0:U', + 'edns-ping-matches' => 'DS:edns-ping-matches:COUNTER:600:0:U', + 'edns-ping-mismatches' => 'DS:edns-ping-mismatches:COUNTER:600:0:U', + 'failed-host-entries' => 'DS:failed-host-entries:GAUGE:600:0:U', + 'ipv6-outqueries' => 'DS:ipv6-outqueries:COUNTER:600:0:U', + 'ipv6-questions' => 'DS:ipv6-questions:COUNTER:600:0:U', + 'malloc-bytes' => 'DS:malloc-bytes:GAUGE:600:0:U', + 'max-mthread-stack' => 'DS:max-mthread-stack:GAUGE:600:0:U', + 'negcache-entries' => 'DS:negcache-entries:GAUGE:600:0:U', + 'no-packet-error' => 'DS:no-packet-error:COUNTER:600:0:U', + 'noedns-outqueries' => 'DS:noedns-outqueries:COUNTER:600:0:U', + 'noerror-answers' => 'DS:noerror-answers:COUNTER:600:0:U', + 'noping-outqueries' => 'DS:noping-outqueries:COUNTER:600:0:U', + 'nsset-invalidations' => 'DS:nsset-invalidations:COUNTER:600:0:U', + 'nsspeeds-entries' => 'DS:nsspeeds-entries:GAUGE:600:0:U', + 'nxdomain-answers' => 'DS:nxdomain-answers:COUNTER:600:0:U', + 'outgoing-timeouts' => 'DS:outgoing-timeouts:COUNTER:600:0:U', + 'over-capacity-drops' => 'DS:over-capacity-drops:COUNTER:600:0:U', + 'packetcache-entries' => 'DS:packetcache-entries:GAUGE:600:0:U', + 'packetcache-hits' => 'DS:packetcache-hits:COUNTER:600:0:U', + 'packetcache-misses' => 'DS:packetcache-misses:COUNTER:600:0:U', + 'policy-drops' => 'DS:policy-drops:COUNTER:600:0:U', + 'qa-latency' => 'DS:qa-latency:GAUGE:600:0:U', + 'questions' => 'DS:questions:COUNTER:600:0:U', + 'resource-limits' => 'DS:resource-limits:COUNTER:600:0:U', + 'security-status' => 'DS:security-status:GAUGE:600:0:U', + 'server-parse-errors' => 'DS:server-parse-errors:COUNTER:600:0:U', + 'servfail-answers' => 'DS:servfail-answers:COUNTER:600:0:U', + 'spoof-prevents' => 'DS:spoof-prevents:COUNTER:600:0:U', + 'sys-msec' => 'DS:sys-msec:COUNTER:600:0:U', + 'tcp-client-overflow' => 'DS:tcp-client-overflow:COUNTER:600:0:U', + 'tcp-clients' => 'DS:tcp-clients:GAUGE:600:0:U', + 'tcp-outqueries' => 'DS:tcp-outqueries:COUNTER:600:0:U', + 'tcp-questions' => 'DS:tcp-questions:COUNTER:600:0:U', + 'throttle-entries' => 'DS:throttle-entries:GAUGE:600:0:U', + 'throttled-out' => 'DS:throttled-out:COUNTER:600:0:U', + 'throttled-outqueries' => 'DS:throttled-outquerie:COUNTER:600:0:U', + 'too-old-drops' => 'DS:too-old-drops:COUNTER:600:0:U', + 'unauthorized-tcp' => 'DS:unauthorized-tcp:COUNTER:600:0:U', + 'unauthorized-udp' => 'DS:unauthorized-udp:COUNTER:600:0:U', + 'unexpected-packets' => 'DS:unexpected-packets:COUNTER:600:0:U', + 'unreachables' => 'DS:unreachables:COUNTER:600:0:U', + 'uptime' => 'DS:uptime:COUNTER:600:0:U', + 'user-msec' => 'DS:user-msec:COUNTER:600:0:U', + ); + + //decode and flatten the data + $stats = array(); + foreach (json_decode($data, true) as $stat) { + $stats[$stat['name']] = $stat['value']; + } + d_echo($stats); + + // only the stats we store in rrd + $fields = array(); + foreach ($rrd_def as $key => $value) { + if (isset($stats[$key])) { + $fields[$key] = $stats[$key]; + } else { + $fields[$key] = 'U'; + } + } + + $rrd_name = array('app', 'powerdns', 'recursor', $app_id); + $tags = compact('name', 'app_id', 'rrd_name', 'rrd_def'); + data_update($device, 'app', $tags, $fields); +} + +unset($data, $stats, $rrd_def, $rrd_name, $rrd_keys, $tags, $fields);