newrelic_f5_plugin 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,411 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'newrelic_plugin'
4
+ require 'snmp'
5
+
6
+ module NewRelic
7
+ module F5Plugin
8
+
9
+ class Device
10
+ attr_accessor :vs_names, :snmp_manager
11
+
12
+ # Create the OIDs if they do not exist
13
+ OID_SYS_CLIENTSSL_STAT_CUR_CONNS = "1.3.6.1.4.1.3375.2.1.1.2.9.2.0"
14
+ OID_SYS_CLIENTSSL_STAT_TOT_COMPAT_CONNS = "1.3.6.1.4.1.3375.2.1.1.2.9.9.0"
15
+ OID_SYS_CLIENTSSL_STAT_TOT_NATIVE_CONNS = "1.3.6.1.4.1.3375.2.1.1.2.9.6.0"
16
+ OID_SYS_GLOBAL_HOST = "1.3.6.1.4.1.3375.2.1.1.2.20"
17
+ OID_SYS_GLOBAL_HOST_CPU_COUNT = "#{OID_SYS_GLOBAL_HOST}.4.0"
18
+ OID_SYS_GLOBAL_HOST_CPU_IDLE_1M = "#{OID_SYS_GLOBAL_HOST}.25.0"
19
+ OID_SYS_GLOBAL_HOST_CPU_IOWAIT_1M = "#{OID_SYS_GLOBAL_HOST}.28.0"
20
+ OID_SYS_GLOBAL_HOST_CPU_IRQ_1M = "#{OID_SYS_GLOBAL_HOST}.26.0"
21
+ OID_SYS_GLOBAL_HOST_CPU_NICE_1M = "#{OID_SYS_GLOBAL_HOST}.23.0"
22
+ OID_SYS_GLOBAL_HOST_CPU_SOFTIRQ_1M = "#{OID_SYS_GLOBAL_HOST}.27.0"
23
+ OID_SYS_GLOBAL_HOST_CPU_SYSTEM_1M = "#{OID_SYS_GLOBAL_HOST}.24.0"
24
+ OID_SYS_GLOBAL_HOST_CPU_USER_1M = "#{OID_SYS_GLOBAL_HOST}.22.0"
25
+ OID_SYS_HOST_MEMORY_USED = "1.3.6.1.4.1.3375.2.1.7.1.2.0"
26
+ OID_SYS_HTTP_COMPRESSION_STAT = "1.3.6.1.4.1.3375.2.1.1.2.22"
27
+ OID_SYS_HTTP_COMPRESSION_STAT_AUDIO_POSTCOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.24.0"
28
+ OID_SYS_HTTP_COMPRESSION_STAT_AUDIO_PRECOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.23.0"
29
+ OID_SYS_HTTP_COMPRESSION_STAT_CSS_POSTCOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.8.0"
30
+ OID_SYS_HTTP_COMPRESSION_STAT_CSS_PRECOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.7.0"
31
+ OID_SYS_HTTP_COMPRESSION_STAT_HTML_POSTCOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.6.0"
32
+ OID_SYS_HTTP_COMPRESSION_STAT_HTML_PRECOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.5.0"
33
+ OID_SYS_HTTP_COMPRESSION_STAT_IMAGE_POSTCOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.20.0"
34
+ OID_SYS_HTTP_COMPRESSION_STAT_IMAGE_PRECOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.19.0"
35
+ OID_SYS_HTTP_COMPRESSION_STAT_JS_POSTCOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.10.0"
36
+ OID_SYS_HTTP_COMPRESSION_STAT_JS_PRECOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.9.0"
37
+ OID_SYS_HTTP_COMPRESSION_STAT_OCTET_POSTCOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.18.0"
38
+ OID_SYS_HTTP_COMPRESSION_STAT_OCTET_PRECOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.17.0"
39
+ OID_SYS_HTTP_COMPRESSION_STAT_OTHER_POSTCOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.26.0"
40
+ OID_SYS_HTTP_COMPRESSION_STAT_OTHER_PRECOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.25.0"
41
+ OID_SYS_HTTP_COMPRESSION_STAT_PLAIN_POSTCOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.16.0"
42
+ OID_SYS_HTTP_COMPRESSION_STAT_PLAIN_PRECOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.15.0"
43
+ OID_SYS_HTTP_COMPRESSION_STAT_POSTCOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.3.0"
44
+ OID_SYS_HTTP_COMPRESSION_STAT_PRECOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.2.0"
45
+ OID_SYS_HTTP_COMPRESSION_STAT_SGML_POSTCOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.14.0"
46
+ OID_SYS_HTTP_COMPRESSION_STAT_SGML_PRECOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.13.0"
47
+ OID_SYS_HTTP_COMPRESSION_STAT_VIDEO_POSTCOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.22.0"
48
+ OID_SYS_HTTP_COMPRESSION_STAT_VIDEO_PRECOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.21.0"
49
+ OID_SYS_HTTP_COMPRESSION_STAT_XML_POSTCOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.12.0"
50
+ OID_SYS_HTTP_COMPRESSION_STAT_XML_PRECOMPRESS_BYTES = "#{OID_SYS_HTTP_COMPRESSION_STAT}.11.0"
51
+ OID_SYS_HTTP_STAT = "1.3.6.1.4.1.3375.2.1.1.2.4"
52
+ OID_SYS_HTTP_STAT_GET_REQS = "#{OID_SYS_HTTP_STAT}.8.0"
53
+ OID_SYS_HTTP_STAT_NUMBER_REQS = "#{OID_SYS_HTTP_STAT}.7.0"
54
+ OID_SYS_HTTP_STAT_POST_REQS = "#{OID_SYS_HTTP_STAT}.9.0"
55
+ OID_SYS_HTTP_STAT_RESP_2XX_CNT = "#{OID_SYS_HTTP_STAT}.3.0"
56
+ OID_SYS_HTTP_STAT_RESP_3XX_CNT = "#{OID_SYS_HTTP_STAT}.4.0"
57
+ OID_SYS_HTTP_STAT_RESP_4XX_CNT = "#{OID_SYS_HTTP_STAT}.5.0"
58
+ OID_SYS_HTTP_STAT_RESP_5XX_CNT = "#{OID_SYS_HTTP_STAT}.6.0"
59
+ OID_SYS_HTTP_STAT_RESP_BUCKET_16K = "#{OID_SYS_HTTP_STAT}.19.0"
60
+ OID_SYS_HTTP_STAT_RESP_BUCKET_1K = "#{OID_SYS_HTTP_STAT}.17.0"
61
+ OID_SYS_HTTP_STAT_RESP_BUCKET_32K = "#{OID_SYS_HTTP_STAT}.20.0"
62
+ OID_SYS_HTTP_STAT_RESP_BUCKET_4K = "#{OID_SYS_HTTP_STAT}.18.0"
63
+ OID_SYS_HTTP_STAT_V10_REQS = "#{OID_SYS_HTTP_STAT}.11.0"
64
+ OID_SYS_HTTP_STAT_V10_RESP = "#{OID_SYS_HTTP_STAT}.14.0"
65
+ OID_SYS_HTTP_STAT_V11_REQS = "#{OID_SYS_HTTP_STAT}.12.0"
66
+ OID_SYS_HTTP_STAT_V11_RESP = "#{OID_SYS_HTTP_STAT}.15.0"
67
+ OID_SYS_HTTP_STAT_V9_REQS = "#{OID_SYS_HTTP_STAT}.10.0"
68
+ OID_SYS_HTTP_STAT_V9_RESP = "#{OID_SYS_HTTP_STAT}.13.0"
69
+ OID_SYS_SERVERSSL_STAT_CUR_CONNS = "1.3.6.1.4.1.3375.2.1.1.2.10.2.0"
70
+ OID_SYS_SERVERSSL_STAT_TOT_COMPAT_CONNS = "1.3.6.1.4.1.3375.2.1.1.2.10.9.0"
71
+ OID_SYS_SERVERSSL_STAT_TOT_NATIVE_CONNS = "1.3.6.1.4.1.3375.2.1.1.2.10.6.0"
72
+ OID_SYS_STAT = "1.3.6.1.4.1.3375.2.1.1.2.1"
73
+ OID_SYS_STAT_CLIENT_BYTES_IN = "#{OID_SYS_STAT}.3.0"
74
+ OID_SYS_STAT_CLIENT_BYTES_OUT = "#{OID_SYS_STAT}.5.0"
75
+ OID_SYS_STAT_CLIENT_CUR_CONNS = "#{OID_SYS_STAT}.8.0"
76
+ OID_SYS_STAT_CLIENT_TOT_CONNS = "#{OID_SYS_STAT}.7.0"
77
+ OID_SYS_STAT_MEMORY_USED = "#{OID_SYS_STAT}.45.0"
78
+ OID_SYS_STAT_PVA_CLIENT_CUR_CONNS = "#{OID_SYS_STAT}.22.0"
79
+ OID_SYS_STAT_PVA_SERVER_CUR_CONNS = "#{OID_SYS_STAT}.29.0"
80
+ OID_SYS_STAT_SERVER_BYTES_IN = "#{OID_SYS_STAT}.10.0"
81
+ OID_SYS_STAT_SERVER_BYTES_OUT = "#{OID_SYS_STAT}.12.0"
82
+ OID_SYS_STAT_SERVER_CUR_CONNS = "#{OID_SYS_STAT}.15.0"
83
+ OID_SYS_STAT_SERVER_TOT_CONNS = "#{OID_SYS_STAT}.14.0"
84
+ OID_SYS_TCP_STAT = "1.3.6.1.4.1.3375.2.1.1.2.12"
85
+ OID_SYS_TCP_STAT_OPEN = "#{OID_SYS_TCP_STAT}.2.0" # "The number of current open connections."
86
+ OID_SYS_TCP_STAT_CLOSE_WAIT = "#{OID_SYS_TCP_STAT}.3.0" # "The number of current connections in CLOSE-WAIT/LAST-ACK."
87
+ OID_SYS_TCP_STAT_FIN_WAIT = "#{OID_SYS_TCP_STAT}.4.0" # "The number of current connections in FIN-WAIT/CLOSING."
88
+ OID_SYS_TCP_STAT_TIME_WAIT = "#{OID_SYS_TCP_STAT}.5.0" # "The number of current connections in TIME-WAIT."
89
+ OID_SYS_TCP_STAT_ACCEPTS = "#{OID_SYS_TCP_STAT}.6.0" # "The number of connections accepted."
90
+ OID_SYS_TCP_STAT_ACCEPTFAILS = "#{OID_SYS_TCP_STAT}.7.0" # "The number of connections not accepted."
91
+ OID_SYS_TCP_STAT_CONNECTS = "#{OID_SYS_TCP_STAT}.8.0" # "The number of connections established."
92
+ OID_SYS_TCP_STAT_CONNFAILS = "#{OID_SYS_TCP_STAT}.9.0" # "The number of connection failures."
93
+ OID_SYS_TCP_STAT_EXPIRES = "#{OID_SYS_TCP_STAT}.10.0" # "The number of connections expired due to idle timeout."
94
+ OID_SYS_TCP_STAT_ABANDONS = "#{OID_SYS_TCP_STAT}.11.0" # "The number of connections abandoned connections due to retries/keep-alives."
95
+ OID_SYS_TCP_STAT_RXRST = "#{OID_SYS_TCP_STAT}.12.0" # "The number of received RST."
96
+ OID_SYS_TCP_STAT_RXBADSUM = "#{OID_SYS_TCP_STAT}.13.0" # "The number of bad checksum."
97
+ OID_SYS_TCP_STAT_RXBADSEG = "#{OID_SYS_TCP_STAT}.14.0" # "The number of malformed segments."
98
+ OID_SYS_TCP_STAT_RXOOSEG = "#{OID_SYS_TCP_STAT}.15.0" # "The number of out of order segments."
99
+ OID_SYS_TCP_STAT_RXCOOKIE = "#{OID_SYS_TCP_STAT}.16.0" # "The number of received SYN-cookies."
100
+ OID_SYS_TCP_STAT_RXBADCOOKIE = "#{OID_SYS_TCP_STAT}.17.0" # "The number of bad SYN-cookies."
101
+ OID_SYS_TCP_STAT_SYNCACHEOVER = "#{OID_SYS_TCP_STAT}.18.0" # "The number of SYN-cache overflow."
102
+ OID_SYS_TCP_STAT_TXREXMITS = "#{OID_SYS_TCP_STAT}.19.0" # "The number of retransmitted segments."
103
+
104
+
105
+ #
106
+ # Init
107
+ #
108
+ def initialize(snmp = nil)
109
+ if snmp
110
+ @snmp_manager = snmp
111
+ else
112
+ @snmp_manager = nil
113
+ end
114
+ end
115
+
116
+
117
+
118
+ #
119
+ # Gather CPU Related metrics and report them in %
120
+ #
121
+ def get_cpu(snmp = nil)
122
+ metrics = { }
123
+ snmp = snmp_manager unless snmp
124
+
125
+ if snmp
126
+ res = gather_snmp_metrics_array([OID_SYS_GLOBAL_HOST_CPU_COUNT, OID_SYS_GLOBAL_HOST_CPU_USER_1M, OID_SYS_GLOBAL_HOST_CPU_NICE_1M,
127
+ OID_SYS_GLOBAL_HOST_CPU_SYSTEM_1M, OID_SYS_GLOBAL_HOST_CPU_IRQ_1M, OID_SYS_GLOBAL_HOST_CPU_SOFTIRQ_1M,
128
+ OID_SYS_GLOBAL_HOST_CPU_IOWAIT_1M],
129
+ snmp)
130
+
131
+ # In order to show the CPU usage as a total percentage, we divide by the number of cpus
132
+ cpu_count = res[0].to_i
133
+ vals = res[1..6].map { |i| i.to_f / cpu_count }
134
+
135
+ metrics["CPU/Global/User"] = vals[0]
136
+ metrics["CPU/Global/Nice"] = vals[1]
137
+ metrics["CPU/Global/System"] = vals[2]
138
+ metrics["CPU/Global/IRQ"] = vals[3]
139
+ metrics["CPU/Global/Soft IRQ"] = vals[4]
140
+ metrics["CPU/Global/IO Wait"] = vals[5]
141
+
142
+ # Add it all up, and send a summary metric
143
+ metrics["CPU/Total/Global"] = vals.inject(0.0){ |a,b| a + b }
144
+
145
+ end
146
+
147
+ return metrics
148
+ end
149
+
150
+
151
+ #
152
+ # Gather Memory related metrics and report them in bytes
153
+ #
154
+ def get_memory(snmp = nil)
155
+ metrics = { }
156
+ snmp = snmp_manager unless snmp
157
+
158
+ if snmp
159
+ res = gather_snmp_metrics_array([OID_SYS_STAT_MEMORY_USED, OID_SYS_HOST_MEMORY_USED], snmp)
160
+
161
+ metrics["Memory/TMM"] = res[0]
162
+ metrics["Memory/Host"] = res[1]
163
+ end
164
+
165
+ return metrics
166
+ end
167
+
168
+
169
+ #
170
+ # Gather Global connection related metrics and report them in conn
171
+ #
172
+ def get_connections(snmp = nil)
173
+ metrics = { }
174
+ snmp = snmp_manager unless snmp
175
+
176
+ if snmp
177
+ res = gather_snmp_metrics_array([OID_SYS_STAT_CLIENT_CUR_CONNS, OID_SYS_STAT_SERVER_CUR_CONNS,
178
+ OID_SYS_CLIENTSSL_STAT_CUR_CONNS, OID_SYS_SERVERSSL_STAT_CUR_CONNS],
179
+ snmp)
180
+
181
+ metrics["Connections/Current/Client"] = res[0]
182
+ metrics["Connections/Current/Server"] = res[1]
183
+ metrics["Connections/Current/Client SSL"] = res[2]
184
+ metrics["Connections/Current/Server SSL"] = res[3]
185
+ end
186
+
187
+ return metrics
188
+ end
189
+
190
+
191
+ #
192
+ # Gather Global connection rate related metrics and report them in conn/sec
193
+ #
194
+ def get_connection_rates(snmp = nil)
195
+ metrics = { }
196
+ snmp = snmp_manager unless snmp
197
+
198
+ if snmp
199
+ res = gather_snmp_metrics_array([OID_SYS_STAT_CLIENT_TOT_CONNS, OID_SYS_STAT_SERVER_TOT_CONNS], snmp)
200
+
201
+ metrics["Connections/Rate/Client"] = res[0]
202
+ metrics["Connections/Rate/Server"] = res[1]
203
+ end
204
+
205
+ return metrics
206
+ end
207
+
208
+
209
+ #
210
+ # Gather Global throughput related metrics and report them in bits/sec
211
+ #
212
+ def get_throughput(snmp = nil)
213
+ metrics = { }
214
+ snmp = snmp_manager unless snmp
215
+
216
+ if snmp
217
+ res = gather_snmp_metrics_array([OID_SYS_STAT_CLIENT_BYTES_IN, OID_SYS_STAT_CLIENT_BYTES_OUT,
218
+ OID_SYS_STAT_SERVER_BYTES_IN, OID_SYS_STAT_SERVER_BYTES_OUT],
219
+ snmp)
220
+
221
+ metrics["Throughput/Client/In"] = (res[0].to_f * 8)
222
+ metrics["Throughput/Client/Out"] = (res[1].to_f * 8)
223
+ metrics["Throughput/Server/In"] = (res[2].to_f * 8)
224
+ metrics["Throughput/Server/Out"] = (res[3].to_f * 8)
225
+ tot = 0
226
+ res.each { |x| tot += x.to_f }
227
+ metrics["Throughput/Total"] = (tot * 8)
228
+ end
229
+
230
+ return metrics
231
+ end
232
+
233
+
234
+ #
235
+ # Gather Global HTTP related metrics in req/sec
236
+ #
237
+ def get_http_requests(snmp = nil)
238
+ metrics = { }
239
+ snmp = snmp_manager unless snmp
240
+
241
+ if snmp
242
+ res = gather_snmp_metrics_array([OID_SYS_HTTP_STAT_NUMBER_REQS, OID_SYS_HTTP_STAT_GET_REQS, OID_SYS_HTTP_STAT_POST_REQS,
243
+ OID_SYS_HTTP_STAT_V9_REQS, OID_SYS_HTTP_STAT_V10_REQS, OID_SYS_HTTP_STAT_V11_REQS],
244
+ snmp)
245
+
246
+ metrics["HTTP/Method/All"] = res[0]
247
+ metrics["HTTP/Method/Get"] = res[1]
248
+ metrics["HTTP/Method/Post"] = res[2]
249
+ metrics["HTTP/Version/v0.9/Request"] = res[3]
250
+ metrics["HTTP/Version/v1.0/Request"] = res[4]
251
+ metrics["HTTP/Version/v1.1/Request"] = res[5]
252
+ end
253
+
254
+ return metrics
255
+ end
256
+
257
+
258
+ #
259
+ # Gather Global HTTP related metrics in resp/sec
260
+ #
261
+ def get_http_responses(snmp = nil)
262
+ metrics = { }
263
+ snmp = snmp_manager unless snmp
264
+
265
+ if snmp
266
+ res = gather_snmp_metrics_array([OID_SYS_HTTP_STAT_RESP_2XX_CNT, OID_SYS_HTTP_STAT_RESP_3XX_CNT, OID_SYS_HTTP_STAT_RESP_4XX_CNT,
267
+ OID_SYS_HTTP_STAT_RESP_5XX_CNT, OID_SYS_HTTP_STAT_V9_RESP, OID_SYS_HTTP_STAT_V10_RESP,
268
+ OID_SYS_HTTP_STAT_V11_RESP, OID_SYS_HTTP_STAT_RESP_BUCKET_1K, OID_SYS_HTTP_STAT_RESP_BUCKET_4K,
269
+ OID_SYS_HTTP_STAT_RESP_BUCKET_16K, OID_SYS_HTTP_STAT_RESP_BUCKET_32K],
270
+ snmp)
271
+
272
+ metrics["HTTP/Response Code/2xx"] = res[0]
273
+ metrics["HTTP/Response Code/3xx"] = res[1]
274
+ metrics["HTTP/Response Code/4xx"] = res[2]
275
+ metrics["HTTP/Response Code/5xx"] = res[3]
276
+ metrics["HTTP/Version/v0.9/Response"] = res[4]
277
+ metrics["HTTP/Version/v1.0/Response"] = res[5]
278
+ metrics["HTTP/Version/v1.1/Response"] = res[6]
279
+ metrics["HTTP/Response Size/1k Bucket"] = res[7]
280
+ metrics["HTTP/Response Size/4k Bucket"] = res[8]
281
+ metrics["HTTP/Response Size/16k Bucket"] = res[9]
282
+ metrics["HTTP/Response Size/32k Bucket"] = res[10]
283
+ end
284
+
285
+ return metrics
286
+ end
287
+
288
+
289
+ #
290
+ # HTTP Compression Stats in bits/sec
291
+ #
292
+ def get_http_compression(snmp = nil)
293
+ metrics = { }
294
+ snmp = snmp_manager unless snmp
295
+
296
+ if snmp
297
+ res = gather_snmp_metrics_array([OID_SYS_HTTP_COMPRESSION_STAT_PRECOMPRESS_BYTES, OID_SYS_HTTP_COMPRESSION_STAT_POSTCOMPRESS_BYTES,
298
+ OID_SYS_HTTP_COMPRESSION_STAT_HTML_PRECOMPRESS_BYTES, OID_SYS_HTTP_COMPRESSION_STAT_HTML_POSTCOMPRESS_BYTES,
299
+ OID_SYS_HTTP_COMPRESSION_STAT_CSS_PRECOMPRESS_BYTES, OID_SYS_HTTP_COMPRESSION_STAT_CSS_POSTCOMPRESS_BYTES,
300
+ OID_SYS_HTTP_COMPRESSION_STAT_JS_PRECOMPRESS_BYTES, OID_SYS_HTTP_COMPRESSION_STAT_JS_POSTCOMPRESS_BYTES,
301
+ OID_SYS_HTTP_COMPRESSION_STAT_XML_PRECOMPRESS_BYTES, OID_SYS_HTTP_COMPRESSION_STAT_XML_POSTCOMPRESS_BYTES,
302
+ OID_SYS_HTTP_COMPRESSION_STAT_SGML_PRECOMPRESS_BYTES, OID_SYS_HTTP_COMPRESSION_STAT_SGML_POSTCOMPRESS_BYTES,
303
+ OID_SYS_HTTP_COMPRESSION_STAT_PLAIN_PRECOMPRESS_BYTES, OID_SYS_HTTP_COMPRESSION_STAT_PLAIN_POSTCOMPRESS_BYTES,
304
+ OID_SYS_HTTP_COMPRESSION_STAT_OCTET_PRECOMPRESS_BYTES, OID_SYS_HTTP_COMPRESSION_STAT_OCTET_POSTCOMPRESS_BYTES,
305
+ OID_SYS_HTTP_COMPRESSION_STAT_IMAGE_PRECOMPRESS_BYTES, OID_SYS_HTTP_COMPRESSION_STAT_IMAGE_POSTCOMPRESS_BYTES,
306
+ OID_SYS_HTTP_COMPRESSION_STAT_VIDEO_PRECOMPRESS_BYTES, OID_SYS_HTTP_COMPRESSION_STAT_VIDEO_POSTCOMPRESS_BYTES,
307
+ OID_SYS_HTTP_COMPRESSION_STAT_AUDIO_PRECOMPRESS_BYTES, OID_SYS_HTTP_COMPRESSION_STAT_AUDIO_POSTCOMPRESS_BYTES,
308
+ OID_SYS_HTTP_COMPRESSION_STAT_OTHER_PRECOMPRESS_BYTES, OID_SYS_HTTP_COMPRESSION_STAT_OTHER_POSTCOMPRESS_BYTES],
309
+ snmp)
310
+
311
+ vals = res.map { |i| i.to_f * 8 } # Convert to bits
312
+ metrics["HTTP/Compression/Total/Pre"] = vals[0]
313
+ metrics["HTTP/Compression/Total/Post"] = vals[1]
314
+ metrics["HTTP/Compression/HTML/Pre"] = vals[2]
315
+ metrics["HTTP/Compression/HTML/Post"] = vals[3]
316
+ metrics["HTTP/Compression/CSS/Pre"] = vals[4]
317
+ metrics["HTTP/Compression/CSS/Post"] = vals[5]
318
+ metrics["HTTP/Compression/Javascript/Pre"] = vals[6]
319
+ metrics["HTTP/Compression/Javascript/Post"] = vals[7]
320
+ metrics["HTTP/Compression/XML/Pre"] = vals[8]
321
+ metrics["HTTP/Compression/XML/Post"] = vals[9]
322
+ metrics["HTTP/Compression/SGML/Pre"] = vals[10]
323
+ metrics["HTTP/Compression/SGML/Post"] = vals[11]
324
+ metrics["HTTP/Compression/Plain/Pre"] = vals[12]
325
+ metrics["HTTP/Compression/Plain/Post"] = vals[13]
326
+ metrics["HTTP/Compression/Octet/Pre"] = vals[14]
327
+ metrics["HTTP/Compression/Octet/Post"] = vals[15]
328
+ metrics["HTTP/Compression/Image/Pre"] = vals[16]
329
+ metrics["HTTP/Compression/Image/Post"] = vals[17]
330
+ metrics["HTTP/Compression/Video/Pre"] = vals[18]
331
+ metrics["HTTP/Compression/Video/Post"] = vals[19]
332
+ metrics["HTTP/Compression/Audio/Pre"] = vals[20]
333
+ metrics["HTTP/Compression/Audio/Post"] = vals[21]
334
+ metrics["HTTP/Compression/Other/Pre"] = vals[22]
335
+ metrics["HTTP/Compression/Other/Post"] = vals[23]
336
+ end
337
+
338
+ return metrics
339
+ end
340
+
341
+
342
+
343
+ #
344
+ # SSL Stats in trans/sec
345
+ #
346
+ def get_ssl(snmp = nil)
347
+ metrics = { }
348
+ snmp = snmp_manager unless snmp
349
+
350
+ if snmp
351
+ res = gather_snmp_metrics_array([OID_SYS_CLIENTSSL_STAT_TOT_NATIVE_CONNS, OID_SYS_CLIENTSSL_STAT_TOT_COMPAT_CONNS,
352
+ OID_SYS_SERVERSSL_STAT_TOT_NATIVE_CONNS, OID_SYS_SERVERSSL_STAT_TOT_COMPAT_CONNS],
353
+ snmp)
354
+
355
+ vals = res.map { |i| i.to_i }
356
+
357
+ metrics["SSL/Global/Client/Native"] = vals[0]
358
+ metrics["SSL/Global/Client/Compat"] = vals[1]
359
+ metrics["SSL/Global/Server/Native"] = vals[2]
360
+ metrics["SSL/Global/Server/Compat"] = vals[3]
361
+ metrics["SSL/Global/Total/Client"] = (vals[0] + vals[1])
362
+ metrics["SSL/Global/Total/Server"] = (vals[2] + vals[3])
363
+ metrics["SSL/Global/Total/All"] = vals.inject(0) { |t,i| t + i }
364
+ end
365
+
366
+ return metrics
367
+ end
368
+
369
+
370
+ #
371
+ # Gather TCP Statistics in conn
372
+ #
373
+ def get_tcp_connections(snmp = nil)
374
+ metrics = { }
375
+ snmp = snmp_manager unless snmp
376
+
377
+ if snmp
378
+ res = gather_snmp_metrics_array([OID_SYS_TCP_STAT_OPEN, OID_SYS_TCP_STAT_CLOSE_WAIT, OID_SYS_TCP_STAT_FIN_WAIT,
379
+ OID_SYS_TCP_STAT_TIME_WAIT],
380
+ snmp)
381
+
382
+ metrics["TCP/Connection State/Open"] = res[0]
383
+ metrics["TCP/Connection State/Wait/Close"] = res[1]
384
+ metrics["TCP/Connection State/Wait/FIN"] = res[2]
385
+ metrics["TCP/Connection State/Wait/TIME"] = res[3]
386
+ end
387
+
388
+ return metrics
389
+ end
390
+
391
+
392
+ #
393
+ # Gather TCP Statistics in conn/sec
394
+ #
395
+ def get_tcp_connection_rates(snmp = nil)
396
+ metrics = { }
397
+ snmp = snmp_manager unless snmp
398
+
399
+ if snmp
400
+ res = gather_snmp_metrics_array([OID_SYS_TCP_STAT_ACCEPTS], snmp)
401
+
402
+ metrics["TCP/Accepts"] = res[0]
403
+ end
404
+
405
+ return metrics
406
+ end
407
+
408
+ end
409
+ end
410
+ end
411
+
@@ -7,7 +7,9 @@ require 'snmp'
7
7
  module NewRelic
8
8
  module F5Plugin
9
9
 
10
- module Nodes
10
+ class Nodes
11
+ attr_accessor :vs_names, :snmp_manager
12
+
11
13
  NODE_MONITOR_STATES = {
12
14
  0 => 'unchecked',
13
15
  1 => 'checking',
@@ -23,6 +25,21 @@ module NewRelic
23
25
  25 => 'disabled',
24
26
  }
25
27
 
28
+ OID_LTM_NODE_ADDR_MONITOR_STATUS = "1.3.6.1.4.1.3375.2.2.4.1.2.1.7"
29
+
30
+
31
+ #
32
+ # Init
33
+ #
34
+ def initialize(snmp = nil)
35
+ if snmp
36
+ @snmp_manager = snmp
37
+ else
38
+ @snmp_manager = nil
39
+ end
40
+ end
41
+
42
+
26
43
  #
27
44
  # Node Naming in SNMP
28
45
  #
@@ -33,26 +50,36 @@ module NewRelic
33
50
  #
34
51
  # Gather Node Status and report
35
52
  #
36
- def self.get_status(snmp)
53
+ def get_status(snmp = nil)
54
+ snmp = snmp_manager unless snmp
55
+ metrics = { }
56
+ counter = 0
57
+
37
58
  if snmp
