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 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.9'
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
- virtual_conns_current = vs.get_conns_current
115
- virtual_conns_current.each_key { |m| report_metric m, "conns", virtual_conns_current[m] } unless virtual_conns_current.nil?
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
- virtual_conns_total = vs.get_conns_total
118
- virtual_conns_total.each_key { |m| report_counter_metric m, "conn/sec", virtual_conns_total[m] } unless virtual_conns_total.nil?
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
- virtual_throughput_in = vs.get_throughput_in
121
- virtual_throughput_in.each_key { |m| report_counter_metric m, "bits/sec", virtual_throughput_in[m] } unless virtual_throughput_in.nil?
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
- virtual_throughput_out = vs.get_throughput_out
124
- virtual_throughput_out.each_key { |m| report_counter_metric m, "bits/sec", virtual_throughput_out[m] } unless virtual_throughput_out.nil?
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
- virtual_cpu_usage_1m = vs.get_cpu_usage_1m
127
- virtual_cpu_usage_1m.each_key { |m| report_metric m, "%", virtual_cpu_usage_1m[m] } unless virtual_cpu_usage_1m.nil?
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
- pool_conns_current = pool.get_conns_current
138
- pool_conns_current.each_key { |m| report_metric m, "conns", pool_conns_current[m] } unless pool_conns_current.nil?
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
- pool_conns_total = pool.get_conns_total
141
- pool_conns_total.each_key { |m| report_counter_metric m, "conn/sec", pool_conns_total[m] } unless pool_conns_total.nil?
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
- pool_throughput_in = pool.get_throughput_in
144
- pool_throughput_in.each_key { |m| report_counter_metric m, "bits/sec", pool_throughput_in[m] } unless pool_throughput_in.nil?
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
- snatpool_conns_max = snatpool.get_conns_max
156
- snatpool_conns_max.each_key { |m| report_metric m, "conns", snatpool_conns_max[m] } unless snatpool_conns_max.nil?
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
- snatpool_conns_current = snatpool.get_conns_current
159
- snatpool_conns_current.each_key { |m| report_metric m, "conns", snatpool_conns_current[m] } unless snatpool_conns_current.nil?
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
- snatpool_conns_total = snatpool.get_conns_total
162
- snatpool_conns_total.each_key { |m| report_counter_metric m, "conn/sec", snatpool_conns_total[m] } unless snatpool_conns_total.nil?
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
- snatpool_throughput_in = snatpool.get_throughput_in
165
- snatpool_throughput_in.each_key { |m| report_counter_metric m, "bits/sec", snatpool_throughput_in[m] } unless snatpool_throughput_in.nil?
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
- snatpool_throughput_out = snatpool.get_throughput_out
168
- snatpool_throughput_out.each_key { |m| report_counter_metric m, "bits/sec", snatpool_throughput_out[m] } unless snatpool_throughput_out.nil?
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
- snatpool_packets_in = snatpool.get_packets_in
171
- snatpool_packets_in.each_key { |m| report_counter_metric m, "pkts/sec", snatpool_packets_in[m] } unless snatpool_packets_in.nil?
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
+
@@ -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'
@@ -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.9'
17
- s.date = '2014-01-21'
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.9
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-01-21 00:00:00.000000000 Z
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