Index: html/pages/device/apps/bind.inc.php =================================================================== --- html/pages/device/apps/bind.inc.php (revision 0) +++ html/pages/device/apps/bind.inc.php (revision 0) @@ -0,0 +1,57 @@ + "Server statistics", + 'auth' => "Authoritative", + 'resolv' => "Resolving", + 'queries' => "Queries"); + +print_optionbar_start(); +echo(''.$app["app_type"].' » '); +unset($sep); +foreach ($app_sections as $app_section => $app_section_text) +{ + echo($sep); + if (!$vars['app_section']) { $vars['app_section'] = $app_section; } + if ($vars['app_section'] == $app_section) + { + echo(""); + } + echo(generate_link($app_section_text,$vars,array('app_section'=>$app_section))); + if ($vars['app_section'] == $app_section) { echo(""); } + $sep = " | "; +} +print_optionbar_end(); + +$graphs['stats'] = array('bind_req_in' => "Incoming requests", + 'bind_answers' => "Answers Given", + 'bind_updates' => "Dynamic Updates", + 'bind_req_proto' => "Request protocol details"); + +$graphs['auth'] = array('bind_zone_maint' => "Zone maintenance"); + +$graphs['resolv'] = array('bind_resolv_queries' => "Queries", + 'bind_resolv_errors' => "Errors", + 'bind_resolv_rtt' => "Query RTT", + 'bind_resolv_dnssec' => "DNSSEC validation"); + + +$graphs['queries'] = array('bind_query_rejected' => "Rejected queries", + 'bind_query_in' => "Incoming queries", + 'bind_query_out' => "Outgoing queries"); + +foreach ($graphs[$vars['app_section']] as $key => $text) { + $graph_type = $key; + $graph_array['to'] = $config['time']['now']; + $graph_array['id'] = $app['app_id']; + $graph_array['type'] = "application_".$key; + echo("

".$text."

"); + echo(""); + + include("includes/print-graphrow.inc.php"); + + echo(""); +} + +?> Index: html/includes/graphs/application/bind_resolv_rtt.inc.php =================================================================== --- html/includes/graphs/application/bind_resolv_rtt.inc.php (revision 0) +++ html/includes/graphs/application/bind_resolv_rtt.inc.php (revision 0) @@ -0,0 +1,36 @@ + array('descr' => "< 10ms", 'colour' => '00d200'), + 'QryRTT100' => array('descr' => "10-100ms", 'colour' => '26ac00'), + 'QryRTT500' => array('descr' => "100-500ms", 'colour' => '498900'), + 'QryRTT800' => array('descr' => "500-800ms", 'colour' => '894900'), + 'QryRTT1600' => array('descr' => "800-1600ms", 'colour' => 'ac2600'), + 'QryRTT1600plus' => array('descr' => "> 1600ms", 'colour' => 'd20000'), +); +$i = 0; + +if (is_file($rrd_filename)) +{ + foreach ($array as $ds => $data) + { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $data['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $data['colour']; + $i++; + } +} else { + echo("file missing: $file"); +} + +include("includes/graphs/generic_multi.inc.php"); + +?> Index: html/includes/graphs/application/bind_answers.inc.php =================================================================== --- html/includes/graphs/application/bind_answers.inc.php (revision 0) +++ html/includes/graphs/application/bind_answers.inc.php (revision 0) @@ -0,0 +1,42 @@ + array('descr' => "Responses sent", 'colour' => '999999'), + 'QrySuccess' => array('descr' => "Successful answers", 'colour' => '33cc33'), + 'QryAuthAns' => array('descr' => "Authoritative answer", 'colour' => '009900'), + 'QryNoauthAns' => array('descr' => "Non-authoritative answer", 'colour' => '336633'), + 'QryReferral' => array('descr' => "Referral answer", 'colour' => '996633'), + 'QryNxrrset' => array('descr' => "Empty answers", 'colour' => '36393d'), + 'QrySERVFAIL' => array('descr' => "SERVFAIL answer", 'colour' => 'ff3333'), + 'QryFORMERR' => array('descr' => "FORMERR answer", 'colour' => 'ffcccc'), + 'QryNXDOMAIN' => array('descr' => "NXDOMAIN answers", 'colour' => 'ff33ff'), + 'QryDropped' => array('descr' => "Dropped queries", 'colour' => '666666'), + 'QryFailure' => array('descr' => "Failed queries", 'colour' => 'ff0000'), + 'XfrReqDone' => array('descr' => "Transfers completed", 'colour' => '6666ff'), +); +$i = 0; + +if (is_file($rrd_filename)) +{ + foreach ($array as $ds => $data) + { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $data['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $data['colour']; + $i++; + } +} else { + echo("file missing: $file"); +} + +include("includes/graphs/generic_multi_line.inc.php"); + +?> Index: html/includes/graphs/application/bind_zone_maint.inc.php =================================================================== --- html/includes/graphs/application/bind_zone_maint.inc.php (revision 0) +++ html/includes/graphs/application/bind_zone_maint.inc.php (revision 0) @@ -0,0 +1,43 @@ + array('descr' => "Notifies sent IPv4", 'colour' => '87cefa'), + 'NotifyOutv6' => array('descr' => "Notifies sent IPv6", 'colour' => '00bfff'), + 'NotifyInv4' => array('descr' => "Notifies received IPv4", 'colour' => '3cb371'), + 'NotifyInv6' => array('descr' => "Notifies received IPv6", 'colour' => '2e8b57'), + 'NotifyRej' => array('descr' => "Notifies rejected", 'colour' => 'ff8c00'), + 'SOAOutv4' => array('descr' => "SOA queries sent IPv4", 'colour' => 'daa520'), + 'SOAOutv6' => array('descr' => "SOA queries sent IPv6", 'colour' => 'b8860b'), + 'AXFRReqv4' => array('descr' => "AXFR requested IPv4", 'colour' => 'da70d6'), + 'AXFRReqv6' => array('descr' => "AXFR requested IPv6", 'colour' => '9932cc'), + 'IXFRReqv4' => array('descr' => "IXFR requested IPv4", 'colour' => 'ff69b4'), + 'IXFRReqv6' => array('descr' => "IXFR requested IPv6", 'colour' => 'ff1493'), + 'XfrSuccess' => array('descr' => "Successful transfer", 'colour' => '32cd32'), + 'XfrFail' => array('descr' => "Failed transfer", 'colour' => 'ff0000'), +); +$i = 0; + +if (is_file($rrd_filename)) +{ + foreach ($array as $ds => $data) + { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $data['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $data['colour']; + $i++; + } +} else { + echo("file missing: $file"); +} + +include("includes/graphs/generic_multi_line.inc.php"); + +?> Index: html/includes/graphs/application/bind_updates.inc.php =================================================================== --- html/includes/graphs/application/bind_updates.inc.php (revision 0) +++ html/includes/graphs/application/bind_updates.inc.php (revision 0) @@ -0,0 +1,37 @@ + array('descr' => "Completed", 'colour' => '228b22'), + 'UpdateFail' => array('descr' => "Failed", 'colour' => 'ff0000'), + 'UpdateRej' => array('descr' => "Rejected", 'colour' => 'cd853f'), + 'UpdateBadPrereq' => array('descr' => "Rejected due to prereq fail", 'colour' => 'ff8c00'), + 'UpdateReqFwd' => array('descr' => "Fwd request", 'colour' => '6495ed'), + 'UpdateRespFwd' => array('descr' => "Fwd response", 'colour' => '40e0d0'), + 'UpdateFwdFail' => array('descr' => "Fwd failed", 'colour' => 'ffd700'), +); +$i = 0; + +if (is_file($rrd_filename)) +{ + foreach ($array as $ds => $data) + { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $data['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $data['colour']; + $i++; + } +} else { + echo("file missing: $file"); +} + +include("includes/graphs/generic_multi.inc.php"); + +?> Index: html/includes/graphs/application/bind_resolv_queries.inc.php =================================================================== --- html/includes/graphs/application/bind_resolv_queries.inc.php (revision 0) +++ html/includes/graphs/application/bind_resolv_queries.inc.php (revision 0) @@ -0,0 +1,39 @@ + array('descr' => "Queries sent IPv4", 'colour' => '87cefa'), + 'Responsev4' => array('descr' => "Responses received IPv4", 'colour' => '00bfff'), + 'Queryv6' => array('descr' => "Queries sent IPv6", 'colour' => 'ff69b4'), + 'Responsev6' => array('descr' => "Responses received IPv6", 'colour' => 'ff1493'), + 'NXDOMAIN' => array('descr' => "NXDOMAIN received", 'colour' => 'ffa07a', 'invert' => True), + 'SERVFAIL' => array('descr' => "SERVFAIL received", 'colour' => 'ff6533', 'invert' => True), + 'FORMERR' => array('descr' => "FORMERR received", 'colour' => 'ff8c00', 'invert' => True), + 'OtherError' => array('descr' => "Other error received", 'colour' => 'ff0000', 'invert' => True), +); +$i = 0; + +if (is_file($rrd_filename)) +{ + foreach ($array as $ds => $data) + { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $data['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $data['colour']; + $rrd_list[$i]['invert'] = $data['invert']; + $i++; + } +} else { + echo("file missing: $file"); +} + +include("includes/graphs/generic_multi_line.inc.php"); + +?> Index: html/includes/graphs/application/bind_query_out.inc.php =================================================================== --- html/includes/graphs/application/bind_query_out.inc.php (revision 0) +++ html/includes/graphs/application/bind_query_out.inc.php (revision 0) @@ -0,0 +1,37 @@ + $rrtype); +} +$i = 0; + +if (is_file($rrd_filename)) +{ + foreach ($array as $ds => $data) + { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $data['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['invert'] = in_array($data['descr'], $inverted); + $i++; + } +} else { + echo("file missing: $file"); +} + +#include("includes/graphs/generic_multi_line.inc.php"); +include("includes/graphs/generic_multi.inc.php"); + +?> Index: html/includes/graphs/application/bind_req_proto.inc.php =================================================================== --- html/includes/graphs/application/bind_req_proto.inc.php (revision 0) +++ html/includes/graphs/application/bind_req_proto.inc.php (revision 0) @@ -0,0 +1,41 @@ + array('descr' => "IPv4 requests", 'colour' => '006600'), + 'Requestv6' => array('descr' => "IPv6 requests", 'colour' => '66cc66'), + 'ReqEdns0' => array('descr' => "EDNS(0) requests", 'colour' => '9999ff'), + 'RespEDNS0' => array('descr' => "EDNS(0) responses", 'colour' => '6666ff'), + 'ReqTSIG' => array('descr' => "TSIG requests", 'colour' => 'ff9999'), + 'RespTSIG' => array('descr' => "TSIG responses", 'colour' => 'ff6666'), + 'ReqSIG0' => array('descr' => "SIG(0) requests", 'colour' => 'da70d6'), + 'RespSIG0' => array('descr' => "responses with SIG(0) sent", 'colour' => '9932cc'), + 'ReqTCP' => array('descr' => "TCP requests", 'colour' => 'ffd700'), + 'Response' => array('descr' => "Responses sent", 'colour' => '999999'), + 'TruncatedResp' => array('descr' => "Truncated Responses", 'colour' => 'ff0000'), +); +$i = 0; + +if (is_file($rrd_filename)) +{ + foreach ($array as $ds => $data) + { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $data['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $data['colour']; + $i++; + } +} else { + echo("file missing: $file"); +} + +include("includes/graphs/generic_multi_line.inc.php"); + +?> Index: html/includes/graphs/application/bind_query_in.inc.php =================================================================== --- html/includes/graphs/application/bind_query_in.inc.php (revision 0) +++ html/includes/graphs/application/bind_query_in.inc.php (revision 0) @@ -0,0 +1,37 @@ + $rrtype); +} +$i = 0; + +if (is_file($rrd_filename)) +{ + foreach ($array as $ds => $data) + { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $data['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['invert'] = in_array($data['descr'], $inverted); + $i++; + } +} else { + echo("file missing: $file"); +} + +#include("includes/graphs/generic_multi_line.inc.php"); +include("includes/graphs/generic_multi.inc.php"); + +?> Index: html/includes/graphs/application/bind_resolv_errors.inc.php =================================================================== --- html/includes/graphs/application/bind_resolv_errors.inc.php (revision 0) +++ html/includes/graphs/application/bind_resolv_errors.inc.php (revision 0) @@ -0,0 +1,38 @@ + array('descr' => "EDNS(0) query failures", 'colour' => '87cefa'), + 'Mismatch' => array('descr' => "Mismatch responses received", 'colour' => '00bfff'), + 'Truncated' => array('descr' => "Truncated responses received", 'colour' => 'ff69b4'), + 'Lame' => array('descr' => "Lame delegations received", 'colour' => 'ff1493'), + 'Retry' => array('descr' => "Retried queries", 'colour' => 'ffa07a'), + 'QueryAbort' => array('descr' => "Aborted due to quota", 'colour' => 'ff6533'), + 'QuerySockFail' => array('descr' => "Socket errors", 'colour' => 'ff8c00'), + 'QueryTimeout' => array('descr' => "Timeouts", 'colour' => 'ff0000'), +); +$i = 0; + +if (is_file($rrd_filename)) +{ + foreach ($array as $ds => $data) + { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $data['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $data['colour']; + $i++; + } +} else { + echo("file missing: $file"); +} + +include("includes/graphs/generic_multi_line.inc.php"); + +?> Index: html/includes/graphs/application/bind_resolv_dnssec.inc.php =================================================================== --- html/includes/graphs/application/bind_resolv_dnssec.inc.php (revision 0) +++ html/includes/graphs/application/bind_resolv_dnssec.inc.php (revision 0) @@ -0,0 +1,35 @@ + array('descr' => "Attempted validation", 'colour' => '4242CC', 'invert' => True), + 'ValOk' => array('descr' => "Succeeded validation", 'colour' => '33A533'), + 'ValNegOk' => array('descr' => "NX Succeeded validation", 'colour' => 'FFA500'), + 'ValFail' => array('descr' => "Failed validation", 'colour' => 'ff0000'), +); +$i = 0; + +if (is_file($rrd_filename)) +{ + foreach ($array as $ds => $data) + { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $data['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $data['colour']; + $rrd_list[$i]['invert'] = $data['invert']; + $i++; + } +} else { + echo("file missing: $file"); +} + +include("includes/graphs/generic_multi.inc.php"); + +?> Index: html/includes/graphs/application/bind_query_rejected.inc.php =================================================================== --- html/includes/graphs/application/bind_query_rejected.inc.php (revision 0) +++ html/includes/graphs/application/bind_query_rejected.inc.php (revision 0) @@ -0,0 +1,35 @@ + array('descr' => "Auth queries rejected", 'colour' => '6495ed'), + 'RecQryRej' => array('descr' => "Recursive queries rejected", 'colour' => '40e0d0'), + 'XfrRej' => array('descr' => "Transfer requests rejected", 'colour' => 'ffd700'), + 'UpdateRej' => array('descr' => "Update requests rejected", 'colour' => 'cd853f'), + 'UpdateBadPrereq' => array('descr' => "Updates rejected due to prereq fail", 'colour' => 'ff8c00'), +); +$i = 0; + +if (is_file($rrd_filename)) +{ + foreach ($array as $ds => $data) + { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $data['descr']; + $rrd_list[$i]['ds'] = $ds; + $rrd_list[$i]['colour'] = $data['colour']; + $i++; + } +} else { + echo("file missing: $file"); +} + +include("includes/graphs/generic_multi.inc.php"); + +?> Index: html/includes/graphs/application/bind_req_in.inc.php =================================================================== --- html/includes/graphs/application/bind_req_in.inc.php (revision 0) +++ html/includes/graphs/application/bind_req_in.inc.php (revision 0) @@ -0,0 +1,33 @@ + array('descr' => 'Query'), + 'status' => array('descr' => 'Status'), + 'notify' => array('descr' => 'Notify'), + 'update' => array('descr' => 'Update'), + ); +$i = 0; + +if (is_file($rrd_filename)) +{ + foreach ($array as $ds => $data) + { + $rrd_list[$i]['filename'] = $rrd_filename; + $rrd_list[$i]['descr'] = $data['descr']; + $rrd_list[$i]['ds'] = $ds; + $i++; + } +} else { + echo("file missing: $file"); +} + +include("includes/graphs/generic_multi_line.inc.php"); + +?> Index: includes/polling/applications/bind.inc.php =================================================================== --- includes/polling/applications/bind.inc.php (revision 0) +++ includes/polling/applications/bind.inc.php (revision 0) @@ -0,0 +1,359 @@ + 0, + 'STATUS' => 0, + 'NOTIFY' => 0, + 'UPDATE' => 0, + ); + + # Query incoming + $query_in = array(); + foreach ($rrtypes as $rrtype) + { + $query_in[$rrtype] = 0; + } + + # Query outgoing + $query_out = array(); + + # Name server statistics + $ns_stats_field_mapping = array( + "IPv4 requests received" => 'Requestv4', + "IPv6 requests received" => 'Requestv6', + "requests with EDNS(0) received" => 'ReqEdns0', + "requests with unsupported EDNS version received" => 'ReqBadEDNSVer', + "requests with TSIG received" => 'ReqTSIG', + "requests with SIG(0) received" => 'ReqSIG0', + "requests with invalid signature" => 'ReqBadSIG', + "TCP requests received" => 'ReqTCP', + "auth queries rejected" => 'AuthQryRej', + "recursive queries rejected" => 'RecQryRej', + "transfer requests rejected" => 'XfrRej', + "update requests rejected" => 'UpdateRej', + "responses sent" => 'Response', + "truncated responses sent" => 'TruncatedResp', + "responses with EDNS(0) sent" => 'RespEDNS0', + "responses with TSIG sent" => 'RespTSIG', + "responses with SIG(0) sent" => 'RespSIG0', + "queries resulted in successful answer" => 'QrySuccess', + "queries resulted in authoritative answer" => 'QryAuthAns', + "queries resulted in non authoritative answer" => 'QryNoauthAns', + "queries resulted in referral answer" => 'QryReferral', + "queries resulted in nxrrset" => 'QryNxrrset', + "queries resulted in SERVFAIL" => 'QrySERVFAIL', + "queries resulted in FORMERR" => 'QryFORMERR', + "queries resulted in NXDOMAIN" => 'QryNXDOMAIN', + "queries caused recursion" => 'QryRecursion', + "duplicate queries received" => 'QryDuplicate', + "queries dropped" => 'QryDropped', + "other query failures" => 'QryFailure', + "requested transfers completed" => 'XfrReqDone', + "update requests forwarded" => 'UpdateReqFwd', + "update responses forwarded" => 'UpdateRespFwd', + "update forward failed" => 'UpdateFwdFail', + "updates completed" => 'UpdateDone', + "updates failed" => 'UpdateFail', + "updates rejected due to prerequisite failure" => 'UpdateBadPrereq', + "response policy zone rewrites" => 'RPZRewrites', + ); + + $ns_stats_fields = array_values($ns_stats_field_mapping); + array_sort($ns_stats_fields); + + $ns_stats = array(); + foreach ($ns_stats_fields as $field) + { + $ns_stats[$field] = 0; + } + + # Zone maintenance + $zone_maint_field_mapping = array( + "IPv4 notifies sent" => 'NotifyOutv4', + "IPv6 notifies sent" => 'NotifyOutv6', + "IPv4 notifies received" => 'NotifyInv4', + "IPv6 notifies received" => 'NotifyInv6', + "notifies rejected" => 'NotifyRej', + "IPv4 SOA queries sent" => 'SOAOutv4', + "IPv6 SOA queries sent" => 'SOAOutv6', + "IPv4 AXFR requested" => 'AXFRReqv4', + "IPv6 AXFR requested" => 'AXFRReqv6', + "IPv4 IXFR requested" => 'IXFRReqv4', + "IPv6 IXFR requested" => 'IXFRReqv6', + "transfer requests succeeded" => 'XfrSuccess', + "transfer requests failed" => 'XfrFail', + ); + + $zone_maint_fields = array_values($zone_maint_field_mapping); + array_sort($zone_maint_fields); + + $zone_maint = array(); + foreach ($zone_maint_fields as $field) + { + $zone_maint[$field] = 0; + } + + # Resolver + $resolver_field_mapping = array( + "IPv4 queries sent" => 'Queryv4', + "IPv6 queries sent" => 'Queryv6', + "IPv4 responses received" => 'Responsev4', + "IPv6 responses received" => 'Responsev6', + "NXDOMAIN received" => 'NXDOMAIN', + "SERVFAIL received" => 'SERVFAIL', + "FORMERR received" => 'FORMERR', + "other errors received" => 'OtherError', + "EDNS(0) query failures" => 'EDNS0Fail', + "mismatch responses received" => 'Mismatch', + "truncated responses received" => 'Truncated', + "lame delegations received" => 'Lame', + "query retries" => 'Retry', + "queries aborted due to quota" => 'QueryAbort', + "failures in opening query sockets" => 'QuerySockFail', + "query timeouts" => 'QueryTimeout', + "IPv4 NS address fetches" => 'GlueFetchv4', + "IPv6 NS address fetches" => 'GlueFetchv6', + "IPv4 NS address fetch failed" => 'GlueFetchv4Fail', + "IPv6 NS address fetch failed" => 'GlueFetchv6Fail', + "DNSSEC validation attempted" => 'ValAttempt', + "DNSSEC validation succeeded" => 'ValOk', + "DNSSEC NX validation succeeded" => 'ValNegOk', + "DNSSEC validation failed" => 'ValFail', + "queries with RTT < 10ms" => 'QryRTT10', + "queries with RTT 10-100ms" => 'QryRTT100', + "queries with RTT 100-500ms" => 'QryRTT500', + "queries with RTT 500-800ms" => 'QryRTT800', + "queries with RTT 800-1600ms" => 'QryRTT1600', + "queries with RTT > 1600ms" => 'QryRTT1600plus', + ); + + $resolver_fields = array_values($resolver_field_mapping); + array_sort($resolver_fields); + + $resolver = array(); + + # Store the data in arrays + # ------------------------ + $lines = explode("\n", $agent_data['app']['bind']['global']); + foreach ($lines as $line) { + # Line format is "key:value" + list ($key, $value) = explode(':', $line); + + # Keys consist of "section,subkey" + list ($section, $subkey) = explode(',', $key, 2); + + # The subkey depends on the section + if ($section == 'req-in') + { + # Subkey is the opcode + $req_in[$subkey] = (int) $value; + } + elseif ($section == 'query-in') + { + # Subkey is the RRType + $query_in[$subkey] = (int) $value; + } + elseif ($section == 'ns-stats') + { + # Subkey is description + if (isset($ns_stats_field_mapping[$subkey])) + { + $subkey = $ns_stats_field_mapping[$subkey]; + } + $ns_stats[$subkey] = (int) $value; + } + elseif ($section == 'zone-maint') + { + # Subkey is description + if (isset($zone_maint_field_mapping[$subkey])) + { + $subkey = $zone_maint_field_mapping[$subkey]; + } + $zone_maint[$subkey] = (int) $value; + } + } + + # Done with the global stuff + unset($agent_data['app']['bind']['global']); + + # The rest is views + foreach ($agent_data['app']['bind'] as $view => $view_data) + { + $lines = explode("\n", $agent_data['app']['bind'][$view]); + foreach ($lines as $line) { + # Line format is "key:value" + list ($key, $value) = explode(':', $line); + + # Keys consist of "section,subkey" + list ($section, $subkey) = explode(',', $key, 2); + + # The subkey depends on the section + if ($section == 'query-out') + { + # Create the view if it doesn't exist yet + if (!isset($query_out[$view])) + { + foreach ($rrtypes as $rrtype) + { + $query_out[$view][$rrtype] = 0; + } + } + + # Subkey is the RRType + $query_out[$view][$subkey] = (int) $value; + } + elseif ($section == 'resolver') + { + # Create the view if it doesn't exist yet + if (!isset($resolver[$view])) + { + foreach ($resolver_fields as $field) + { + $resolver[$view][$field] = 0; + } + } + + # Subkey is the description + if (isset($resolver_field_mapping[$subkey])) + { + $subkey = $resolver_field_mapping[$subkey]; + } + $resolver[$view][$subkey] = (int) $value; + } + } + } + + # Use the data from the arrays to build RRDs + # ------------------------------------------ + + # rrdcreate list of rrtypes + $rrdcreate_rrtypes = ""; + foreach ($rrtypes as $rrtype) + { + $rrdcreate_rrtypes .= " DS:$rrtype:DERIVE:600:0:7500000"; + } + + # req-in + $rrd_filename = $config['rrd_dir'] . "/" . $device['hostname'] . "/app-bind-".$app['app_id']."-req-in.rrd"; + + if (!is_file($rrd_filename)) + { + rrdtool_create($rrd_filename, "--step 300 \ + DS:query:DERIVE:600:0:7500000 \ + DS:status:DERIVE:600:0:7500000 \ + DS:notify:DERIVE:600:0:7500000 \ + DS:update:DERIVE:600:0:7500000 ".$config['rrd_rra']); + } + + rrdtool_update($rrd_filename, "N:$req_in[QUERY]:$req_in[STATUS]:$req_in[NOTIFY]:$req_in[UPDATE]"); + + # query-in + $rrd_filename = $config['rrd_dir'] . "/" . $device['hostname'] . "/app-bind-".$app['app_id']."-query-in.rrd"; + + if (!is_file($rrd_filename)) + { + rrdtool_create($rrd_filename, "--step 300 $rrdcreate_rrtypes ".$config['rrd_rra']); + } + + $rrd_data = ""; + foreach ($rrtypes as $rrtype) + { + $rrd_data .= ":".$query_in[$rrtype]; + } + rrdtool_update($rrd_filename, "N".$rrd_data); + + # ns-stats + $rrd_filename = $config['rrd_dir'] . "/" . $device['hostname'] . "/app-bind-".$app['app_id']."-ns-stats.rrd"; + + if (!is_file($rrd_filename)) + { + # rrdcreate list of fields + $rrdcreate_ns_stats = ""; + foreach ($ns_stats_fields as $field) + { + $rrdcreate_ns_stats .= " DS:$field:DERIVE:600:0:7500000"; + } + rrdtool_create($rrd_filename, "--step 300 $rrdcreate_ns_stats ".$config['rrd_rra']); + } + + $rrd_data = ""; + foreach ($ns_stats_fields as $field) + { + $rrd_data .= ":".$ns_stats[$field]; + } + rrdtool_update($rrd_filename, "N".$rrd_data); + + # zone-maint + $rrd_filename = $config['rrd_dir'] . "/" . $device['hostname'] . "/app-bind-".$app['app_id']."-zone-maint.rrd"; + + if (!is_file($rrd_filename)) + { + # rrdcreate list of fields + $rrdcreate_zone_maint = ""; + foreach ($zone_maint_fields as $field) + { + $rrdcreate_zone_maint .= " DS:$field:DERIVE:600:0:7500000"; + } + rrdtool_create($rrd_filename, "--step 300 $rrdcreate_zone_maint ".$config['rrd_rra']); + } + + $rrd_data = ""; + foreach ($zone_maint_fields as $field) + { + $rrd_data .= ":".$zone_maint[$field]; + } + rrdtool_update($rrd_filename, "N".$rrd_data); + + # query-out + foreach ($query_out as $view => $view_data) + { + $rrd_filename = $config['rrd_dir'] . "/" . $device['hostname'] . "/app-bind-".$app['app_id']."-query-out-".$view.".rrd"; + + if (!is_file($rrd_filename)) + { + rrdtool_create($rrd_filename, "--step 300 $rrdcreate_rrtypes ".$config['rrd_rra']); + } + + $rrd_data = ""; + foreach ($rrtypes as $rrtype) + { + $rrd_data .= ":".$view_data[$rrtype]; + } + rrdtool_update($rrd_filename, "N".$rrd_data); + } + + # resolver + foreach ($resolver as $view => $view_data) + { + $rrd_filename = $config['rrd_dir'] . "/" . $device['hostname'] . "/app-bind-".$app['app_id']."-resolver-".$view.".rrd"; + + if (!is_file($rrd_filename)) + { + # rrdcreate list of fields + $rrdcreate_resolver = ""; + foreach ($resolver_fields as $field) + { + $rrdcreate_resolver .= " DS:$field:DERIVE:600:0:7500000"; + } + rrdtool_create($rrd_filename, "--step 300 $rrdcreate_resolver ".$config['rrd_rra']); + } + + $rrd_data = ""; + foreach ($resolver_fields as $field) + { + $rrd_data .= ":".$view_data[$field]; + } + rrdtool_update($rrd_filename, "N".$rrd_data); + } +} + +?> Index: includes/definitions.inc.php =================================================================== --- includes/definitions.inc.php (revision 4326) +++ includes/definitions.inc.php (working copy) @@ -1529,6 +1529,19 @@ $config['graph_descr']['application_unbound_rcode'] = "Answers sorted by return value. RRSets bogus is the number of RRSets marked bogus per second by the validator."; $config['graph_descr']['application_unbound_flags'] = "This graphs plots the flags inside incoming queries. For example, if QR, AA, TC, RA, Z flags are set, the query can be rejected. RD, AD, CD and DO are legitimately set by some software."; +$config['graph_types']['application']['bind_answers']['descr'] = 'BIND Received Answers'; +$config['graph_types']['application']['bind_query_in']['descr'] = 'BIND Incoming Queries'; +$config['graph_types']['application']['bind_query_out']['descr'] = 'BIND Outgoing Queries'; +$config['graph_types']['application']['bind_query_rejected']['descr'] = 'BIND Rejected Queries'; +$config['graph_types']['application']['bind_req_in']['descr'] = 'BIND Incoming Requests'; +$config['graph_types']['application']['bind_req_proto']['descr'] = 'BIND Request Protocol Details'; +$config['graph_types']['application']['bind_resolv_dnssec']['descr'] = 'BIND DNSSEC Validation'; +$config['graph_types']['application']['bind_resolv_errors']['descr'] = 'BIND Errors while Resolving'; +$config['graph_types']['application']['bind_resolv_queries']['descr'] = 'BIND Resolving Queries'; +$config['graph_types']['application']['bind_resolv_rtt']['descr'] = 'BIND Resolving RTT'; +$config['graph_types']['application']['bind_updates']['descr'] = 'BIND Dynamic Updates'; +$config['graph_types']['application']['bind_zone_maint']['descr'] = 'BIND Zone Maintenance'; + // Device Types $i = 0; Index: scripts/agent-local/bind =================================================================== --- scripts/agent-local/bind (revision 0) +++ scripts/agent-local/bind (revision 0) @@ -0,0 +1,173 @@ +#!/bin/bash + +STATS_FILE=/var/cache/bind/named.stats + +# Remove old stats file +rm -f $STATS_FILE + +# Generate new stats +/usr/sbin/rndc stats + +# Delay until the stats file is written +i=0 +while [ ! -f $STATS_FILE ]; do + # We don't wait forever + if [ $i -ge 10 ]; then + exit 1 + fi + i=$[ $i + 1 ] + + # Wait a little + sleep 0.2 +done + +# Save view specific stuff +declare -A VIEWS +VIEWS[global]="" + +# Read the stats file and parse it +MODE="unknown" +while read LINE; do + if [[ "$LINE" =~ ^-- ]]; then + # Statistics, skip this line + continue + elif [[ "$LINE" =~ ^\+\+ ]]; then + # This is a section start, switch mode + if [ "$LINE" == "++ Incoming Requests ++" ]; then + MODE="req-in" + elif [ "$LINE" == "++ Incoming Queries ++" ]; then + MODE="query-in" + elif [ "$LINE" == "++ Outgoing Queries ++" ]; then + MODE="query-out" + VIEW="default" + elif [ "$LINE" == "++ Name Server Statistics ++" ]; then + MODE="ns-stats" + elif [ "$LINE" == "++ Zone Maintenance Statistics ++" ]; then + MODE="zone-maint" + elif [ "$LINE" == "++ Resolver Statistics ++" ]; then + MODE="resolver" + VIEW="default" + elif [ "$LINE" == "++ Cache DB RRsets ++" ]; then + MODE="cache" + VIEW="default" + elif [ "$LINE" == "++ Per Zone Query Statistics ++" ]; then + MODE="zone" + VIEW="default" + ZONE="unknown" + else + MODE="unknown" + fi + + continue + fi + + # Parse based on current mode + if [ "$MODE" == "req-in" ]; then + # Line format is: + read REQ_COUNT REQ_OPCODE <<< $( echo $LINE ) + VIEWS[global]+="req-in,$REQ_OPCODE:$REQ_COUNT"$'\n' + elif [ "$MODE" == "query-in" ]; then + # Line format is: + read QUERY_COUNT QUERY_RRTYPE <<< $( echo $LINE ) + VIEWS[global]+="query-in,$QUERY_RRTYPE:$QUERY_COUNT"$'\n' + elif [ "$MODE" == "query-out" ]; then + # Is this a section? + if [[ "$LINE" =~ ^\[ ]]; then + # Is this a view start? + NEW_VIEW=$( echo "$LINE" | sed -n 's/^\[View: \(.*\)\]$/\1/p' ) + if [ -n "$NEW_VIEW" ]; then + VIEW="$NEW_VIEW" + fi + + continue + fi + + # Ignore the _bind view + if [ "$VIEW" == "_bind" ]; then + continue + fi + + # Line format is: + read QUERY_COUNT QUERY_RRTYPE <<< $( echo $LINE ) + VIEWS[$VIEW]+="query-out,$QUERY_RRTYPE:$QUERY_COUNT"$'\n' + elif [ "$MODE" == "ns-stats" ]; then + # Line format is: + read COUNT ACTION <<< $( echo $LINE ) + VIEWS[global]+="ns-stats,$ACTION:$COUNT"$'\n' + elif [ "$MODE" == "zone-maint" ]; then + # Line format is: + read COUNT ACTION <<< $( echo $LINE ) + VIEWS[global]+="zone-maint,$ACTION:$COUNT"$'\n' + elif [ "$MODE" == "resolver" ]; then + # Is this a section? + if [[ "$LINE" =~ ^\[ ]]; then + # Is this a view start? + NEW_VIEW=$( echo "$LINE" | sed -n 's/^\[View: \(.*\)\]$/\1/p' ) + if [ -n "$NEW_VIEW" ]; then + VIEW="$NEW_VIEW" + fi + + continue + fi + + # Ignore the _bind view + if [ "$VIEW" == "_bind" ]; then + continue + fi + + # Line format is: + read COUNT ACTION <<< $( echo $LINE ) + VIEWS[$VIEW]+="resolver,$ACTION:$COUNT"$'\n' + elif [ "$MODE" == "cache" ]; then + # Is this a section? + if [[ "$LINE" =~ ^\[ ]]; then + # Is this a view start? + NEW_VIEW=$( echo "$LINE" | sed -n 's/^\[View: \(.*\)\]$/\1/p' ) + if [ -n "$NEW_VIEW" ]; then + VIEW="$NEW_VIEW" + fi + + continue + fi + + # Ignore the _bind view + if [ "$VIEW" == "_bind" ]; then + continue + fi + + # Line format is: + read COUNT ACTION <<< $( echo $LINE ) + VIEWS[$VIEW]+="cache,$ACTION:$COUNT"$'\n' + elif [ "$MODE" == "zone" ]; then + # Is this a section? + if [[ "$LINE" =~ ^\[ ]]; then + # Does this line define a view? + NEW_VIEW=$( echo "$LINE" | sed -n 's/^.* (view: \(.*\))\]$/\1/p' ) + if [ -n "$NEW_VIEW" ]; then + VIEW="$NEW_VIEW" + fi + + # Is this a zone start? + NEW_ZONE=$( echo "$LINE" | sed -n 's/^\[\([^] ]*\).*/\1/p' ) + if [ -n "$NEW_ZONE" ]; then + ZONE="$NEW_ZONE" + fi + + continue + fi + + # Ignore the _bind view + if [ "$VIEW" == "_bind" ]; then + continue + fi + + # Line format is: + read COUNT ACTION <<< $( echo $LINE ) + VIEWS[$VIEW]+="$ZONE,$ACTION:$COUNT"$'\n' + fi +done < $STATS_FILE + +for VIEW in "${!VIEWS[@]}"; do + echo "<<>>" + echo -n "${VIEWS[$VIEW]}" +done Property changes on: scripts/agent-local/bind ___________________________________________________________________ Added: svn:executable + *