38
59
  # Init all the states with zeros so we always get them
39
60
  base_name = "Nodes/Monitor Status"
40
- metrics = { }
41
61
  NODE_MONITOR_STATES.each do |key,value|
42
62
  metrics["#{base_name}/#{value}"] = { :label => "nodes", :count => 0 }
43
63
  end
44
64
 
45
65
  # ltmNodeAddrMonitorStatus
46
- snmp.walk(["1.3.6.1.4.1.3375.2.2.4.1.2.1.7"]) do |row|
47
- row.each do |vb|
48
- metric_name = "#{base_name}/#{NODE_MONITOR_STATES[vb.value.to_i]}"
49
- metrics[metric_name][:count] += 1
66
+ begin
67
+ snmp.walk([OID_LTM_NODE_ADDR_MONITOR_STATUS]) do |row|
68
+ row.each do |vb|
69
+ metric_name = "#{base_name}/#{NODE_MONITOR_STATES[vb.value.to_i]}"
70
+ metrics[metric_name][:count] += 1
71
+ counter += 1
72
+ end
50
73
  end
74
+ rescue Exception => e
75
+ NewRelic::PlatformLogger.error("Unable to gather Node Status metrics with error: #{e}")
51
76
  end
52
-
53
- return metrics
54
77
  end
