sensu 0.9.6.beta.3 → 0.9.6.beta.4

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/lib/sensu/api.rb CHANGED
@@ -77,7 +77,7 @@ module Sensu
77
77
  aget '/info' do
78
78
  response = {
79
79
  :sensu => {
80
- :version => VERSION
80
+ :version => Sensu::VERSION
81
81
  },
82
82
  :health => {
83
83
  :redis => 'ok',
data/lib/sensu/base.rb CHANGED
@@ -4,6 +4,8 @@ gem 'eventmachine', '~> 1.0.0.beta.4'
4
4
 
5
5
  require 'optparse'
6
6
  require 'json'
7
+ require 'time'
8
+ require 'uri'
7
9
  require 'cabin'
8
10
  require 'amqp'
9
11
 
@@ -21,7 +23,7 @@ module Sensu
21
23
  attr_reader :options, :logger, :settings
22
24
 
23
25
  def initialize(options={})
24
- @options = DEFAULT_OPTIONS.merge(options)
26
+ @options = Sensu::DEFAULT_OPTIONS.merge(options)
25
27
  @logger = Cabin::Channel.get
26
28
  setup_logging
27
29
  setup_settings
@@ -29,7 +31,9 @@ module Sensu
29
31
  end
30
32
 
31
33
  def setup_logging
32
- Sensu::Logger.new(@options)
34
+ logger = Sensu::Logger.new(@options)
35
+ logger.reopen
36
+ logger.setup_traps
33
37
  end
34
38
 
35
39
  def setup_settings
@@ -42,7 +46,7 @@ module Sensu
42
46
  begin
43
47
  @settings.validate
44
48
  rescue => error
45
- @logger.fatal('CONFIG INVALID', {
49
+ @logger.fatal('config invalid', {
46
50
  :error => error.to_s
47
51
  })
48
52
  @logger.fatal('SENSU NOT RUNNING!')
@@ -52,7 +56,14 @@ module Sensu
52
56
  end
53
57
 
54
58
  def setup_process
55
- Sensu::Process.new(@options)
59
+ process = Sensu::Process.new
60
+ if @options[:daemonize]
61
+ process.daemonize
62
+ end
63
+ if @options[:pid_file]
64
+ process.write_pid(@options[:pid_file])
65
+ end
66
+ process.setup_eventmachine
56
67
  end
57
68
  end
58
69
  end
data/lib/sensu/cli.rb CHANGED
@@ -8,7 +8,7 @@ module Sensu
8
8
  exit
9
9
  end
10
10
  opts.on('-V', '--version', 'Display version') do
11
- puts VERSION
11
+ puts Sensu::VERSION
12
12
  exit
13
13
  end
14
14
  opts.on('-c', '--config FILE', 'Sensu JSON config FILE. Default is /etc/sensu/config.json') do |file|
@@ -31,7 +31,7 @@ module Sensu
31
31
  end
32
32
  end
33
33
  optparse.parse!(arguments)
34
- DEFAULT_OPTIONS.merge(options)
34
+ Sensu::DEFAULT_OPTIONS.merge(options)
35
35
  end
36
36
  end
37
37
  end
@@ -1,8 +1,12 @@
1
1
  module Sensu
2
- VERSION = '0.9.6.beta.3'
2
+ unless defined?(Sensu::VERSION)
3
+ VERSION = '0.9.6.beta.4'
4
+ end
3
5
 
4
- DEFAULT_OPTIONS = {
5
- :config_file => '/etc/sensu/config.json',
6
- :config_dir => '/etc/sensu/conf.d'
7
- }
6
+ unless defined?(Sensu::DEFAULT_OPTIONS)
7
+ DEFAULT_OPTIONS = {
8
+ :config_file => '/etc/sensu/config.json',
9
+ :config_dir => '/etc/sensu/conf.d'
10
+ }
11
+ end
8
12
  end
data/lib/sensu/logger.rb CHANGED
@@ -4,26 +4,26 @@ module Sensu
4
4
  @logger = Cabin::Channel.get
5
5
  @logger.subscribe(STDOUT)
6
6
  @logger.level = options[:verbose] ? :debug : options[:log_level] || :info
7
- reopen(options)
8
- setup_traps(options)
7
+ @log_file = options[:log_file]
9
8
  end
10
9
 
11
- def reopen(options={})
12
- unless options[:log_file].nil?
13
- if File.writable?(options[:log_file]) ||
14
- !File.exist?(options[:log_file]) && File.writable?(File.dirname(options[:log_file]))
15
- STDOUT.reopen(options[:log_file], 'a')
10
+ def reopen(file=nil)
11
+ file ||= @log_file
12
+ unless file.nil?
13
+ @log_file = file
14
+ if File.writable?(file) || !File.exist?(file) && File.writable?(File.dirname(file))
15
+ STDOUT.reopen(file, 'a')
16
16
  STDERR.reopen(STDOUT)
17
17
  STDOUT.sync = true
18
18
  else
19
19
  @logger.error('log file is not writable', {
20
- :log_file => options[:log_file]
20
+ :log_file => file
21
21
  })
22
22
  end
23
23
  end
24
24
  end
25
25
 
26
- def setup_traps(options={})
26
+ def setup_traps
27
27
  if Signal.list.include?('USR1')
28
28
  Signal.trap('USR1') do
29
29
  @logger.level = @logger.level == :info ? :debug : :info
@@ -31,7 +31,7 @@ module Sensu
31
31
  end
32
32
  if Signal.list.include?('USR2')
33
33
  Signal.trap('USR2') do
34
- reopen(options)
34
+ reopen(@log_file)
35
35
  end
36
36
  end
37
37
  end
@@ -46,13 +46,26 @@ module Redis
46
46
  end
47
47
  end
48
48
 
49
- def self.connect(options={})
50
- host = options[:host] || 'localhost'
51
- port = options[:port] || 6379
49
+ def self.connect(options)
50
+ options ||= Hash.new
51
+ if options.is_a?(String)
52
+ begin
53
+ uri = URI.parse(options)
54
+ host = uri.host
55
+ port = uri.port || 6379
56
+ password = uri.password
57
+ rescue
58
+ raise('invalid redis url')
59
+ end
60
+ else
61
+ host = options[:host] || 'localhost'
62
+ port = options[:port] || 6379
63
+ password = options[:password]
64
+ end
52
65
  EM::connect(host, port, Redis::Client) do |client|
53
66
  client.redis_host = host
54
67
  client.redis_port = port
55
- client.redis_password = options[:password]
68
+ client.redis_password = password
56
69
  end
57
70
  end
58
71
  end
data/lib/sensu/process.rb CHANGED
@@ -1,25 +1,19 @@
1
1
  module Sensu
2
2
  class Process
3
- def initialize(options={})
3
+ def initialize
4
4
  @logger = Cabin::Channel.get
5
- if options[:daemonize]
6
- daemonize
7
- end
8
- if options[:pid_file]
9
- write_pid(options[:pid_file])
10
- end
11
- setup_eventmachine
12
5
  end
13
6
 
14
- def write_pid(pid_file)
7
+ def write_pid(file)
15
8
  begin
16
- File.open(pid_file, 'w') do |file|
17
- file.puts(::Process.pid)
9
+ File.open(file, 'w') do |pid_file|
10
+ pid_file.puts(::Process.pid)
18
11
  end
19
12
  rescue
20
13
  @logger.fatal('could not write to pid file', {
21
- :pid_file => pid_file
14
+ :pid_file => file
22
15
  })
16
+ @logger.fatal('SENSU NOT RUNNING!')
23
17
  exit 2
24
18
  end
25
19
  end
@@ -31,6 +25,7 @@ module Sensu
31
25
  end
32
26
  unless ::Process.setsid
33
27
  @logger.fatal('cannot detach from controlling terminal')
28
+ @logger.fatal('SENSU NOT RUNNING!')
34
29
  exit 2
35
30
  end
36
31
  Signal.trap('SIGHUP', 'IGNORE')
data/lib/sensu/server.rb CHANGED
@@ -63,6 +63,43 @@ module Sensu
63
63
  end
64
64
  end
65
65
 
66
+ def check_subdued?(check, subdue_type)
67
+ subdue = false
68
+ if check[:subdue].is_a?(Hash)
69
+ if check[:subdue].has_key?(:start) && check[:subdue].has_key?(:end)
70
+ start = Time.parse(check[:subdue][:start])
71
+ stop = Time.parse(check[:subdue][:end])
72
+ if stop < start
73
+ if Time.now < stop
74
+ start = Time.parse('12:00:00 AM')
75
+ else
76
+ stop = Time.parse('11:59:59 PM')
77
+ end
78
+ end
79
+ if Time.now >= start && Time.now <= stop
80
+ subdue = true
81
+ end
82
+ end
83
+ if check[:subdue].has_key?(:days)
84
+ days = check[:subdue][:days].map(&:downcase)
85
+ if days.include?(Time.now.strftime('%A').downcase)
86
+ subdue = true
87
+ end
88
+ end
89
+ if subdue && check[:subdue].has_key?(:exceptions)
90
+ subdue = check[:subdue][:exceptions].none? do |exception|
91
+ Time.now >= Time.parse(exception[:start]) && Time.now <= Time.parse(exception[:end])
92
+ end
93
+ end
94
+ end
95
+ if subdue
96
+ (!check[:subdue].has_key?(:at) && subdue_type == :handler) ||
97
+ (check[:subdue].has_key?(:at) && check[:subdue][:at].to_sym == subdue_type)
98
+ else
99
+ false
100
+ end
101
+ end
102
+
66
103
  def check_handlers(check)
67
104
  handler_list = case
68
105
  when check.has_key?(:handler)
@@ -93,73 +130,75 @@ module Sensu
93
130
  end
94
131
 
95
132
  def handle_event(event)
96
- report = proc do |output|
97
- if output.is_a?(String)
98
- output.split(/\n+/).each do |line|
99
- @logger.info('handler output', {
100
- :output => line
101
- })
102
- end
103
- end
104
- @handlers_in_progress -= 1
105
- end
106
- handlers = check_handlers(event[:check])
107
- handlers.each do |handler|
108
- @logger.debug('handling event', {
109
- :event => event,
110
- :handler => handler
111
- })
112
- @handlers_in_progress += 1
113
- case handler[:type]
114
- when 'pipe'
115
- execute = proc do
116
- begin
117
- IO.popen(handler[:command] + ' 2>&1', 'r+') do |io|
118
- io.write(event.to_json)
119
- io.close_write
120
- io.read
121
- end
122
- rescue Errno::ENOENT => error
123
- @logger.error('handler does not exist', {
124
- :event => event,
125
- :handler => handler,
126
- :error => error.to_s
127
- })
128
- rescue Errno::EPIPE => error
129
- @logger.error('broken pipe', {
130
- :event => event,
131
- :handler => handler,
132
- :error => error.to_s
133
- })
134
- rescue => error
135
- @logger.error('unexpected error', {
136
- :event => event,
137
- :handler => handler,
138
- :error => error.to_s
133
+ unless check_subdued?(event[:check], :handler)
134
+ report = proc do |output|
135
+ if output.is_a?(String)
136
+ output.split(/\n+/).each do |line|
137
+ @logger.info('handler output', {
138
+ :output => line
139
139
  })
140
140
  end
141
141
  end
142
- EM::defer(execute, report)
143
- when 'amqp'
144
- exchange_name = handler[:exchange][:name]
145
- exchange_type = handler[:exchange].has_key?(:type) ? handler[:exchange][:type].to_sym : :direct
146
- exchange_options = handler[:exchange].reject do |key, value|
147
- [:name, :type].include?(key)
148
- end
149
- @logger.debug('publishing event to an amqp exchange', {
150
- :event => event,
151
- :exchange => handler[:exchange]
152
- })
153
- payload = handler[:send_only_check_output] ? event[:check][:output] : event.to_json
154
- unless payload.empty?
155
- @amq.method(exchange_type).call(exchange_name, exchange_options).publish(payload)
156
- end
157
142
  @handlers_in_progress -= 1
158
- when 'set'
159
- @logger.error('handler sets cannot be nested', {
143
+ end
144
+ handlers = check_handlers(event[:check])
145
+ handlers.each do |handler|
146
+ @logger.debug('handling event', {
147
+ :event => event,
160
148
  :handler => handler
161
149
  })
162
- @handlers_in_progress -= 1
150
+ @handlers_in_progress += 1
151
+ case handler[:type]
152
+ when 'pipe'
153
+ execute = proc do
154
+ begin
155
+ IO.popen(handler[:command] + ' 2>&1', 'r+') do |io|
156
+ io.write(event.to_json)
157
+ io.close_write
158
+ io.read
159
+ end
160
+ rescue Errno::ENOENT => error
161
+ @logger.error('handler does not exist', {
162
+ :event => event,
163
+ :handler => handler,
164
+ :error => error.to_s
165
+ })
166
+ rescue Errno::EPIPE => error
167
+ @logger.error('broken pipe', {
168
+ :event => event,
169
+ :handler => handler,
170
+ :error => error.to_s
171
+ })
172
+ rescue => error
173
+ @logger.error('unexpected error', {
174
+ :event => event,
175
+ :handler => handler,
176
+ :error => error.to_s
177
+ })
178
+ end
179
+ end
180
+ EM::defer(execute, report)
181
+ when 'amqp'
182
+ exchange_name = handler[:exchange][:name]
183
+ exchange_type = handler[:exchange].has_key?(:type) ? handler[:exchange][:type].to_sym : :direct
184
+ exchange_options = handler[:exchange].reject do |key, value|
185
+ [:name, :type].include?(key)
186
+ end
187
+ @logger.debug('publishing event to an amqp exchange', {
188
+ :event => event,
189
+ :exchange => handler[:exchange]
190
+ })
191
+ payload = handler[:send_only_check_output] ? event[:check][:output] : event.to_json
192
+ unless payload.empty?
193
+ @amq.method(exchange_type).call(exchange_name, exchange_options).publish(payload)
194
+ end
195
+ @handlers_in_progress -= 1
196
+ when 'set'
197
+ @logger.error('handler sets cannot be nested', {
198
+ :handler => handler
199
+ })
200
+ @handlers_in_progress -= 1
201
+ end
163
202
  end
164
203
  end
165
204
  end
@@ -242,6 +281,7 @@ module Sensu
242
281
  unless check[:auto_resolve] == false && !check[:force_resolve]
243
282
  @redis.hdel('events:' + client[:name], check[:name]).callback do
244
283
  unless check[:handle] == false
284
+ event[:occurrences] = previous_occurrence[:occurrences]
245
285
  event[:action] = 'resolve'
246
286
  handle_event(event)
247
287
  else
@@ -294,17 +334,19 @@ module Sensu
294
334
  @timers << EM::Timer.new(stagger * check_count) do
295
335
  interval = options[:test] ? 0.5 : check[:interval]
296
336
  @timers << EM::PeriodicTimer.new(interval) do
297
- unless @rabbitmq.reconnecting?
298
- payload = {
299
- :name => check[:name],
300
- :issued => Time.now.to_i
301
- }
302
- @logger.info('publishing check request', {
303
- :payload => payload,
304
- :subscribers => check[:subscribers]
305
- })
306
- check[:subscribers].uniq.each do |exchange_name|
307
- @amq.fanout(exchange_name).publish(payload.to_json)
337
+ unless check_subdued?(check, :publisher)
338
+ unless @rabbitmq.reconnecting?
339
+ payload = {
340
+ :name => check[:name],
341
+ :issued => Time.now.to_i
342
+ }
343
+ @logger.info('publishing check request', {
344
+ :payload => payload,
345
+ :subscribers => check[:subscribers]
346
+ })
347
+ check[:subscribers].uniq.each do |exchange_name|
348
+ @amq.fanout(exchange_name).publish(payload.to_json)
349
+ end
308
350
  end
309
351
  end
310
352
  end
@@ -203,6 +203,48 @@ module Sensu
203
203
  raise('handlers must be an array for check: ' + check[:name])
204
204
  end
205
205
  end
206
+ if check.has_key?(:subdue)
207
+ unless check[:subdue].is_a?(Hash)
208
+ raise('subdue must be a hash for check: ' + check[:name])
209
+ end
210
+ if check[:subdue].has_key?(:start) || check[:subdue].has_key?(:end)
211
+ begin
212
+ Time.parse(check[:subdue][:start])
213
+ Time.parse(check[:subdue][:end])
214
+ rescue
215
+ raise('subdue start & end times must be valid for check: ' + check[:name])
216
+ end
217
+ end
218
+ if check[:subdue].has_key?(:days)
219
+ unless check[:subdue][:days].is_a?(Array)
220
+ raise('subdue days must be an array for check: ' + check[:name])
221
+ end
222
+ check[:subdue][:days].each do |day|
223
+ days = %w[sunday monday tuesday wednesday thursday friday saturday]
224
+ unless day.is_a?(String) && days.include?(day.downcase)
225
+ raise('subdue days must be valid days of the week for check: ' + check[:name])
226
+ end
227
+ end
228
+ end
229
+ if check[:subdue].has_key?(:exceptions)
230
+ unless check[:subdue][:exceptions].is_a?(Array)
231
+ raise('subdue exceptions must be an array for check: ' + check[:name])
232
+ end
233
+ check[:subdue][:exceptions].each do |exception|
234
+ unless exception.is_a?(Hash)
235
+ raise('subdue exception items must be a hash for check: ' + check[:name])
236
+ end
237
+ if exception.has_key?(:start) || exception.has_key?(:end)
238
+ begin
239
+ Time.parse(exception[:start])
240
+ Time.parse(exception[:end])
241
+ rescue
242
+ raise('subdue exception start & end times must be valid for check: ' + check[:name])
243
+ end
244
+ end
245
+ end
246
+ end
247
+ end
206
248
  end
207
249
  end
208
250
 
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sensu
3
3
  version: !ruby/object:Gem::Version
4
- hash: 62196229
4
+ hash: 62196235
5
5
  prerelease: true
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
9
  - 6
10
10
  - beta
11
- - 3
12
- version: 0.9.6.beta.3
11
+ - 4
12
+ version: 0.9.6.beta.4
13
13
  platform: ruby
14
14
  authors:
15
15
  - Sean Porter
@@ -18,7 +18,7 @@ autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
20
 
21
- date: 2012-05-04 00:00:00 -07:00
21
+ date: 2012-05-19 00:00:00 -07:00
22
22
  default_executable:
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency