riemann-tools-dgvz 0.2.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/riemann-riak ADDED
@@ -0,0 +1,300 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Forwards information on a Riak node to Riemann.
4
+
5
+ require File.expand_path('../../lib/riemann/tools', __FILE__)
6
+
7
+ require 'net/http'
8
+ require 'net/https'
9
+ require 'yajl/json_gem'
10
+
11
+ class Riemann::Tools::Riak
12
+ include Riemann::Tools
13
+
14
+ opt :riak_host, "Riak host for stats <IP> or SSL http(s)://<IP>", :default => Socket.gethostname
15
+ opt :data_dir, "Riak data directory", :default => '/var/lib/riak'
16
+ opt :stats_port, "Riak HTTP port for stats", :default => 8098
17
+ opt :stats_path, "Riak HTTP stats path", :default => '/stats'
18
+ opt :node_name, "Riak erlang node name", :default => "riak@#{Socket.gethostname}"
19
+ opt :cookie, "Riak cookie to use", :default => "riak"
20
+
21
+ opt :get_50_warning, "FSM 50% get time warning threshold (ms)", :default => 1000
22
+ opt :put_50_warning, "FSM 50% put time warning threshold (ms)", :default => 1000
23
+ opt :get_95_warning, "FSM 95% get time warning threshold (ms)", :default => 2000
24
+ opt :put_95_warning, "FSM 95% put time warning threshold (ms)", :default => 2000
25
+ opt :get_99_warning, "FSM 99% get time warning threshold (ms)", :default => 10000
26
+ opt :put_99_warning, "FSM 99% put time warning threshold (ms)", :default => 10000
27
+
28
+ def initialize
29
+ detect_features
30
+
31
+ @httpstatus = true
32
+ # What's going on here? --aphyr
33
+ if
34
+ begin
35
+ uri = URI.parse(opts[:riak_host])
36
+ if uri.host == nil
37
+ uri.host = opts[:riak_host]
38
+ end
39
+ http = Net::HTTP.new(uri.host, opts[:stats_port])
40
+ http.use_ssl = uri.scheme == 'https'
41
+ if http.use_ssl?
42
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
43
+ end
44
+ http.start do |http|
45
+ http.get opts[:stats_path]
46
+ end
47
+ rescue => e
48
+ @httpstatus = false
49
+ end
50
+ end
51
+
52
+ # we're going to override the emulator setting to allow users to
53
+ # dynamically input the cookie
54
+ # this is done only once - hopefully it doesn't get overridden.
55
+ ENV['ERL_AFLAGS'] = "-setcookie #{opts[:cookie]}"
56
+ end
57
+
58
+ # Identifies whether escript and riak-admin are installed
59
+ def detect_features
60
+ @escript = true # Whether escript is present on this machine
61
+ @riakadmin = true # Whether riak-admin is present
62
+
63
+ if `which escript` =~ /^\s*$/
64
+ @escript = false
65
+ end
66
+
67
+ if `which riak-admin` =~ /^\s*$/
68
+ @riakadmin = false
69
+ end
70
+ end
71
+
72
+ def check_ring
73
+ if @escript
74
+ str = `#{File.expand_path(File.dirname(__FILE__))}/riemann-riak-ring #{opts[:node_name]}`.chomp
75
+ elsif @riakadmin
76
+ str = `riak-admin ringready`
77
+ end
78
+
79
+ if str =~ /^TRUE/
80
+ report(
81
+ :host => opts[:riak_host],
82
+ :service => 'riak ring',
83
+ :state => 'ok',
84
+ :description => str
85
+ )
86
+ else
87
+ report(
88
+ :host => opts[:riak_host],
89
+ :service => 'riak ring',
90
+ :state => 'warning',
91
+ :description => str
92
+ )
93
+ end
94
+ end
95
+
96
+ def check_keys
97
+ keys = `#{File.expand_path(File.dirname(__FILE__))}/riemann-riak-keys #{opts[:node_name]}`.chomp
98
+ if keys =~ /^\d+$/
99
+ report(
100
+ :host => opts[:riak_host],
101
+ :service => 'riak keys',
102
+ :state => 'ok',
103
+ :metric => keys.to_i,
104
+ :description => keys
105
+ )
106
+ else
107
+ report(
108
+ :host => opts[:riak_host],
109
+ :service => 'riak keys',
110
+ :state => 'unknown',
111
+ :description => keys
112
+ )
113
+ end
114
+ end
115
+
116
+ def check_disk
117
+ gb = `du -Ls #{opts[:data_dir]}`.split(/\s+/).first.to_i / (1024.0**2)
118
+ report(
119
+ :host => opts[:riak_host],
120
+ :service => 'riak disk',
121
+ :state => 'ok',
122
+ :metric => gb,
123
+ :description => "#{gb} GB in #{opts[:data_dir]}"
124
+ )
125
+ end
126
+
127
+ # Returns the riak stat for the given fsm type and percentile.
128
+ def fsm_stat(type, property, percentile)
129
+ "node_#{type}_fsm_#{property}_#{percentile == 50 ? 'median' : percentile}"
130
+ end
131
+
132
+ # Returns the alerts state for the given fsm.
133
+ def fsm_state(type, percentile, val)
134
+ limit = opts["#{type}_#{percentile}_warning".to_sym]
135
+ case val
136
+ when 0 .. limit
137
+ 'ok'
138
+ when limit .. limit * 2
139
+ 'warning'
140
+ else
141
+ 'critical'
142
+ end
143
+ end
144
+
145
+ # Get current stats via HTTP
146
+ def stats_http
147
+ begin
148
+ uri = URI.parse(opts[:riak_host])
149
+ if uri.host == nil
150
+ uri.host = opts[:riak_host]
151
+ end
152
+ http = Net::HTTP.new(uri.host, opts[:stats_port])
153
+ http.use_ssl = uri.scheme == 'https'
154
+ if http.use_ssl?
155
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
156
+ end
157
+ res = http.start do |http|
158
+ http.get opts[:stats_path]
159
+ end
160
+ rescue => e
161
+ report(
162
+ :host => opts[:riak_host],
163
+ :service => 'riak',
164
+ :state => 'critical',
165
+ :description => "error fetching #{opts[:riak_host]}:#{opts[:stats_port]} #{e.class}, #{e.message}"
166
+ )
167
+ raise
168
+ end
169
+
170
+ if res.code.to_i == 200
171
+ return JSON.parse(res.body)
172
+ else
173
+ report(
174
+ :host => opts[:riak_host],
175
+ :service => 'riak',
176
+ :state => 'critical',
177
+ :description => "stats returned HTTP #{res.code}:\n\n#{res.body}"
178
+ )
179
+ raise "Can't fetch stats via HTTP: #{res.core}:\n\n#{res.body}"
180
+ end
181
+ end
182
+
183
+ # Get current stats via riak-admin
184
+ def stats_riak_admin
185
+ str = `riak-admin status`
186
+ raise "riak-admin failed" unless $? == 0
187
+ Hash[str.split(/\n/).map{|i| i.split(/ : /)}]
188
+ end
189
+
190
+ # Get current stats as a hash
191
+ def stats
192
+ if @httpstatus
193
+ stats_http
194
+ elsif @riakadmin
195
+ stats_riak_admin
196
+ else
197
+ report(
198
+ :host => opts[:riak_host],
199
+ :service => 'riak',
200
+ :state => 'critical',
201
+ :description => "No mechanism for fetching Riak stats: neither HTTP nor riak-admin available."
202
+ )
203
+ raise "No mechanism for fetching Riak stats: neither HTTP nor riak-admin available."
204
+ end
205
+ end
206
+
207
+ def core_services
208
+ ['vnode_gets',
209
+ 'vnode_puts',
210
+ 'node_gets',
211
+ 'node_puts',
212
+ 'node_gets_set',
213
+ 'node_puts_set',
214
+ 'read_repairs']
215
+ end
216
+
217
+ def fsm_types
218
+ [{'get' => 'time'}, {'put' => 'time'},
219
+ {'get' => 'set_objsize'}]
220
+ end
221
+
222
+ def fsm_percentiles
223
+ [50, 95, 99]
224
+ end
225
+
226
+ # Reports current stats to Riemann
227
+ def check_stats
228
+ begin
229
+ stats = self.stats
230
+ rescue => e
231
+ event = {:state => 'critical',
232
+ :description => e.message,
233
+ :host => opts[:riak_host]}
234
+ # Report errors
235
+ report(event.merge(:service => 'riak'))
236
+ core_services.each do |s|
237
+ report(event.merge(:service => "riak #{s}"))
238
+ end
239
+ fsm_types.each do |typespec|
240
+ typespec.each do |type, prop|
241
+ fsm_percentiles.each do |percentile|
242
+ report(event.merge(:service => "riak #{type} #{prop} #{percentile}"))
243
+ end
244
+ end
245
+ end
246
+ return
247
+ end
248
+
249
+ # Riak itself
250
+ report(
251
+ :host => opts[:riak_host],
252
+ :service => 'riak',
253
+ :state => 'ok'
254
+ )
255
+
256
+ # Gets/puts/rr
257
+ core_services.each do |s|
258
+ report(
259
+ :host => opts[:riak_host],
260
+ :service => "riak #{s}",
261
+ :state => 'ok',
262
+ :metric => stats[s].to_i/60.0,
263
+ :description => "#{stats[s].to_i/60.0}/sec"
264
+ )
265
+ end
266
+
267
+ # FSMs
268
+ fsm_types.each do |typespec|
269
+ typespec.each do |type, prop|
270
+ fsm_percentiles.each do |percentile|
271
+ val = stats[fsm_stat(type, prop, percentile)].to_i || 0
272
+ val = 0 if val == 'undefined'
273
+ val /= 1000.0 if prop == 'time' # Convert us to ms
274
+ if prop == 'time'
275
+ state = fsm_state(type, percentile, val)
276
+ else
277
+ state = "ok"
278
+ end
279
+ report(
280
+ :host => opts[:riak_host],
281
+ :service => "riak #{type} #{prop} #{percentile}",
282
+ :state => state,
283
+ :metric => val,
284
+ :description => "#{val} ms"
285
+ )
286
+ end
287
+ end
288
+ end
289
+ end
290
+
291
+ def tick
292
+ # This can utterly destroy a cluster, so we disable
293
+ # check_keys
294
+ check_stats
295
+ check_ring
296
+ check_disk
297
+ end
298
+ end
299
+
300
+ Riemann::Tools::Riak.run
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env escript
2
+ %%! -name riakstatuscheck@127.0.0.1 -hidden
3
+
4
+ main([]) -> main(["riak@127.0.0.1"]);
5
+ main([Node]) ->
6
+ io:format("~w\n", [
7
+ lists:foldl(
8
+ fun({_VNode, Count}, Sum) -> Sum + Count end,
9
+ 0,
10
+ rpc:call(list_to_atom(Node), riak_kv_bitcask_backend, key_counts, [])
11
+ )
12
+ ]).
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env escript
2
+ %%! -name riakstatuscheck@127.0.0.1 -hidden
3
+
4
+ main([]) -> main(["riak@127.0.0.1"]);
5
+ main([Node]) ->
6
+ io:format("~p\n", [
7
+ rpc:call(list_to_atom(Node), riak_kv_console, ringready, [[]])
8
+ ]).
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Reports varnish stats to Riemann.
4
+
5
+ require File.expand_path('../../lib/riemann/tools', __FILE__)
6
+
7
+ class Riemann::Tools::Varnish
8
+ include Riemann::Tools
9
+
10
+ opt :varnish_host, "Varnish hostname", :default => `hostname`.chomp
11
+
12
+ def initialize
13
+ @vstats = [ "client_conn",
14
+ "client_drop",
15
+ "client_req",
16
+ "cache_hit",
17
+ "cache_miss" ]
18
+ end
19
+
20
+ def tick
21
+ stats = `varnishstat -1 -f #{@vstats.join(",")}`
22
+ stats.each_line do |stat|
23
+ m = stat.split()
24
+ report(
25
+ :host => opts[:varnish_host].dup,
26
+ :service => "varnish #{m[0]}",
27
+ :metric => m[1].to_f,
28
+ :state => "ok",
29
+ :description => "#{m[3..-1].join(' ')}",
30
+ :tags => ["varnish"]
31
+ )
32
+ end
33
+ end
34
+ end
35
+
36
+ Riemann::Tools::Varnish.run
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Gathers zookeeper STATS and submits them to Riemann.
4
+
5
+ require File.expand_path('../../lib/riemann/tools', __FILE__)
6
+
7
+ class Riemann::Tools::Zookeeper
8
+ include Riemann::Tools
9
+ require 'socket'
10
+
11
+ opt :zookeeper_host, "Zookeeper hostname", :default => 'localhost'
12
+ opt :zookeeper_port, "Zookeeper port", :default => 2181
13
+
14
+ def tick
15
+ sock = TCPSocket.new(opts[:zookeeper_host], opts[:zookeeper_port])
16
+ sock.sync = true
17
+ sock.print("mntr")
18
+ sock.flush
19
+
20
+
21
+ data = {}
22
+ while true
23
+ stats = sock.gets
24
+
25
+ break if stats.nil?
26
+
27
+ m = stats.match /^(\w+)\t+(.*)/
28
+
29
+ report(
30
+ :host => opts[ :zookeeper_host].dup,
31
+ :service => "zookeeper #{m[1]}",
32
+ :metric => m[2].to_f,
33
+ :state => 'ok',
34
+ :tags => ['zookeeper']
35
+ )
36
+ end
37
+ sock.close
38
+ end
39
+ end
40
+
41
+ Riemann::Tools::Zookeeper.run
@@ -0,0 +1,107 @@
1
+ module Riemann
2
+ module Tools
3
+ require 'trollop'
4
+ require 'riemann/client'
5
+
6
+ def self.included(base)
7
+ base.instance_eval do
8
+ def run
9
+ new.run
10
+ end
11
+
12
+ def opt(*a)
13
+ a.unshift :opt
14
+ @opts ||= []
15
+ @opts << a
16
+ end
17
+
18
+ def options
19
+ p = Trollop::Parser.new
20
+ @opts.each do |o|
21
+ p.send *o
22
+ end
23
+ Trollop::with_standard_exception_handling(p) do
24
+ p.parse ARGV
25
+ end
26
+ end
27
+
28
+ opt :host, "Riemann host", :default => '127.0.0.1'
29
+ opt :port, "Riemann port", :default => 5555
30
+ opt :event_host, "Event hostname", :type => String
31
+ opt :interval, "Seconds between updates", :default => 5
32
+ opt :tag, "Tag to add to events", :type => String, :multi => true
33
+ opt :ttl, "TTL for events", :type => Integer
34
+ opt :attribute, "Attribute to add to the event", :type => String, :multi => true
35
+ opt :timeout, "Timeout (in seconds) when waiting for acknowledgements", :default => 30
36
+ opt :tcp, "Use TCP transport instead of UDP (improves reliability, slight overhead.", :default => true
37
+ end
38
+ end
39
+
40
+ # Returns parsed options (cached) from command line.
41
+ def options
42
+ @options ||= self.class.options
43
+ end
44
+ alias :opts :options
45
+
46
+ def attributes
47
+ @attributes ||= Hash[options[:attribute].map do |attr|
48
+ k,v = attr.split(/=/)
49
+ if k and v
50
+ [k,v]
51
+ end
52
+ end]
53
+ end
54
+
55
+ def report(event)
56
+ if options[:tag]
57
+ # Work around a bug with beefcake which can't take frozen strings.
58
+ event[:tags] = options[:tag].map(&:dup)
59
+ end
60
+
61
+ event[:ttl] ||= (options[:ttl] || (options[:interval] * 2))
62
+
63
+ if options[:event_host]
64
+ event[:host] = options[:event_host].dup
65
+ end
66
+
67
+ event = event.merge(attributes)
68
+
69
+ riemann << event
70
+ end
71
+
72
+ def new_riemann_client
73
+ r = Riemann::Client.new(
74
+ :host => options[:host],
75
+ :port => options[:port],
76
+ :timeout => options[:timeout]
77
+ )
78
+ if options[:tcp]
79
+ r.tcp
80
+ else
81
+ r
82
+ end
83
+ end
84
+
85
+ def riemann
86
+ @riemann ||= new_riemann_client
87
+ end
88
+ alias :r :riemann
89
+
90
+ def run
91
+ t0 = Time.now
92
+ loop do
93
+ begin
94
+ tick
95
+ rescue => e
96
+ $stderr.puts "#{e.class} #{e}\n#{e.backtrace.join "\n"}"
97
+ end
98
+
99
+ # Sleep.
100
+ sleep(options[:interval] - ((Time.now - t0) % options[:interval]))
101
+ end
102
+ end
103
+
104
+ def tick
105
+ end
106
+ end
107
+ end
metadata ADDED
@@ -0,0 +1,210 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: riemann-tools-dgvz
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Matt Palmer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-12-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: riemann-client
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.2.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.2.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: trollop
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 1.16.2
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 1.16.2
46
+ - !ruby/object:Gem::Dependency
47
+ name: munin-ruby
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.2.1
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.2.1
62
+ - !ruby/object:Gem::Dependency
63
+ name: yajl-ruby
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: 1.1.0
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: 1.1.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: fog
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 1.4.0
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 1.4.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: faraday
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: 0.8.5
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: 0.8.5
110
+ - !ruby/object:Gem::Dependency
111
+ name: nokogiri
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: 1.5.6
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: 1.5.6
126
+ description: This is a gem with some Digivizer-specific enhancements.
127
+ email: mpalmer@hezmatt.org
128
+ executables:
129
+ - riemann-fd
130
+ - riemann-elb-metrics
131
+ - riemann-elasticsearch
132
+ - riemann-cloudant
133
+ - riemann-rabbitmq
134
+ - riemann-riak-keys
135
+ - riemann-aws-status
136
+ - riemann-bench
137
+ - riemann-munin
138
+ - riemann-kvminstance
139
+ - riemann-memcached
140
+ - riemann-apache-status
141
+ - riemann-haproxy
142
+ - riemann-zookeeper
143
+ - riemann-nginx-status
144
+ - riemann-riak-ring
145
+ - riemann-aws-billing
146
+ - riemann-proc
147
+ - riemann-freeswitch
148
+ - riemann-net
149
+ - riemann-diskstats
150
+ - riemann-riak
151
+ - riemann-resmon
152
+ - riemann-varnish
153
+ - riemann-health
154
+ extensions: []
155
+ extra_rdoc_files: []
156
+ files:
157
+ - lib/riemann/tools.rb
158
+ - bin/riemann-apache-status
159
+ - bin/riemann-aws-billing
160
+ - bin/riemann-aws-status
161
+ - bin/riemann-bench
162
+ - bin/riemann-cloudant
163
+ - bin/riemann-diskstats
164
+ - bin/riemann-elasticsearch
165
+ - bin/riemann-elb-metrics
166
+ - bin/riemann-fd
167
+ - bin/riemann-freeswitch
168
+ - bin/riemann-haproxy
169
+ - bin/riemann-health
170
+ - bin/riemann-kvminstance
171
+ - bin/riemann-memcached
172
+ - bin/riemann-munin
173
+ - bin/riemann-net
174
+ - bin/riemann-nginx-status
175
+ - bin/riemann-proc
176
+ - bin/riemann-rabbitmq
177
+ - bin/riemann-resmon
178
+ - bin/riemann-riak
179
+ - bin/riemann-riak-keys
180
+ - bin/riemann-riak-ring
181
+ - bin/riemann-varnish
182
+ - bin/riemann-zookeeper
183
+ - LICENSE
184
+ - README.markdown
185
+ homepage: https://github.com/dgvz/riemann-tools
186
+ licenses:
187
+ - MIT
188
+ post_install_message:
189
+ rdoc_options: []
190
+ require_paths:
191
+ - lib
192
+ required_ruby_version: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ! '>='
196
+ - !ruby/object:Gem::Version
197
+ version: 1.8.7
198
+ required_rubygems_version: !ruby/object:Gem::Requirement
199
+ none: false
200
+ requirements:
201
+ - - ! '>='
202
+ - !ruby/object:Gem::Version
203
+ version: '0'
204
+ requirements: []
205
+ rubyforge_project: riemann-tools
206
+ rubygems_version: 1.8.23
207
+ signing_key:
208
+ specification_version: 3
209
+ summary: Utilities which submit events to Riemann.
210
+ test_files: []