78
+
79
+ NewRelic::PlatformLogger.debug("Nodes: Got #{counter} Status metrics")
80
+ return metrics
55
81
  end
82
+
56
83
  end
57
84
  end
58
85
  end
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'newrelic_plugin'
4
- require 'snmp'
5
4
 
6
5
  # LtmPoolStatEntry
7
6
  # ltmPoolStatName LongDisplayString,
@@ -79,12 +78,17 @@ module NewRelic
79
78
  if snmp
80
79
  @pool_names.clear
81
80
 
82
- snmp.walk([OID_LTM_POOL_STAT_NAME]) do |row|
83
- row.each do |vb|
84
- @pool_names.push(vb.value)
81
+ begin
82
+ snmp.walk([OID_LTM_POOL_STAT_NAME]) do |row|
83
+ row.each do |vb|
84
+ @pool_names.push(vb.value)
85
+ end
85
86
  end
87
+ rescue Exception => e
88
+ NewRelic::PlatformLogger.error("Unable to gather Pool names with error: #{e}")
86
89
  end
87
90
 
91
+ NewRelic::PlatformLogger.debug("Pools: Found #{@pool_names.size} pools")
88
92
  return @pool_names
89
93
  end
90
94
  end
@@ -95,22 +99,12 @@ module NewRelic
95
99
  # Gather Total Requests
