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.
- data/CHANGES +9 -0
- data/Gemfile +1 -1
- data/lib/newrelic_f5_plugin/agent.rb +61 -338
- data/lib/newrelic_f5_plugin/device.rb +411 -0
- data/lib/newrelic_f5_plugin/nodes.rb +36 -9
- data/lib/newrelic_f5_plugin/pools.rb +35 -81
- data/lib/newrelic_f5_plugin/util.rb +77 -0
- data/lib/newrelic_f5_plugin/virtuals.rb +41 -97
- data/lib/newrelic_f5_plugin.rb +2 -0
- data/newrelic_f5_plugin.gemspec +6 -3
- data/test/nodes_test.rb +72 -0
- data/test/plugin_test.rb +4 -31
- metadata +9 -6
@@ -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
|
-
|
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
|
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
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
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
|
-
|
113
|
-
|
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
|
-
|
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
|
-
|
137
|
-
|
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
|
-
|
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
|
-
|
161
|
-
|
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
|
-
|
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
|
-
|
185
|
-
|
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
|
-
|
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
|
-
|
209
|
-
|
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
|