newrelic_f5_plugin 1.0.9 → 1.0.10
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +9 -0
- data/README.rdoc +12 -0
- data/lib/newrelic_f5_plugin/agent.rb +86 -37
- data/lib/newrelic_f5_plugin/rules.rb +134 -0
- data/lib/newrelic_f5_plugin.rb +1 -0
- data/newrelic_f5_plugin.gemspec +3 -2
- metadata +3 -2
data/CHANGES
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
* 1.0.10
|
2
|
+
- Add iRule statistics:
|
3
|
+
- Executions per second
|
4
|
+
- Failures per second
|
5
|
+
- Aborts per second
|
6
|
+
- Average cycles taken (requires timing to be enabled)
|
7
|
+
- Updated SNMP connection logic to skip devices that are unreachable
|
8
|
+
- Skip collecting metrics if we can not get list of names for them
|
9
|
+
|
1
10
|
* 1.0.9
|
2
11
|
- Add SNAT Pools statistics:
|
3
12
|
- Current Connections
|
data/README.rdoc
CHANGED
@@ -27,6 +27,12 @@ Pool Statistics
|
|
27
27
|
* Connections per Second
|
28
28
|
* Inbound and Outbound Throughput
|
29
29
|
|
30
|
+
iRule Statistics
|
31
|
+
* Executions per Second
|
32
|
+
* Failures per Second
|
33
|
+
* Aborts per Second
|
34
|
+
* Average cycles (requires timing enabled on the iRule)
|
35
|
+
|
30
36
|
|
31
37
|
== Requirements
|
32
38
|
|
@@ -62,6 +68,12 @@ SNMP version 2c is supported.
|
|
62
68
|
|
63
69
|
f5_monitor run
|
64
70
|
|
71
|
+
== Installation with Chef/Puppet
|
72
|
+
|
73
|
+
The F5 plugin can also be installed with {Chef}[http://www.getchef.com] and {Puppet}[http://puppetlabs.com]. For Chef and Puppet support see the New Relic plugin's {Chef Cookbook}[http://community.opscode.com/cookbooks/newrelic_plugins] and {Puppet Module}[https://forge.puppetlabs.com/newrelic/newrelic_plugins].
|
74
|
+
|
75
|
+
Additional information on using Chef and Puppet with New Relic is available in New Relic's {documentation}[https://docs.newrelic.com/docs/plugins/plugin-installation-with-chef-and-puppet].
|
76
|
+
|
65
77
|
== Developer Instructions
|
66
78
|
|
67
79
|
1. Fork/Clone the repository
|
@@ -4,7 +4,7 @@ require 'newrelic_plugin'
|
|
4
4
|
require 'snmp'
|
5
5
|
|
6
6
|
module NewRelic::F5Plugin
|
7
|
-
VERSION = '1.0.
|
7
|
+
VERSION = '1.0.10'
|
8
8
|
|
9
9
|
# Register and run the agent
|
10
10
|
def self.run
|
@@ -50,9 +50,27 @@ module NewRelic::F5Plugin
|
|
50
50
|
# This is called on every polling cycle
|
51
51
|
#
|
52
52
|
def poll_cycle
|
53
|
+
NewRelic::PlatformLogger.debug("Starting poll cycle for '#{hostname}'")
|
54
|
+
|
53
55
|
# SNMP Stuff here
|
54
56
|
snmp = SNMP::Manager.new(:host => hostname, :port => port, :community => snmp_community)
|
55
57
|
|
58
|
+
#
|
59
|
+
# Test our SNMP connection, return if we fail to connect so the entire agent doesn't quit
|
60
|
+
#
|
61
|
+
begin
|
62
|
+
product_name = snmp.get_value(["1.3.6.1.4.1.3375.2.1.4.1.0"]).first
|
63
|
+
NewRelic::PlatformLogger.debug("Found F5 device of type: '#{product_name}'")
|
64
|
+
rescue SNMP::RequestTimeout
|
65
|
+
NewRelic::PlatformLogger.error("Unable to connect to device: '#{hostname}', skipping...")
|
66
|
+
snmp.close
|
67
|
+
return
|
68
|
+
rescue => e
|
69
|
+
NewRelic::PlatformLogger.error(e)
|
70
|
+
snmp.close
|
71
|
+
return
|
72
|
+
end
|
73
|
+
|
56
74
|
|
57
75
|
#
|
58
76
|
# Device wide metrics
|
@@ -108,43 +126,71 @@ module NewRelic::F5Plugin
|
|
108
126
|
#
|
109
127
|
NewRelic::PlatformLogger.debug("Collecting Virtual Server stats")
|
110
128
|
vs = NewRelic::F5Plugin::Virtuals.new snmp
|
111
|
-
virtual_requests = vs.get_requests
|
112
|
-
virtual_requests.each_key { |m| report_counter_metric m, "req/sec", virtual_requests[m] } unless virtual_requests.nil?
|
113
129
|
|
114
|
-
|
115
|
-
|
130
|
+
if vs.get_names
|
131
|
+
virtual_requests = vs.get_requests
|
132
|
+
virtual_requests.each_key { |m| report_counter_metric m, "req/sec", virtual_requests[m] } unless virtual_requests.nil?
|
116
133
|
|
117
|
-
|
118
|
-
|
134
|
+
virtual_conns_current = vs.get_conns_current
|
135
|
+
virtual_conns_current.each_key { |m| report_metric m, "conns", virtual_conns_current[m] } unless virtual_conns_current.nil?
|
119
136
|
|
120
|
-
|
121
|
-
|
137
|
+
virtual_conns_total = vs.get_conns_total
|
138
|
+
virtual_conns_total.each_key { |m| report_counter_metric m, "conn/sec", virtual_conns_total[m] } unless virtual_conns_total.nil?
|
122
139
|
|
123
|
-
|
124
|
-
|
140
|
+
virtual_throughput_in = vs.get_throughput_in
|
141
|
+
virtual_throughput_in.each_key { |m| report_counter_metric m, "bits/sec", virtual_throughput_in[m] } unless virtual_throughput_in.nil?
|
125
142
|
|
126
|
-
|
127
|
-
|
143
|
+
virtual_throughput_out = vs.get_throughput_out
|
144
|
+
virtual_throughput_out.each_key { |m| report_counter_metric m, "bits/sec", virtual_throughput_out[m] } unless virtual_throughput_out.nil?
|
145
|
+
|
146
|
+
virtual_cpu_usage_1m = vs.get_cpu_usage_1m
|
147
|
+
virtual_cpu_usage_1m.each_key { |m| report_metric m, "%", virtual_cpu_usage_1m[m] } unless virtual_cpu_usage_1m.nil?
|
148
|
+
end
|
128
149
|
|
129
150
|
#
|
130
151
|
# Collect pool statistics
|
131
152
|
#
|
132
153
|
NewRelic::PlatformLogger.debug("Collecting Pool stats")
|
133
154
|
pool = NewRelic::F5Plugin::Pools.new snmp
|
134
|
-
pool_requests = pool.get_requests
|
135
|
-
pool_requests.each_key { |m| report_counter_metric m, "req/sec", pool_requests[m] } unless pool_requests.nil?
|
136
155
|
|
137
|
-
|
138
|
-
|
156
|
+
if pool.get_names
|
157
|
+
pool_requests = pool.get_requests
|
158
|
+
pool_requests.each_key { |m| report_counter_metric m, "req/sec", pool_requests[m] } unless pool_requests.nil?
|
159
|
+
|
160
|
+
pool_conns_current = pool.get_conns_current
|
161
|
+
pool_conns_current.each_key { |m| report_metric m, "conns", pool_conns_current[m] } unless pool_conns_current.nil?
|
139
162
|
|
140
|
-
|
141
|
-
|
163
|
+
pool_conns_total = pool.get_conns_total
|
164
|
+
pool_conns_total.each_key { |m| report_counter_metric m, "conn/sec", pool_conns_total[m] } unless pool_conns_total.nil?
|
142
165
|
|
143
|
-
|
144
|
-
|
166
|
+
pool_throughput_in = pool.get_throughput_in
|
167
|
+
pool_throughput_in.each_key { |m| report_counter_metric m, "bits/sec", pool_throughput_in[m] } unless pool_throughput_in.nil?
|
168
|
+
|
169
|
+
pool_throughput_out = pool.get_throughput_out
|
170
|
+
pool_throughput_out.each_key { |m| report_counter_metric m, "bits/sec", pool_throughput_out[m] } unless pool_throughput_out.nil?
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
#
|
175
|
+
# iRule statistics
|
176
|
+
#
|
177
|
+
NewRelic::PlatformLogger.debug("Collecting iRule stats")
|
178
|
+
rule = NewRelic::F5Plugin::Rules.new snmp
|
179
|
+
|
180
|
+
if rule.get_names
|
181
|
+
rule_execs = rule.get_executions
|
182
|
+
rule_execs.each_key { |m| report_counter_metric m, "execs/sec", rule_execs[m] } unless rule_execs.nil?
|
183
|
+
|
184
|
+
rule_failures = rule.get_failures
|
185
|
+
rule_failures.each_key { |m| report_counter_metric m, "failures/sec", rule_failures[m] } unless rule_failures.nil?
|
186
|
+
|
187
|
+
rule_aborts = rule.get_aborts
|
188
|
+
rule_aborts.each_key { |m| report_counter_metric m, "aborts/sec", rule_aborts[m] } unless rule_aborts.nil?
|
189
|
+
|
190
|
+
rule_cycles = rule.get_average_cycles
|
191
|
+
rule_cycles.each_key { |m| report_metric m, "cycles", rule_cycles[m] } unless rule_cycles.nil?
|
192
|
+
end
|
145
193
|
|
146
|
-
pool_throughput_out = pool.get_throughput_out
|
147
|
-
pool_throughput_out.each_key { |m| report_counter_metric m, "bits/sec", pool_throughput_out[m] } unless pool_throughput_out.nil?
|
148
194
|
|
149
195
|
#
|
150
196
|
# Collect snat pool statistics
|
@@ -152,26 +198,29 @@ module NewRelic::F5Plugin
|
|
152
198
|
NewRelic::PlatformLogger.debug("Collecting SNAT Pool stats")
|
153
199
|
snatpool = NewRelic::F5Plugin::SnatPools.new snmp
|
154
200
|
|
155
|
-
|
156
|
-
|
201
|
+
if snatpool.get_names
|
202
|
+
snatpool_conns_max = snatpool.get_conns_max
|
203
|
+
snatpool_conns_max.each_key { |m| report_metric m, "conns", snatpool_conns_max[m] } unless snatpool_conns_max.nil?
|
157
204
|
|
158
|
-
|
159
|
-
|
205
|
+
snatpool_conns_current = snatpool.get_conns_current
|
206
|
+
snatpool_conns_current.each_key { |m| report_metric m, "conns", snatpool_conns_current[m] } unless snatpool_conns_current.nil?
|
160
207
|
|
161
|
-
|
162
|
-
|
208
|
+
snatpool_conns_total = snatpool.get_conns_total
|
209
|
+
snatpool_conns_total.each_key { |m| report_counter_metric m, "conn/sec", snatpool_conns_total[m] } unless snatpool_conns_total.nil?
|
163
210
|
|
164
|
-
|
165
|
-
|
211
|
+
snatpool_throughput_in = snatpool.get_throughput_in
|
212
|
+
snatpool_throughput_in.each_key { |m| report_counter_metric m, "bits/sec", snatpool_throughput_in[m] } unless snatpool_throughput_in.nil?
|
166
213
|
|
167
|
-
|
168
|
-
|
214
|
+
snatpool_throughput_out = snatpool.get_throughput_out
|
215
|
+
snatpool_throughput_out.each_key { |m| report_counter_metric m, "bits/sec", snatpool_throughput_out[m] } unless snatpool_throughput_out.nil?
|
169
216
|
|
170
|
-
|
171
|
-
|
217
|
+
snatpool_packets_in = snatpool.get_packets_in
|
218
|
+
snatpool_packets_in.each_key { |m| report_counter_metric m, "pkts/sec", snatpool_packets_in[m] } unless snatpool_packets_in.nil?
|
219
|
+
|
220
|
+
snatpool_packets_out = snatpool.get_packets_out
|
221
|
+
snatpool_packets_out.each_key { |m| report_counter_metric m, "pkts/sec", snatpool_packets_out[m] } unless snatpool_packets_out.nil?
|
222
|
+
end
|
172
223
|
|
173
|
-
snatpool_packets_out = snatpool.get_packets_out
|
174
|
-
snatpool_packets_out.each_key { |m| report_counter_metric m, "pkts/sec", snatpool_packets_out[m] } unless snatpool_packets_out.nil?
|
175
224
|
|
176
225
|
#
|
177
226
|
# Cleanup snmp connection
|
@@ -0,0 +1,134 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'newrelic_plugin'
|
4
|
+
require 'snmp'
|
5
|
+
|
6
|
+
#LtmRuleEventStatEntry
|
7
|
+
# ltmRuleEventStatName LongDisplayString,
|
8
|
+
# ltmRuleEventStatEventType LongDisplayString,
|
9
|
+
# ltmRuleEventStatPriority INTEGER,
|
10
|
+
# ltmRuleEventStatFailures Integer32,
|
11
|
+
# ltmRuleEventStatAborts Integer32,
|
12
|
+
# ltmRuleEventStatTotalExecutions Integer32,
|
13
|
+
# ltmRuleEventStatAvgCycles Integer32,
|
14
|
+
# ltmRuleEventStatMaxCycles Integer32,
|
15
|
+
# ltmRuleEventStatMinCycles Integer32
|
16
|
+
|
17
|
+
|
18
|
+
module NewRelic
|
19
|
+
module F5Plugin
|
20
|
+
|
21
|
+
class Rules
|
22
|
+
attr_accessor :rule_names, :snmp_manager
|
23
|
+
|
24
|
+
OID_LTM_RULES = "1.3.6.1.4.1.3375.2.2.8"
|
25
|
+
OID_LTM_RULE_STAT = "#{OID_LTM_RULES}.3"
|
26
|
+
OID_LTM_RULE_ENTRY = "#{OID_LTM_RULE_STAT}.3.1"
|
27
|
+
OID_LTM_RULE_STAT_NAME = "#{OID_LTM_RULE_ENTRY}.1"
|
28
|
+
OID_LTM_RULE_STAT_TYPE = "#{OID_LTM_RULE_ENTRY}.2"
|
29
|
+
OID_LTM_RULE_STAT_FAILURES = "#{OID_LTM_RULE_ENTRY}.4"
|
30
|
+
OID_LTM_RULE_STAT_ABORTS = "#{OID_LTM_RULE_ENTRY}.5"
|
31
|
+
OID_LTM_RULE_STAT_TOT_EXEC = "#{OID_LTM_RULE_ENTRY}.6"
|
32
|
+
OID_LTM_RULE_STAT_AVG_CYCLES = "#{OID_LTM_RULE_ENTRY}.7"
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
#
|
37
|
+
# Init
|
38
|
+
#
|
39
|
+
def initialize(snmp = nil)
|
40
|
+
@rule_names = [ ]
|
41
|
+
|
42
|
+
if snmp
|
43
|
+
@snmp_manager = snmp
|
44
|
+
else
|
45
|
+
@snmp_manager = nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
#
|
52
|
+
# Get the list of iRule names
|
53
|
+
#
|
54
|
+
def get_names(snmp = nil)
|
55
|
+
snmp = snmp_manager unless snmp
|
56
|
+
|
57
|
+
if snmp
|
58
|
+
@rule_names.clear
|
59
|
+
|
60
|
+
begin
|
61
|
+
snmp.walk([OID_LTM_RULE_STAT_NAME, OID_LTM_RULE_STAT_TYPE]) do |rule, func|
|
62
|
+
@rule_names.push("#{rule.value}/#{func.value}")
|
63
|
+
end
|
64
|
+
rescue Exception => e
|
65
|
+
NewRelic::PlatformLogger.error("Unable to gather iRule names with error: #{e}")
|
66
|
+
end
|
67
|
+
|
68
|
+
NewRelic::PlatformLogger.debug("Rules: Found #{@rule_names.size} iRules")
|
69
|
+
return @rule_names
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
#
|
76
|
+
# Gather Total iRule Executions
|
77
|
+
#
|
78
|
+
def get_executions(snmp = nil)
|
79
|
+
snmp = snmp_manager unless snmp
|
80
|
+
|
81
|
+
get_names(snmp) if @rule_names.empty?
|
82
|
+
res = gather_snmp_metrics_by_name("Rules/Executions", @rule_names, OID_LTM_RULE_STAT_TOT_EXEC, snmp)
|
83
|
+
NewRelic::PlatformLogger.debug("Rules: Got #{res.size}/#{@rule_names.size} Execution metrics")
|
84
|
+
return res
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
#
|
90
|
+
# Gather Total iRule Failures
|
91
|
+
#
|
92
|
+
def get_failures(snmp = nil)
|
93
|
+
snmp = snmp_manager unless snmp
|
94
|
+
|
95
|
+
get_names(snmp) if @rule_names.empty?
|
96
|
+
res = gather_snmp_metrics_by_name("Rules/Failures", @rule_names, OID_LTM_RULE_STAT_FAILURES, snmp)
|
97
|
+
NewRelic::PlatformLogger.debug("Rules: Got #{res.size}/#{@rule_names.size} Failure metrics")
|
98
|
+
return res
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
#
|
104
|
+
# Gather Total iRule Aborts
|
105
|
+
#
|
106
|
+
def get_aborts(snmp = nil)
|
107
|
+
snmp = snmp_manager unless snmp
|
108
|
+
|
109
|
+
get_names(snmp) if @rule_names.empty?
|
110
|
+
res = gather_snmp_metrics_by_name("Rules/Aborts", @rule_names, OID_LTM_RULE_STAT_ABORTS, snmp)
|
111
|
+
NewRelic::PlatformLogger.debug("Rules: Got #{res.size}/#{@rule_names.size} Abort metrics")
|
112
|
+
return res
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
|
117
|
+
#
|
118
|
+
# Gather Average iRule execution time (in cycles)
|
119
|
+
#
|
120
|
+
def get_average_cycles(snmp = nil)
|
121
|
+
snmp = snmp_manager unless snmp
|
122
|
+
|
123
|
+
get_names(snmp) if @rule_names.empty?
|
124
|
+
res = gather_snmp_metrics_by_name("Rules/Time", @rule_names, OID_LTM_RULE_STAT_AVG_CYCLES, snmp)
|
125
|
+
NewRelic::PlatformLogger.debug("Rules: Got #{res.size}/#{@rule_names.size} Abort metrics")
|
126
|
+
return res
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
data/lib/newrelic_f5_plugin.rb
CHANGED
@@ -3,6 +3,7 @@ require 'newrelic_f5_plugin/util'
|
|
3
3
|
require 'newrelic_f5_plugin/device'
|
4
4
|
require 'newrelic_f5_plugin/nodes'
|
5
5
|
require 'newrelic_f5_plugin/pools'
|
6
|
+
require 'newrelic_f5_plugin/rules'
|
6
7
|
require 'newrelic_f5_plugin/snatpools'
|
7
8
|
require 'newrelic_f5_plugin/virtuals'
|
8
9
|
require 'newrelic_f5_plugin/agent'
|
data/newrelic_f5_plugin.gemspec
CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
|
|
13
13
|
## If your rubyforge_project name is different, then edit it and comment out
|
14
14
|
## the sub! line in the Rakefile
|
15
15
|
s.name = 'newrelic_f5_plugin'
|
16
|
-
s.version = '1.0.
|
17
|
-
s.date = '2014-
|
16
|
+
s.version = '1.0.10'
|
17
|
+
s.date = '2014-02-03'
|
18
18
|
s.rubyforge_project = 'newrelic_f5_plugin'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
@@ -78,6 +78,7 @@ to find out how to install and run the plugin agent.
|
|
78
78
|
lib/newrelic_f5_plugin/device.rb
|
79
79
|
lib/newrelic_f5_plugin/nodes.rb
|
80
80
|
lib/newrelic_f5_plugin/pools.rb
|
81
|
+
lib/newrelic_f5_plugin/rules.rb
|
81
82
|
lib/newrelic_f5_plugin/snatpools.rb
|
82
83
|
lib/newrelic_f5_plugin/util.rb
|
83
84
|
lib/newrelic_f5_plugin/virtuals.rb
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: newrelic_f5_plugin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.10
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-02-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: newrelic_plugin
|
@@ -69,6 +69,7 @@ files:
|
|
69
69
|
- lib/newrelic_f5_plugin/device.rb
|
70
70
|
- lib/newrelic_f5_plugin/nodes.rb
|
71
71
|
- lib/newrelic_f5_plugin/pools.rb
|
72
|
+
- lib/newrelic_f5_plugin/rules.rb
|
72
73
|
- lib/newrelic_f5_plugin/snatpools.rb
|
73
74
|
- lib/newrelic_f5_plugin/util.rb
|
74
75
|
- lib/newrelic_f5_plugin/virtuals.rb
|