96
100
  #
97
101
  def get_requests(snmp = nil)
98
- metrics = { }
99
- index = 0
100
- snmp = snmp_manager unless snmp
101
-
102
- if snmp
103
- get_names(snmp) if @pool_names.empty?
104
-
105
- snmp.walk([OID_LTM_POOL_STAT_TOT_REQUESTS]) do |row|
106
- row.each do |vb|
107
- metrics["Pools/Requests/#{@pool_names[index]}"] = vb.value.to_i
108
- index += 1
109
- end
110
- end
102
+ snmp = snmp_manager unless snmp
111
103
 
112
- return metrics
113
- end
104
+ get_names(snmp) if @pool_names.empty?
105
+ res = gather_snmp_metrics_by_name("Pools/Requests", @pool_names, OID_LTM_POOL_STAT_TOT_REQUESTS, snmp)
106
+ NewRelic::PlatformLogger.debug("Pools: Got #{res.size}/#{@pool_names.size} Request metrics")
107
+ return res
114
108
  end
115
109
 
116
110
 
@@ -119,22 +113,12 @@ module NewRelic
119
113
  # Gather Connection count
120
114
  #
121
115
  def get_conns_current(snmp = nil)
122
- metrics = { }
123
- index = 0
124
- snmp = snmp_manager unless snmp
125
-
126
- if snmp
127
- get_names(snmp) if @pool_names.empty?
128
-
129
- snmp.walk([OID_LTM_POOL_STAT_SERVER_CUR_CONNS]) do |row|
130
- row.each do |vb|
131
- metrics["Pools/Current Connections/#{@pool_names[index]}"] = vb.value.to_i
132
- index += 1
133
- end
134
- end
116
+ snmp = snmp_manager unless snmp
135
117
 
