123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610 |
- 'use strict';
- require('url');
- require('http');
- var XML = require('pixl-xml');
- var netdata = require('netdata');
- if(netdata.options.DEBUG === true) netdata.debug('loaded', __filename, 'plugin');
- var named = {
- name: __filename,
- enable_autodetect: true,
- update_every: 1,
- base_priority: 60000,
- charts: {},
- chartFromMembersCreate: function(service, obj, id, title_suffix, units, family, context, type, priority, algorithm, multiplier, divisor) {
- var chart = {
- id: id,
- name: '',
- title: service.name + ' ' + title_suffix,
- units: units,
- family: family,
- context: context,
- type: type,
- priority: priority,
- update_every: service.update_every,
- dimensions: {}
- };
- var found = 0;
- var dims = Object.keys(obj);
- var len = dims.length;
- for(var i = 0; i < len ;i++) {
- var x = dims[i];
- if(typeof(obj[x]) !== 'undefined' && obj[x] !== 0) {
- found++;
- chart.dimensions[x] = {
- id: x,
- name: x,
- algorithm: algorithm,
- multiplier: multiplier,
- divisor: divisor,
- hidden: false
- };
- }
- }
- if(!found)
- return null;
- chart = service.chart(id, chart);
- this.charts[id] = chart;
- return chart;
- },
- chartFromMembers: function(service, obj, id_suffix, title_suffix, units, family, context, type, priority, algorithm, multiplier, divisor) {
- var id = 'named_' + service.name + '.' + id_suffix;
- var chart = this.charts[id];
- var dims, len, x, i;
- if(typeof chart === 'undefined') {
- chart = this.chartFromMembersCreate(service, obj, id, title_suffix, units, family, context, type, priority, algorithm, multiplier, divisor);
- if(chart === null) return false;
- }
- else {
-
- dims = Object.keys(obj);
- len = dims.length;
- for(i = 0; i < len ;i++) {
- x = dims[i];
- if(typeof(chart.dimensions[x]) === 'undefined') {
- chart = this.chartFromMembersCreate(service, obj, id, title_suffix, units, family, context, type, priority, algorithm, multiplier, divisor);
- if(chart === null) return false;
- break;
- }
- }
- }
- service.begin(chart);
- var found = 0;
- dims = Object.keys(obj);
- len = dims.length;
- for(i = 0; i < len ;i++) {
- x = dims[i];
- if(typeof(chart.dimensions[x]) !== 'undefined') {
- found++;
- service.set(x, obj[x]);
- }
- }
- service.end();
- return (found > 0);
- },
-
- lookups: {
- nsstats: {},
- resolver_stats: {},
- numfetch: {}
- },
-
-
- xml2js: function(service, data_xml) {
- var d = XML.parse(data_xml);
- if(d === null) return null;
- var a, aa, alen, alen2;
- var data = {};
- var len = d.server.counters.length;
- while(len--) {
- a = d.server.counters[len];
- if(typeof a.counter === 'undefined') continue;
- if(a.type === 'opcode') a.type = 'opcodes';
- else if(a.type === 'qtype') a.type = 'qtypes';
- else if(a.type === 'nsstat') a.type = 'nsstats';
- aa = data[a.type] = {};
- alen = 0;
- alen2 = a.counter.length;
- while(alen < alen2) {
- aa[a.counter[alen].name] = parseInt(a.counter[alen]._Data, 10);
- alen++;
- }
- }
- data.views = {};
- var vlen = d.views.view.length;
- while(vlen--) {
- var vname = d.views.view[vlen].name;
- data.views[vname] = { resolver: {} };
- len = d.views.view[vlen].counters.length;
- while(len--) {
- a = d.views.view[vlen].counters[len];
- if(typeof a.counter === 'undefined') continue;
- if(a.type === 'resstats') a.type = 'stats';
- else if(a.type === 'resqtype') a.type = 'qtypes';
- else if(a.type === 'adbstat') a.type = 'adb';
- aa = data.views[vname].resolver[a.type] = {};
- alen = 0;
- alen2 = a.counter.length;
- while(alen < alen2) {
- aa[a.counter[alen].name] = parseInt(a.counter[alen]._Data, 10);
- alen++;
- }
- }
- }
- return data;
- },
- processResponse: function(service, data) {
- if(data !== null) {
- var r, x, look, id, chart, keys, len;
-
-
- if(service.request.path.match(/^\/xml/) !== null)
- r = named.xml2js(service, data);
- else
- r = JSON.parse(data);
- if(typeof r === 'undefined' || r === null) {
- service.error("Cannot parse these data: " + data.toString());
- return;
- }
- if(service.added !== true)
- service.commit();
- if(typeof r.nsstats !== 'undefined') {
-
- var global_requests = {}, global_requests_enable = false;
- var global_failures = {}, global_failures_enable = false;
- var global_failures_detail = {}, global_failures_detail_enable = false;
- var global_updates = {}, global_updates_enable = false;
- var protocol_queries = {}, protocol_queries_enable = false;
- var global_queries = {}, global_queries_enable = false;
- var global_queries_success = {}, global_queries_success_enable = false;
- var default_enable = false;
- var RecursClients = 0;
-
- if(typeof r.nsstats['RecursClients'] !== 'undefined') {
- RecursClients = r.nsstats['RecursClients'];
- delete r.nsstats['RecursClients'];
- }
- keys = Object.keys(r.nsstats);
- len = keys.length;
- while(len--) {
- x = keys[len];
-
-
- look = named.lookups.nsstats[x];
- if(typeof look === 'undefined') {
-
-
- if(x === 'Requestv4') {
- named.lookups.nsstats[x] = {
- name: 'IPv4',
- type: 'global_requests'
- };
- }
- else if(x === 'Requestv6') {
- named.lookups.nsstats[x] = {
- name: 'IPv6',
- type: 'global_requests'
- };
- }
- else if(x === 'QryFailure') {
- named.lookups.nsstats[x] = {
- name: 'failures',
- type: 'global_failures'
- };
- }
- else if(x === 'QryUDP') {
- named.lookups.nsstats[x] = {
- name: 'UDP',
- type: 'protocol_queries'
- };
- }
- else if(x === 'QryTCP') {
- named.lookups.nsstats[x] = {
- name: 'TCP',
- type: 'protocol_queries'
- };
- }
- else if(x === 'QrySuccess') {
- named.lookups.nsstats[x] = {
- name: 'queries',
- type: 'global_queries_success'
- };
- }
- else if(x.match(/QryRej$/) !== null) {
- named.lookups.nsstats[x] = {
- name: x,
- type: 'global_failures_detail'
- };
- }
- else if(x.match(/^Qry/) !== null) {
- named.lookups.nsstats[x] = {
- name: x,
- type: 'global_queries'
- };
- }
- else if(x.match(/^Update/) !== null) {
- named.lookups.nsstats[x] = {
- name: x,
- type: 'global_updates'
- };
- }
- else {
-
-
- named.lookups.nsstats[x] = {
- name: x,
- type: 'default'
- };
- }
- look = named.lookups.nsstats[x];
-
- }
- switch(look.type) {
- case 'global_requests': global_requests[look.name] = r.nsstats[x]; delete r.nsstats[x]; global_requests_enable = true; break;
- case 'global_queries': global_queries[look.name] = r.nsstats[x]; delete r.nsstats[x]; global_queries_enable = true; break;
- case 'global_queries_success': global_queries_success[look.name] = r.nsstats[x]; delete r.nsstats[x]; global_queries_success_enable = true; break;
- case 'global_updates': global_updates[look.name] = r.nsstats[x]; delete r.nsstats[x]; global_updates_enable = true; break;
- case 'protocol_queries': protocol_queries[look.name] = r.nsstats[x]; delete r.nsstats[x]; protocol_queries_enable = true; break;
- case 'global_failures': global_failures[look.name] = r.nsstats[x]; delete r.nsstats[x]; global_failures_enable = true; break;
- case 'global_failures_detail': global_failures_detail[look.name] = r.nsstats[x]; delete r.nsstats[x]; global_failures_detail_enable = true; break;
- default: default_enable = true; break;
- }
- }
- if(global_requests_enable === true)
- service.module.chartFromMembers(service, global_requests, 'received_requests', 'Bind, Global Received Requests by IP version', 'requests/s', 'requests', 'named.requests', netdata.chartTypes.stacked, named.base_priority + 1, netdata.chartAlgorithms.incremental, 1, 1);
- if(global_queries_success_enable === true)
- service.module.chartFromMembers(service, global_queries_success, 'global_queries_success', 'Bind, Global Successful Queries', 'queries/s', 'queries', 'named.queries_succcess', netdata.chartTypes.line, named.base_priority + 2, netdata.chartAlgorithms.incremental, 1, 1);
- if(protocol_queries_enable === true)
- service.module.chartFromMembers(service, protocol_queries, 'protocols_queries', 'Bind, Global Queries by IP Protocol', 'queries/s', 'queries', 'named.protocol_queries', netdata.chartTypes.stacked, named.base_priority + 3, netdata.chartAlgorithms.incremental, 1, 1);
- if(global_queries_enable === true)
- service.module.chartFromMembers(service, global_queries, 'global_queries', 'Bind, Global Queries Analysis', 'queries/s', 'queries', 'named.global_queries', netdata.chartTypes.stacked, named.base_priority + 4, netdata.chartAlgorithms.incremental, 1, 1);
- if(global_updates_enable === true)
- service.module.chartFromMembers(service, global_updates, 'received_updates', 'Bind, Global Received Updates', 'updates/s', 'updates', 'named.global_updates', netdata.chartTypes.stacked, named.base_priority + 5, netdata.chartAlgorithms.incremental, 1, 1);
- if(global_failures_enable === true)
- service.module.chartFromMembers(service, global_failures, 'query_failures', 'Bind, Global Query Failures', 'failures/s', 'failures', 'named.global_failures', netdata.chartTypes.line, named.base_priority + 6, netdata.chartAlgorithms.incremental, 1, 1);
- if(global_failures_detail_enable === true)
- service.module.chartFromMembers(service, global_failures_detail, 'query_failures_detail', 'Bind, Global Query Failures Analysis', 'failures/s', 'failures', 'named.global_failures_detail', netdata.chartTypes.stacked, named.base_priority + 7, netdata.chartAlgorithms.incremental, 1, 1);
- if(default_enable === true)
- service.module.chartFromMembers(service, r.nsstats, 'nsstats', 'Bind, Other Global Server Statistics', 'operations/s', 'other', 'named.nsstats', netdata.chartTypes.line, named.base_priority + 8, netdata.chartAlgorithms.incremental, 1, 1);
-
- id = 'named_' + service.name + '.recursive_clients';
- chart = named.charts[id];
- if(typeof chart === 'undefined') {
- chart = {
- id: id,
- name: '',
- title: service.name + ' Bind, Current Recursive Clients',
- units: 'clients',
- family: 'clients',
- context: 'named.recursive_clients',
- type: netdata.chartTypes.line,
- priority: named.base_priority + 1,
- update_every: service.update_every,
- dimensions: {
- 'clients': {
- id: 'clients',
- name: '',
- algorithm: netdata.chartAlgorithms.absolute,
- multiplier: 1,
- divisor: 1,
- hidden: false
- }
- }
- };
- chart = service.chart(id, chart);
- named.charts[id] = chart;
- }
- service.begin(chart);
- service.set('clients', RecursClients);
- service.end();
- }
- if(typeof r.opcodes !== 'undefined')
- service.module.chartFromMembers(service, r.opcodes, 'in_opcodes', 'Bind, Global Incoming Requests by OpCode', 'requests/s', 'requests', 'named.in_opcodes', netdata.chartTypes.stacked, named.base_priority + 9, netdata.chartAlgorithms.incremental, 1, 1);
- if(typeof r.qtypes !== 'undefined')
- service.module.chartFromMembers(service, r.qtypes, 'in_qtypes', 'Bind, Global Incoming Requests by Query Type', 'requests/s', 'requests', 'named.in_qtypes', netdata.chartTypes.stacked, named.base_priority + 10, netdata.chartAlgorithms.incremental, 1, 1);
- if(typeof r.sockstats !== 'undefined')
- service.module.chartFromMembers(service, r.sockstats, 'in_sockstats', 'Bind, Global Socket Statistics', 'operations/s', 'sockets', 'named.in_sockstats', netdata.chartTypes.line, named.base_priority + 11, netdata.chartAlgorithms.incremental, 1, 1);
- if(typeof r.views !== 'undefined') {
- keys = Object.keys(r.views);
- len = keys.length;
- while(len--) {
- x = keys[len];
- var resolver = r.views[x].resolver;
- if(typeof resolver !== 'undefined') {
- if(typeof resolver.stats !== 'undefined') {
- var NumFetch = 0;
- var key = service.name + '.' + x;
- var rtt = {}, rtt_enable = false;
- default_enable = false;
-
- if(typeof resolver.stats['NumFetch'] !== 'undefined') {
- named.lookups.numfetch[key] = true;
- NumFetch = resolver.stats['NumFetch'];
- delete resolver.stats['NumFetch'];
- }
- if(typeof resolver.stats['BucketSize'] !== 'undefined') {
- delete resolver.stats['BucketSize'];
- }
-
- var ykeys = Object.keys(resolver.stats);
- var ylen = ykeys.length;
- while(ylen--) {
- var y = ykeys[ylen];
-
-
- look = named.lookups.resolver_stats[y];
- if(typeof look === 'undefined') {
- if(y.match(/^QryRTT/) !== null) {
- named.lookups.resolver_stats[y] = {
- name: y,
- type: 'rtt'
- };
- }
- else {
- named.lookups.resolver_stats[y] = {
- name: y,
- type: 'default'
- };
- }
- look = named.lookups.resolver_stats[y];
-
- }
- switch(look.type) {
- case 'rtt': rtt[look.name] = resolver.stats[y]; delete resolver.stats[y]; rtt_enable = true; break;
- default: default_enable = true; break;
- }
- }
- if(rtt_enable)
- service.module.chartFromMembers(service, rtt, 'view_resolver_rtt_' + x, 'Bind, ' + x + ' View, Resolver Round Trip Timings', 'queries/s', 'view_' + x, 'named.resolver_rtt', netdata.chartTypes.stacked, named.base_priority + 12, netdata.chartAlgorithms.incremental, 1, 1);
- if(default_enable)
- service.module.chartFromMembers(service, resolver.stats, 'view_resolver_stats_' + x, 'Bind, ' + x + ' View, Resolver Statistics', 'operations/s', 'view_' + x, 'named.resolver_stats', netdata.chartTypes.line, named.base_priority + 13, netdata.chartAlgorithms.incremental, 1, 1);
-
- if(typeof named.lookups.numfetch[key] !== 'undefined') {
- id = 'named_' + service.name + '.view_resolver_numfetch_' + x;
- chart = named.charts[id];
- if(typeof chart === 'undefined') {
- chart = {
- id: id,
- name: '',
- title: service.name + ' Bind, ' + x + ' View, Resolver Active Queries',
- units: 'queries',
- family: 'view_' + x,
- context: 'named.resolver_active_queries',
- type: netdata.chartTypes.line,
- priority: named.base_priority + 1001,
- update_every: service.update_every,
- dimensions: {
- 'queries': {
- id: 'queries',
- name: '',
- algorithm: netdata.chartAlgorithms.absolute,
- multiplier: 1,
- divisor: 1,
- hidden: false
- }
- }
- };
- chart = service.chart(id, chart);
- named.charts[id] = chart;
- }
- service.begin(chart);
- service.set('queries', NumFetch);
- service.end();
- }
- }
- }
- if(typeof resolver.qtypes !== 'undefined')
- service.module.chartFromMembers(service, resolver.qtypes, 'view_resolver_qtypes_' + x, 'Bind, ' + x + ' View, Requests by Query Type', 'requests/s', 'view_' + x, 'named.resolver_qtypes', netdata.chartTypes.stacked, named.base_priority + 14, netdata.chartAlgorithms.incremental, 1, 1);
-
-
- if(typeof resolver.cachestats['CacheHits'] !== 'undefined' && resolver.cachestats['CacheHits'] > 0) {
- id = 'named_' + service.name + '.view_resolver_cachehits_' + x;
- chart = named.charts[id];
- if(typeof chart === 'undefined') {
- chart = {
- id: id,
- name: '',
- title: service.name + ' Bind, ' + x + ' View, Resolver Cache Hits',
- units: 'operations/s',
- family: 'view_' + x,
- context: 'named.resolver_cache_hits',
- type: netdata.chartTypes.area,
- priority: named.base_priority + 1100,
- update_every: service.update_every,
- dimensions: {
- 'CacheHits': {
- id: 'CacheHits',
- name: 'hits',
- algorithm: netdata.chartAlgorithms.incremental,
- multiplier: 1,
- divisor: 1,
- hidden: false
- },
- 'CacheMisses': {
- id: 'CacheMisses',
- name: 'misses',
- algorithm: netdata.chartAlgorithms.incremental,
- multiplier: -1,
- divisor: 1,
- hidden: false
- }
- }
- };
- chart = service.chart(id, chart);
- named.charts[id] = chart;
- }
- service.begin(chart);
- service.set('CacheHits', resolver.cachestats['CacheHits']);
- service.set('CacheMisses', resolver.cachestats['CacheMisses']);
- service.end();
- }
-
-
-
-
-
-
-
-
-
-
-
- }
- }
- }
- },
-
-
-
-
- serviceExecute: function(name, a_url, update_every) {
- if(netdata.options.DEBUG === true) netdata.debug(this.name + ': ' + name + ': url: ' + a_url + ', update_every: ' + update_every);
- var service = netdata.service({
- name: name,
- request: netdata.requestFromURL(a_url),
- update_every: update_every,
- module: this
- });
- service.execute(this.processResponse);
- },
- configure: function(config) {
- var added = 0;
- if(this.enable_autodetect === true) {
- this.serviceExecute('local', 'http://localhost:8888/json/v1/server', this.update_every);
- added++;
- }
-
- if(typeof(config.servers) !== 'undefined') {
- var len = config.servers.length;
- while(len--) {
- if(typeof config.servers[len].update_every === 'undefined')
- config.servers[len].update_every = this.update_every;
- this.serviceExecute(config.servers[len].name, config.servers[len].url, config.servers[len].update_every);
- added++;
- }
- }
- return added;
- },
-
-
-
- update: function(service, callback) {
- service.execute(function(serv, data) {
- service.module.processResponse(serv, data);
- callback();
- });
- }
- };
- module.exports = named;
|