sensu 0.9.5 → 0.9.6.beta

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/README.org CHANGED
@@ -1,46 +1,12 @@
1
- * Welcome to Sensu
2
- Sensu, a monitoring framework that aims to be simple, malleable, and scalable.
1
+ * Sensu
2
+ A monitoring framework that aims to be simple, malleable, and scalable.
3
3
 
4
- [[https://github.com/sonian/sensu/raw/master/sensu-logo.png]]
4
+ [[https://github.com/sensu/sensu/raw/master/sensu-logo.png]]
5
5
 
6
- [[http://portertech.ca/2011/11/01/sensu-a-monitoring-framework][Blog post]]
6
+ [[https://secure.travis-ci.org/sensu/sensu.png]]
7
7
 
8
- [[http://www.sonian.com/cloud-tools/cloud-monitoring-sensu/][Homepage]]
9
- * Documentation
10
- - [[https://github.com/sonian/sensu/wiki][Sensu Wiki]].
11
- - [[http://joemiller.me/2012/01/19/getting-started-with-the-sensu-monitoring-framework/][Getting Started]]
12
- - [[http://joemiller.me/2012/01/24/re-use-nagios-plugins-in-sensu-for-quick-profit/][How to reuse your existing Nagios plugins]]
13
- - [[http://joemiller.me/2012/02/02/sensu-and-graphite/][Sensu and Graphite]]
14
- * Other Projects
15
- - [[https://github.com/sonian/sensu-community-plugins][Sensu Community Plugins]]
16
- - [[https://github.com/sonian/sensu-dashboard][Sensu Dashboard]]
17
- - [[https://github.com/sonian/sensu-plugin][Sensu Plugin & Handler Helper]]
18
- * License
8
+ [[https://gemnasium.com/portertech/sensu.png]]
9
+ ** Documentation
10
+ Please refer to the [[https://github.com/sensu/sensu/wiki][Sensu Wiki]].
11
+ ** License
19
12
  Sensu is released under the [[https://github.com/sonian/sensu/blob/master/MIT-LICENSE.txt][MIT license]].
20
- * Contributing
21
- - [[http://help.github.com/fork-a-repo/][Fork]] Sensu
22
- - Use a [[https://github.com/dchelimsky/rspec/wiki/Topic-Branches][topic branch]]
23
- - Create a [[http://help.github.com/send-pull-requests/][pull request]]
24
-
25
- Keep it simple.
26
- ** Testing
27
- *** Travis CI
28
- [[https://secure.travis-ci.org/sonian/sensu.png]]
29
- *** System Dependencies
30
- - Ruby (MRI) & Rubygems
31
- - RabbitMQ
32
- - Redis
33
- *** Running
34
- : bundle install
35
- : rake
36
- * Contributors
37
- - [[http://twitter.com/portertech][Sean Porter]]
38
- - [[http://twitter.com/amdprophet][Justin Kolberg]]
39
- - [[http://twitter.com/kartar][James Turnbull]]
40
- - [[http://twitter.com/joshpasqualetto][Josh Pasqualetto]]
41
- - [[http://github.com/lum][Steve Lum]]
42
- - [[http://twitter.com/miller_joe][Joe Miller]]
43
- - [[http://twitter.com/decklin][Decklin Foster]]
44
- - [[http://twitter.com/ohlol][Scott Smith]]
45
- - [[http://twitter.com/webframp][Sean Escriva]]
46
- - [[http://twitter.com/fujin_][AJ Christensen]]
data/bin/sensu-api CHANGED
@@ -1,7 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $: << File.dirname(__FILE__) + '/../lib' unless $:.include?(File.dirname(__FILE__) + '/../lib/')
3
+ unless $:.include?(File.dirname(__FILE__) + '/../lib/')
4
+ $: << File.dirname(__FILE__) + '/../lib'
5
+ end
6
+
4
7
  require 'sensu/api'
5
8
 
6
- options = Sensu::Config.read_arguments(ARGV)
9
+ options = Sensu::CLI.read
7
10
  Sensu::API.run(options)
data/bin/sensu-client CHANGED
@@ -1,7 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $: << File.dirname(__FILE__) + '/../lib' unless $:.include?(File.dirname(__FILE__) + '/../lib/')
3
+ unless $:.include?(File.dirname(__FILE__) + '/../lib/')
4
+ $: << File.dirname(__FILE__) + '/../lib'
5
+ end
6
+
4
7
  require 'sensu/client'
5
8
 
6
- options = Sensu::Config.read_arguments(ARGV)
9
+ options = Sensu::CLI.read
7
10
  Sensu::Client.run(options)
data/bin/sensu-server CHANGED
@@ -1,7 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $: << File.dirname(__FILE__) + '/../lib' unless $:.include?(File.dirname(__FILE__) + '/../lib/')
3
+ unless $:.include?(File.dirname(__FILE__) + '/../lib/')
4
+ $: << File.dirname(__FILE__) + '/../lib'
5
+ end
6
+
4
7
  require 'sensu/server'
5
8
 
6
- options = Sensu::Config.read_arguments(ARGV)
9
+ options = Sensu::CLI.read
7
10
  Sensu::Server.run(options)
data/lib/sensu/api.rb CHANGED
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'config')
1
+ require File.join(File.dirname(__FILE__), 'base')
2
2
 
3
3
  require 'thin'
4
4
  require 'sinatra/async'
@@ -15,7 +15,7 @@ module Sensu
15
15
  self.setup(options)
16
16
 
17
17
  Thin::Logging.silent = true
18
- Thin::Server.start(self, $settings.api.port)
18
+ Thin::Server.start(self, $settings[:api][:port])
19
19
 
20
20
  %w[INT TERM].each do |signal|
21
21
  Signal.trap(signal) do
@@ -26,27 +26,36 @@ module Sensu
26
26
  end
27
27
 
28
28
  def self.setup(options={})
29
- config = Sensu::Config.new(options)
30
- $logger = config.logger
31
- $settings = config.settings
32
- if options[:daemonize]
33
- Process.daemonize
34
- end
35
- if options[:pid_file]
36
- Process.write_pid(options[:pid_file])
37
- end
38
- $logger.debug('[setup] -- connecting to redis')
39
- $redis = Redis.connect($settings.redis.to_hash.symbolize_keys)
40
- $logger.debug('[setup] -- connecting to rabbitmq')
41
- $rabbitmq = AMQP.connect($settings.rabbitmq.to_hash.symbolize_keys)
29
+ base = Sensu::Base.new(options)
30
+ $logger = base.logger
31
+ $settings = base.settings
32
+ $logger.debug('connecting to redis', {
33
+ :settings => $settings[:redis]
34
+ })
35
+ $redis = Redis.connect($settings[:redis])
36
+ $logger.debug('connecting to rabbitmq', {
37
+ :settings => $settings[:rabbitmq]
38
+ })
39
+ $rabbitmq = AMQP.connect($settings[:rabbitmq])
42
40
  $amq = AMQP::Channel.new($rabbitmq)
43
- if $settings.api.user && $settings.api.password
41
+ if $settings[:api][:user] && $settings[:api][:password]
44
42
  use Rack::Auth::Basic do |user, password|
45
- user == $settings.api.user && password == $settings.api.password
43
+ user == $settings[:api][:user] && password == $settings[:api][:password]
46
44
  end
47
45
  end
48
46
  end
49
47
 
48
+ def request_log(env)
49
+ $logger.info([env['REQUEST_METHOD'], env['REQUEST_PATH']].join(' '), {
50
+ :remote_address => env['REMOTE_ADDR'],
51
+ :user_agent => env['HTTP_USER_AGENT'],
52
+ :request_method => env['REQUEST_METHOD'],
53
+ :request_uri => env['REQUEST_URI'],
54
+ :request_body => env['rack.input'].read
55
+ })
56
+ env['rack.input'].rewind
57
+ end
58
+
50
59
  configure do
51
60
  disable :protection
52
61
  end
@@ -60,10 +69,10 @@ module Sensu
60
69
  end
61
70
 
62
71
  aget '/info' do
63
- $logger.debug('[info] -- ' + request.ip + ' -- GET -- request for sensu info')
72
+ request_log(env)
64
73
  response = {
65
74
  :sensu => {
66
- :version => Sensu::VERSION
75
+ :version => VERSION
67
76
  },
68
77
  :health => {
69
78
  :redis => 'ok',
@@ -80,12 +89,12 @@ module Sensu
80
89
  end
81
90
 
82
91
  aget '/clients' do
83
- $logger.debug('[clients] -- ' + request.ip + ' -- GET -- request for client list')
92
+ request_log(env)
84
93
  response = Array.new
85
94
  $redis.smembers('clients').callback do |clients|
86
95
  unless clients.empty?
87
- clients.each_with_index do |client, index|
88
- $redis.get('client:' + client).callback do |client_json|
96
+ clients.each_with_index do |client_name, index|
97
+ $redis.get('client:' + client_name).callback do |client_json|
89
98
  response.push(JSON.parse(client_json))
90
99
  if index == clients.size - 1
91
100
  body response.to_json
@@ -98,9 +107,9 @@ module Sensu
98
107
  end
99
108
  end
100
109
 
101
- aget '/client/:name' do |client|
102
- $logger.debug('[client] -- ' + request.ip + ' -- GET -- request for client -- ' + client)
103
- $redis.get('client:' + client).callback do |client_json|
110
+ aget '/client/:name' do |client_name|
111
+ request_log(env)
112
+ $redis.get('client:' + client_name).callback do |client_json|
104
113
  unless client_json.nil?
105
114
  body client_json
106
115
  else
@@ -110,30 +119,37 @@ module Sensu
110
119
  end
111
120
  end
112
121
 
113
- adelete '/client/:name' do |client|
114
- $logger.debug('[client] -- ' + request.ip + ' -- DELETE -- request for client -- ' + client)
115
- $redis.sismember('clients', client).callback do |client_exists|
116
- if client_exists
117
- $redis.hgetall('events:' + client).callback do |events|
118
- events.keys.each do |check_name|
119
- $logger.info('[client] -- publishing check result to resolve event -- ' + client + ' -- ' + check_name)
120
- check = {
121
- :name => check_name,
122
- :output => 'Client is being removed on request of the API',
123
- :status => 0,
124
- :issued => Time.now.to_i,
125
- :force_resolve => true
122
+ adelete '/client/:name' do |client_name|
123
+ request_log(env)
124
+ $redis.get('client:' + client_name).callback do |client_json|
125
+ unless client_json.nil?
126
+ client = JSON.parse(client_json, :symbolize_names => true)
127
+ $logger.info('deleting client', {
128
+ :client => client
129
+ })
130
+ $redis.hgetall('events:' + client_name).callback do |events|
131
+ events.each_key do |check_name|
132
+ payload = {
133
+ :client => client_name,
134
+ :check => {
135
+ :name => check_name,
136
+ :output => 'Client is being removed on request of the API',
137
+ :status => 0,
138
+ :issued => Time.now.to_i,
139
+ :force_resolve => true
140
+ }
126
141
  }
127
- $amq.queue('results').publish({:client => client, :check => check}.to_json)
142
+ $logger.info('publishing check result', {
143
+ :payload => payload
144
+ })
145
+ $amq.queue('results').publish(payload.to_json)
128
146
  end
129
- $logger.info('[client] -- client will be deleted -- ' + client)
130
147
  EM::Timer.new(5) do
131
- $logger.info('[client] -- deleting client -- ' + client)
132
- $redis.srem('clients', client)
133
- $redis.del('events:' + client)
134
- $redis.del('client:' + client)
135
- $settings.checks.each_key do |check_name|
136
- $redis.del('history:' + client + ':' + check_name)
148
+ $redis.srem('clients', client_name)
149
+ $redis.del('events:' + client_name)
150
+ $redis.del('client:' + client_name)
151
+ $settings[:checks].each_key do |check_name|
152
+ $redis.del('history:' + client_name + ':' + check_name)
137
153
  end
138
154
  end
139
155
  status 204
@@ -147,15 +163,14 @@ module Sensu
147
163
  end
148
164
 
149
165
  aget '/checks' do
150
- $logger.debug('[checks] -- ' + request.ip + ' -- GET -- request for check list')
151
- response = $settings.checks.map { |check, details| details.merge(:name => check) }
152
- body response.to_json
166
+ request_log(env)
167
+ body $settings.checks.to_json
153
168
  end
154
169
 
155
- aget '/check/:name' do |check|
156
- $logger.debug('[check] -- ' + request.ip + ' -- GET -- request for check -- ' + check)
157
- if $settings.checks.key?(check)
158
- response = $settings.checks[check].merge(:name => check)
170
+ aget '/check/:name' do |check_name|
171
+ request_log(env)
172
+ if $settings.check_exists?(check_name)
173
+ response = $settings[:checks][check_name].merge(:name => check_name)
159
174
  body response.to_json
160
175
  else
161
176
  status 404
@@ -164,17 +179,24 @@ module Sensu
164
179
  end
165
180
 
166
181
  apost '/check/request' do
167
- $logger.debug('[check] -- ' + request.ip + ' -- POST -- request to publish a check request')
182
+ request_log(env)
168
183
  begin
169
- post_body = Hashie::Mash.new(JSON.parse(request.body.read))
184
+ post_body = JSON.parse(request.body.read, :symbolize_names => true)
170
185
  rescue JSON::ParserError
171
186
  status 400
172
187
  body ''
173
188
  end
174
- if post_body.check.is_a?(String) && post_body.subscribers.is_a?(Array)
175
- post_body.subscribers.each do |exchange|
176
- $logger.info('[check] -- publishing check request -- ' + post_body.check + ' -- ' + exchange)
177
- $amq.fanout(exchange).publish({:name => post_body.check, :issued => Time.now.to_i}.to_json)
189
+ if post_body[:check].is_a?(String) && post_body[:subscribers].is_a?(Array)
190
+ payload = {
191
+ :name => post_body[:check],
192
+ :issued => Time.now.to_i
193
+ }
194
+ $logger.info('publishing check request', {
195
+ :payload => payload,
196
+ :subscribers => post_body[:subscribers]
197
+ })
198
+ post_body[:subscribers].uniq.each do |exchange_name|
199
+ $amq.fanout(exchange_name).publish(payload.to_json)
178
200
  end
179
201
  status 201
180
202
  else
@@ -184,14 +206,14 @@ module Sensu
184
206
  end
185
207
 
186
208
  aget '/events' do
187
- $logger.debug('[events] -- ' + request.ip + ' -- GET -- request for event list')
209
+ request_log(env)
188
210
  response = Array.new
189
211
  $redis.smembers('clients').callback do |clients|
190
212
  unless clients.empty?
191
- clients.each_with_index do |client, index|
192
- $redis.hgetall('events:' + client).callback do |events|
193
- events.each do |check, details|
194
- response.push(JSON.parse(details).merge(:client => client, :check => check))
213
+ clients.each_with_index do |client_name, index|
214
+ $redis.hgetall('events:' + client_name).callback do |events|
215
+ events.each do |check_name, event_json|
216
+ response.push(JSON.parse(event_json).merge(:client => client_name, :check => check_name))
195
217
  end
196
218
  if index == clients.size - 1
197
219
  body response.to_json
@@ -204,12 +226,12 @@ module Sensu
204
226
  end
205
227
  end
206
228
 
207
- aget '/event/:client/:check' do |client, check|
208
- $logger.debug('[event] -- ' + request.ip + ' -- GET -- request for event -- ' + client + ' -- ' + check)
209
- $redis.hgetall('events:' + client).callback do |events|
210
- event_json = events[check]
229
+ aget '/event/:client/:check' do |client_name, check_name|
230
+ request_log(env)
231
+ $redis.hgetall('events:' + client_name).callback do |events|
232
+ event_json = events[check_name]
211
233
  unless event_json.nil?
212
- response = JSON.parse(event_json).merge(:client => client, :check => check)
234
+ response = JSON.parse(event_json).merge(:client => client_name, :check => check_name)
213
235
  body response.to_json
214
236
  else
215
237
  status 404
@@ -219,25 +241,30 @@ module Sensu
219
241
  end
220
242
 
221
243
  apost '/event/resolve' do
222
- $logger.debug('[event] -- ' + request.ip + ' -- POST -- request to resolve event')
244
+ request_log(env)
223
245
  begin
224
- post_body = Hashie::Mash.new(JSON.parse(request.body.read))
246
+ post_body = JSON.parse(request.body.read, :symbolize_names => true)
225
247
  rescue JSON::ParserError
226
248
  status 400
227
249
  body ''
228
250
  end
229
- if post_body.client.is_a?(String) && post_body.check.is_a?(String)
230
- $redis.hgetall('events:' + post_body.client).callback do |events|
231
- if events.include?(post_body.check)
232
- $logger.info('[event] -- publishing check result to resolve event -- ' + post_body.client + ' -- ' + post_body.check)
233
- check = {
234
- :name => post_body.check,
235
- :output => 'Resolving on request of the API',
236
- :status => 0,
237
- :issued => Time.now.to_i,
238
- :force_resolve => true
251
+ if post_body[:client].is_a?(String) && post_body[:check].is_a?(String)
252
+ $redis.hgetall('events:' + post_body[:client]).callback do |events|
253
+ if events.include?(post_body[:check])
254
+ payload = {
255
+ :client => post_body[:client],
256
+ :check => {
257
+ :name => post_body[:check],
258
+ :output => 'Resolving on request of the API',
259
+ :status => 0,
260
+ :issued => Time.now.to_i,
261
+ :force_resolve => true
262
+ }
239
263
  }
240
- $amq.queue('results').publish({:client => post_body.client, :check => check}.to_json)
264
+ $logger.info('publishing check result', {
265
+ :payload => payload
266
+ })
267
+ $amq.queue('results').publish(payload.to_json)
241
268
  status 201
242
269
  else
243
270
  status 404
@@ -251,7 +278,7 @@ module Sensu
251
278
  end
252
279
 
253
280
  apost '/stash/*' do |path|
254
- $logger.debug('[stash] -- ' + request.ip + ' -- POST -- request for stash -- ' + path)
281
+ request_log(env)
255
282
  begin
256
283
  post_body = JSON.parse(request.body.read)
257
284
  rescue JSON::ParserError
@@ -267,7 +294,7 @@ module Sensu
267
294
  end
268
295
 
269
296
  aget '/stash/*' do |path|
270
- $logger.debug('[stash] -- ' + request.ip + ' -- GET -- request for stash -- ' + path)
297
+ request_log(env)
271
298
  $redis.get('stash:' + path).callback do |stash_json|
272
299
  if stash_json.nil?
273
300
  status 404
@@ -279,7 +306,7 @@ module Sensu
279
306
  end
280
307
 
281
308
  adelete '/stash/*' do |path|
282
- $logger.debug('[stash] -- ' + request.ip + ' -- DELETE -- request for stash -- ' + path)
309
+ request_log(env)
283
310
  $redis.exists('stash:' + path).callback do |stash_exists|
284
311
  if stash_exists
285
312
  $redis.srem('stashes', path).callback do
@@ -296,14 +323,14 @@ module Sensu
296
323
  end
297
324
 
298
325
  aget '/stashes' do
299
- $logger.debug('[stashes] -- ' + request.ip + ' -- GET -- request for list of stashes')
326
+ request_log(env)
300
327
  $redis.smembers('stashes') do |stashes|
301
328
  body stashes.to_json
302
329
  end
303
330
  end
304
331
 
305
332
  apost '/stashes' do
306
- $logger.debug('[stashes] -- ' + request.ip + ' -- POST -- request for multiple stashes')
333
+ request_log(env)
307
334
  begin
308
335
  post_body = JSON.parse(request.body.read)
309
336
  rescue JSON::ParserError
@@ -330,20 +357,20 @@ module Sensu
330
357
 
331
358
  def self.run_test(options={}, &block)
332
359
  self.setup(options)
333
- $settings.client.timestamp = Time.now.to_i
334
- $redis.set('client:' + $settings.client.name, $settings.client.to_json).callback do
335
- $redis.sadd('clients', $settings.client.name).callback do
336
- $redis.hset('events:' + $settings.client.name, 'test', {
360
+ $settings[:client][:timestamp] = Time.now.to_i
361
+ $redis.set('client:' + $settings[:client][:name], $settings[:client].to_json).callback do
362
+ $redis.sadd('clients', $settings[:client][:name]).callback do
363
+ $redis.hset('events:' + $settings[:client][:name], 'test', {
337
364
  :output => "CRITICAL\n",
338
365
  :status => 2,
339
- :issued => Time.now.utc.iso8601,
366
+ :issued => Time.now.to_i,
340
367
  :flapping => false,
341
368
  :occurrences => 1
342
369
  }.to_json).callback do
343
370
  $redis.set('stash:test/test', '{"key": "value"}').callback do
344
371
  $redis.sadd('stashes', 'test/test').callback do
345
372
  Thin::Logging.silent = true
346
- Thin::Server.start(self, $settings.api.port)
373
+ Thin::Server.start(self, $settings[:api][:port])
347
374
  block.call
348
375
  end
349
376
  end
@@ -353,8 +380,11 @@ module Sensu
353
380
  end
354
381
 
355
382
  def self.stop(signal)
356
- $logger.warn('[stop] -- stopping sensu api -- ' + signal)
357
- $logger.warn('[stop] -- stopping reactor')
383
+ $logger.warn('received signal', {
384
+ :signal => signal
385
+ })
386
+ $logger.warn('stopping')
387
+ $logger.warn('stopping reactor')
358
388
  EM::PeriodicTimer.new(0.25) do
359
389
  EM::stop_event_loop
360
390
  end