136
- return metrics
137
- end
118
+ get_names(snmp) if @pool_names.empty?
119
+ res = gather_snmp_metrics_by_name("Pools/Current Connections", @pool_names, OID_LTM_POOL_STAT_SERVER_CUR_CONNS, snmp)
120
+ NewRelic::PlatformLogger.debug("Pools: Got #{res.size}/#{@pool_names.size} Current Connection metrics")
121
+ return res
138
122
  end
139
123
 
140
124
 
@@ -143,22 +127,12 @@ module NewRelic
143
127
  # Gather Connection rate
144
128
  #
145
129
  def get_conns_total(snmp = nil)
146
- metrics = { }
147
- index = 0
148
- snmp = snmp_manager unless snmp
149
-
150
- if snmp
151
- get_names(snmp) if @pool_names.empty?
152
-
153
- snmp.walk([OID_LTM_POOL_STAT_SERVER_TOT_CONNS]) do |row|
154
- row.each do |vb|
155
- metrics["Pools/Connection Rate/#{@pool_names[index]}"] = vb.value.to_i
156
- index += 1
157
- end
158
- end
130
+ snmp = snmp_manager unless snmp
159
131
 
160
- return metrics
161
- end
132
+ get_names(snmp) if @pool_names.empty?
133
+ res = gather_snmp_metrics_by_name("Pools/Connection Rate", @pool_names, OID_LTM_POOL_STAT_SERVER_TOT_CONNS, snmp)
134
+ NewRelic::PlatformLogger.debug("Pools: Got #{res.size}/#{@pool_names.size} Connection Rate metrics")
135
+ return res
162
136
  end
