newrelic_f5_plugin 1.0.9 → 1.0.10

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 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