@cryptotaxi247 / netdata-1 / commits / d9e4b8c44

snmp now supports max request size, also can retreive chart titles and dimension names from snmp values

Costa Tsaousis (ktsaou) committed Feb 18, 2016 at 00:57 UTC d9e4b8c4470a3f36d4a87e3583454cf0e98cf7cb
1 file changed +122 -34
node.d/snmp.node.js
+122 -34
@@ -7,11 +7,13 @@
7 {
8 "enable_autodetect": false,
9 "update_every": 5,
10 + "max_request_size": 50,
11 "servers": [
12 {
13 "hostname": "10.11.12.8",
14 "community": "public",
15 "update_every": 10,
16 + "max_request_size": 50,
17 "options": { "timeout": 10000 },
18 "charts": {
19 "snmp_switch.bandwidth_port1": {
@@ -67,11 +69,13 @@
69 {
70 "enable_autodetect": false,
71 "update_every": 10,
72 + "max_request_size": 50,
73 "servers": [
74 {
75 "hostname": "10.11.12.8",
76 "community": "public",
77 "update_every": 10,
78 + "max_request_size": 50,
79 "options": { "timeout": 20000 },
80 "charts": {
81 "snmp_switch.bandwidth_port": {
@@ -111,13 +115,16 @@ netdata.processors.snmp = {
115 name: 'snmp',
116
117 fixoid: function(oid) {
118 + if(typeof oid !== 'string')
119 + return oid;
120 +
121 if(oid.charAt(0) === '.')
122 return oid.substring(1, oid.length);
123
124 return oid;
125 },
126
120 - process: function(service, callback) {
127 + prepare: function(service) {
128 if(typeof service.snmp_oids === 'undefined' || service.snmp_oids === null || service.snmp_oids.length === 0) {
129 // this is the first time we see this service
130
@@ -132,21 +139,39 @@ netdata.processors.snmp = {
139 if(netdata.options.DEBUG === true)
140 netdata.debug(service.module.name + ': ' + service.name + ': indexing ' + this.name + ' chart: ' + c);
141
142 + if(typeof service.request.charts[c].titleoid !== 'undefined') {
143 + service.snmp_oids_index[this.fixoid(service.request.charts[c].titleoid)] = {
144 + type: 'title',
145 + link: service.request.charts[c]
146 + };
147 + }
148 +
149 for(var d in service.request.charts[c].dimensions) {
150 // for each dimension in the chart
151
152 var oid = this.fixoid(service.request.charts[c].dimensions[d].oid);
153 + var oidname = this.fixoid(service.request.charts[c].dimensions[d].oidname);
154
155 if(netdata.options.DEBUG === true)
141 - netdata.debug(service.module.name + ': ' + service.name + ': indexing ' + this.name + ' chart: ' + c + ', dimension: ' + d + ', OID: ' + oid);
156 + netdata.debug(service.module.name + ': ' + service.name + ': indexing ' + this.name + ' chart: ' + c + ', dimension: ' + d + ', OID: ' + oid + ", OID name: " + oidname);
157
158 // link it to the point we need to set the value to
144 - service.snmp_oids_index[oid] = service.request.charts[c].dimensions[d];
159 + service.snmp_oids_index[oid] = {
160 + type: 'value',
161 + link: service.request.charts[c].dimensions[d]
162 + };
163 +
164 + if(typeof oidname !== 'undefined')
165 + service.snmp_oids_index[oidname] = {
166 + type: 'name',
167 + link: service.request.charts[c].dimensions[d]
168 + };
169
170 // and set the value to null
171 service.request.charts[c].dimensions[d].value = null;
172 }
173 }
174 +
175 if(netdata.options.DEBUG === true)
176 netdata.debug(service.module.name + ': ' + service.name + ': indexed ' + this.name + ' OIDs: ' + netdata.stringify(service.snmp_oids_index));
177
@@ -157,77 +182,127 @@ netdata.processors.snmp = {
182
183 if(netdata.options.DEBUG === true)
184 netdata.debug(service.module.name + ': ' + service.name + ': final list of ' + this.name + ' OIDs: ' + netdata.stringify(service.snmp_oids));
185 +
186 + service.snmp_oids_cleaned = 0;
187 }
188 + else if(service.snmp_oids_cleaned === 0) {
189 + service.snmp_oids_cleaned = 1;
190
162 - if(service.snmp_oids.length === 0) {
163 - // no OIDs found for this service
191 + // the second time, keep only values
192 + service.snmp_oids = new Array();
193 + for(var o in service.snmp_oids_index)
194 + if(service.snmp_oids_index[o].type === 'value')
195 + service.snmp_oids.push(o);
196 + }
197 + },
198
165 - if(netdata.options.DEBUG === true)
166 - service.error('no OIDs to process.');
199 + getdata: function(service, index, ok, failed, callback) {
200 + var that = this;
201
168 - callback(null);
202 + if(index >= service.snmp_oids.length) {
203 + callback((ok > 0)?{ ok: ok, failed: failed }:null);
204 return;
205 }
206
172 - if(typeof service.snmp_session === 'undefined' || service.snmp_session === null) {
173 - // no SNMP session has been created for this service
174 - // the SNMP session is just the initialization of NET-SNMP
175 -
176 - if(netdata.options.DEBUG === true)
177 - netdata.debug(service.module.name + ': ' + service.name + ': opening ' + this.name + ' session on ' + service.request.hostname + ' community ' + service.request.community + ' options ' + netdata.stringify(service.request.options));
178 -
179 - // create the SNMP session
180 - service.snmp_session = net_snmp.createSession (service.request.hostname, service.request.community, service.request.options);
181 -
182 - if(netdata.options.DEBUG === true)
183 - netdata.debug(service.module.name + ': ' + service.name + ': got ' + this.name + ' session: ' + netdata.stringify(service.snmp_session));
184 -
185 - // if we later need traps, this is how to do it:
186 - //service.snmp_session.trap(net_snmp.TrapType.LinkDown, function(error) {
187 - // if(error) console.error('trap error: ' + netdata.stringify(error));
188 - //});
207 + var slice;
208 + if(service.snmp_oids.length <= service.request.max_request_size) {
209 + slice = service.snmp_oids;
210 + index = service.snmp_oids.length;
211 + }
212 + else if(service.snmp_oids.length - index <= service.request.max_request_size) {
213 + slice = service.snmp_oids.slice(index, service.snmp_oids.length);
214 + index = service.snmp_oids.length;
215 + }
216 + else {
217 + slice = service.snmp_oids.slice(index, index + service.request.max_request_size);
218 + index += service.request.max_request_size;
219 }
220
191 - // do it, get the SNMP values for the sessions we need
192 - service.snmp_session.get(service.snmp_oids, function(error, varbinds) {
193 - var ok = 0, failed = 0;
221 + if(netdata.options.DEBUG === true)
222 + netdata.debug(service.module.name + ': ' + service.name + ': making ' + slice.length + ' entries request, max is: ' + service.request.max_request_size);
223
224 + service.snmp_session.get(slice, function(error, varbinds) {
225 if(error) {
226 service.error('Received error = ' + netdata.stringify(error) + ' varbinds = ' + netdata.stringify(varbinds));
227
228 // make all values null
199 - var len = service.snmp_oids.length;
229 + var len = slice.length;
230 while(len--)
201 - service.snmp_oids_index[service.snmp_oids[len]].value = null;
231 + service.snmp_oids_index[slice[len]].value = null;
232 }
233 else {
234 if(netdata.options.DEBUG === true)
235 netdata.debug(service.module.name + ': ' + service.name + ': got valid ' + service.module.name + ' response: ' + netdata.stringify(varbinds));
236
237 for(var i = 0; i < varbinds.length; i++) {
238 + var value = null;
239 +
240 if(net_snmp.isVarbindError(varbinds[i])) {
241 if(netdata.options.DEBUG === true)
242 netdata.debug(service.module.name + ': ' + service.name + ': failed ' + service.module.name + ' get for OIDs ' + varbinds[i].oid);
243
244 service.error('OID ' + varbinds[i].oid + ' gave error: ' + snmp.varbindError(varbinds[i]));
213 - service.snmp_oids_index[varbinds[i].oid].value = null;
245 + value = null;
246 failed++;
247 }
248 else {
249 if(netdata.options.DEBUG === true)
250 netdata.debug(service.module.name + ': ' + service.name + ': found ' + service.module.name + ' value of OIDs ' + varbinds[i].oid + " = " + varbinds[i].value);
251
220 - service.snmp_oids_index[varbinds[i].oid].value = varbinds[i].value;
252 + value = varbinds[i].value;
253 ok++;
254 }
255 +
256 + if(value !== null) {
257 + switch(service.snmp_oids_index[varbinds[i].oid].type) {
258 + case 'title': service.snmp_oids_index[varbinds[i].oid].link.title += ' ' + value; break;
259 + case 'name' : service.snmp_oids_index[varbinds[i].oid].link.name = value; break;
260 + case 'value': service.snmp_oids_index[varbinds[i].oid].link.value = value; break;
261 + }
262 + }
263 }
264
265 if(netdata.options.DEBUG === true)
266 netdata.debug(service.module.name + ': ' + service.name + ': finished ' + service.module.name + ' with ' + ok + ' successful and ' + failed + ' failed values');
267 }
228 -
229 - callback((ok > 0)?{ ok: ok, failed: failed }:null);
268 + that.getdata(service, index, ok, failed, callback);
269 });
270 + },
271 +
272 + process: function(service, callback) {
273 + this.prepare(service);
274 +
275 + if(service.snmp_oids.length === 0) {
276 + // no OIDs found for this service
277 +
278 + if(netdata.options.DEBUG === true)
279 + service.error('no OIDs to process.');
280 +
281 + callback(null);
282 + return;
283 + }
284 +
285 + if(typeof service.snmp_session === 'undefined' || service.snmp_session === null) {
286 + // no SNMP session has been created for this service
287 + // the SNMP session is just the initialization of NET-SNMP
288 +
289 + if(netdata.options.DEBUG === true)
290 + netdata.debug(service.module.name + ': ' + service.name + ': opening ' + this.name + ' session on ' + service.request.hostname + ' community ' + service.request.community + ' options ' + netdata.stringify(service.request.options));
291 +
292 + // create the SNMP session
293 + service.snmp_session = net_snmp.createSession (service.request.hostname, service.request.community, service.request.options);
294 +
295 + if(netdata.options.DEBUG === true)
296 + netdata.debug(service.module.name + ': ' + service.name + ': got ' + this.name + ' session: ' + netdata.stringify(service.snmp_session));
297 +
298 + // if we later need traps, this is how to do it:
299 + //service.snmp_session.trap(net_snmp.TrapType.LinkDown, function(error) {
300 + // if(error) console.error('trap error: ' + netdata.stringify(error));
301 + //});
302 + }
303 +
304 + // do it, get the SNMP values for the sessions we need
305 + this.getdata(service, 0, 0, 0, callback);
306 }
307 };
308
@@ -298,9 +373,16 @@ var snmp = {
373 var id = c + from.toString();
374 var chart = extend(true, {}, service.request.charts[c]);
375 chart.title += from.toString();
376 +
377 + if(typeof chart.titleoid !== 'undefined')
378 + chart.titleoid += from.toString();
379 +
380 chart.priority = prio++;
381 for(var d in chart.dimensions) {
382 chart.dimensions[d].oid += from.toString();
383 +
384 + if(typeof chart.dimensions[d].oidname !== 'undefined')
385 + chart.dimensions[d].oidname += from.toString();
386 }
387 service.request.charts[id] = chart;
388 from++;
@@ -316,12 +398,18 @@ var snmp = {
398 configure: function(config) {
399 var added = 0;
400
401 + if(typeof config.max_request_size === 'undefined')
402 + config.max_request_size = 50;
403 +
404 if(typeof(config.servers) !== 'undefined') {
405 var len = config.servers.length;
406 while(len--) {
407 if(typeof config.servers[len].update_every === 'undefined')
408 config.servers[len].update_every = this.update_every;
409
410 + if(typeof config.servers[len].max_request_size === 'undefined')
411 + config.servers[len].max_request_size = config.max_request_size;
412 +
413 this.serviceExecute(config.servers[len]);
414 added++;
415 }