163
137
 
164
138
 
@@ -167,22 +141,13 @@ module NewRelic
167
141
  # Gather Throughput Inbound (returns in bits)
168
142
  #
169
143
  def get_throughput_in(snmp = nil)
170
- metrics = { }
171
- index = 0
172
- snmp = snmp_manager unless snmp
173
-
174
- if snmp
175
- get_names(snmp) if @pool_names.empty?
176
-
177
- snmp.walk([OID_LTM_POOL_STAT_SERVER_BYTES_IN]) do |row|
178
- row.each do |vb|
179
- metrics["Pools/Throughput/In/#{@pool_names[index]}"] = (vb.value.to_f * 8)
180
- index += 1
181
- end
182
- end
144
+ snmp = snmp_manager unless snmp
183
145
 
184
- return metrics
185
- end
146
+ get_names(snmp) if @pool_names.empty?
147
+ res = gather_snmp_metrics_by_name("Pools/Throughput/In", @pool_names, OID_LTM_POOL_STAT_SERVER_BYTES_IN, snmp)
148
+ res = res.each_key { |n| res[n] *= 8 }
149
+ NewRelic::PlatformLogger.debug("Pools: Got #{res.size}/#{@pool_names.size} Inbound Throughput metrics")
150
+ return res
186
151
  end
187
152
 
188
153
 
@@ -191,26 +156,15 @@ module NewRelic
191
156
  # Gather Throughput Inbound (returns in bits)
192
157
  #
193
158
  def get_throughput_out(snmp = nil)
194
- metrics = { }
195
- index = 0
196
- snmp = snmp_manager unless snmp
197
-
198
- if snmp
199
- get_names(snmp) if @pool_names.empty?
200
-
201
- snmp.walk([OID_LTM_POOL_STAT_SERVER_BYTES_OUT]) do |row|
202
- row.each do |vb|
203
- metrics["Pools/Throughput/Out/#{@pool_names[index]}"] = (vb.value.to_f * 8)
204
- index += 1
205
- end
206
- end
159
+ snmp = snmp_manager unless snmp
207
160
 
208
- return metrics
209
- end
161
+ get_names(snmp) if @pool_names.empty?
162
+ res = gather_snmp_metrics_by_name("Pools/Throughput/Out", @pool_names, OID_LTM_POOL_STAT_SERVER_BYTES_OUT, snmp)
163
+ res = res.each_key { |n| res[n] *= 8 }
164
+ NewRelic::PlatformLogger.debug("Pools: Got #{res.size}/#{@pool_names.size} Outbound Throughput metrics")
165
+ return res
210
166
  end
211
167
 
212
-
213
-
214
168
  end
215
169
  end
216
170
  end