sensu 0.7.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,13 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sensu (0.7.0)
4
+ sensu (0.8.0)
5
5
  amqp (= 0.7.4)
6
6
  async_sinatra
7
7
  em-hiredis
8
8
  em-syslog
9
9
  hashie
10
10
  json
11
+ rack (~> 1.3.4)
11
12
  thin
12
13
  uuidtools
13
14
 
@@ -30,12 +31,12 @@ GEM
30
31
  callsite (~> 0.0.5)
31
32
  eventmachine
32
33
  eventmachine (0.12.10)
33
- hashie (1.1.0)
34
+ hashie (1.2.0)
34
35
  hiredis (0.3.2)
35
36
  json (1.6.1)
36
37
  mime-types (1.16)
37
- minitest (2.6.0)
38
- rack (1.3.4)
38
+ minitest (2.7.0)
39
+ rack (1.3.5)
39
40
  rack-protection (1.1.4)
40
41
  rack
41
42
  rake (0.9.2)
@@ -57,7 +58,7 @@ PLATFORMS
57
58
 
58
59
  DEPENDENCIES
59
60
  em-ventually
60
- minitest
61
+ minitest (~> 2.7.0)
61
62
  rake
62
63
  rest-client
63
64
  sensu!
data/Rakefile CHANGED
@@ -1,10 +1,13 @@
1
1
  require 'bundler/gem_tasks'
2
- require 'rake/testtask'
3
2
 
4
3
  task :default => 'test'
5
4
 
6
- Rake::TestTask.new do |test|
7
- test.pattern = 'test/*_test.rb'
5
+ desc "Run tests"
6
+ task :test do
7
+ require File.join(File.dirname(__FILE__), 'test', 'helper')
8
+ Dir['test/*_test.rb'].each do |test|
9
+ require File.join(File.dirname(__FILE__), test)
10
+ end
8
11
  end
9
12
 
10
13
  desc "Build Sensu for Windows"
data/lib/sensu.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Sensu
2
- VERSION = "0.7.2"
2
+ VERSION = "0.8.0"
3
3
  end
data/lib/sensu/api.rb CHANGED
@@ -11,12 +11,13 @@ module Sensu
11
11
  self.setup(options)
12
12
  self.run!(:port => @settings.api.port)
13
13
 
14
- Signal.trap('INT') do
15
- EM.stop
16
- end
17
-
18
- Signal.trap('TERM') do
19
- EM.stop
14
+ %w[INT TERM].each do |signal|
15
+ Signal.trap(signal) do
16
+ EM.warning('[process] -- ' + signal + ' -- stopping sensu api')
17
+ EM.add_timer(1) do
18
+ EM.stop
19
+ end
20
+ end
20
21
  end
21
22
  end
22
23
  end
@@ -24,7 +25,10 @@ module Sensu
24
25
  def self.setup(options={})
25
26
  config = Sensu::Config.new(options)
26
27
  @settings = config.settings
28
+ EM.syslog_setup(@settings.syslog.host, @settings.syslog.port)
29
+ EM.debug('[setup] -- connecting to redis')
27
30
  set :redis, EM::Hiredis.connect('redis://' + @settings.redis.host + ':' + @settings.redis.port.to_s)
31
+ EM.debug('[setup] -- connecting to rabbitmq')
28
32
  connection = AMQP.connect(@settings.rabbitmq.to_hash.symbolize_keys)
29
33
  set :amq, MQ.new(connection)
30
34
  end
@@ -39,13 +43,14 @@ module Sensu
39
43
  end
40
44
 
41
45
  aget '/clients' do
46
+ EM.debug('[clients] -- ' + request.ip + ' -- GET -- request for client list')
42
47
  current_clients = Array.new
43
48
  conn.redis.smembers('clients').callback do |clients|
44
49
  unless clients.empty?
45
50
  clients.each_with_index do |client, index|
46
51
  conn.redis.get('client:' + client).callback do |client_json|
47
52
  current_clients.push(JSON.parse(client_json))
48
- body current_clients.to_json if index == clients.size-1
53
+ body current_clients.to_json if index == clients.size - 1
49
54
  end
50
55
  end
51
56
  else
@@ -55,6 +60,7 @@ module Sensu
55
60
  end
56
61
 
57
62
  aget '/client/:name' do |client|
63
+ EM.debug('[client] -- ' + request.ip + ' -- GET -- request for client -- ' + client)
58
64
  conn.redis.get('client:' + client).callback do |client_json|
59
65
  status 404 if client_json.nil?
60
66
  body client_json
@@ -62,6 +68,7 @@ module Sensu
62
68
  end
63
69
 
64
70
  adelete '/client/:name' do |client|
71
+ EM.debug('[client] -- ' + request.ip + ' -- DELETE -- request for client -- ' + client)
65
72
  conn.redis.sismember('clients', client).callback do |client_exists|
66
73
  unless client_exists == 0
67
74
  conn.redis.exists('events:' + client).callback do |events_exist|
@@ -92,16 +99,8 @@ module Sensu
92
99
  end
93
100
  end
94
101
 
95
- aget '/event/:client/:check' do |client, check|
96
- conn.redis.hgetall('events:' + client).callback do |events|
97
- client_events = Hash[*events]
98
- event = client_events[check]
99
- status 404 if event.nil?
100
- body event
101
- end
102
- end
103
-
104
102
  aget '/events' do
103
+ EM.debug('[events] -- ' + request.ip + ' -- GET -- request for event list')
105
104
  current_events = Hash.new
106
105
  conn.redis.smembers('clients').callback do |clients|
107
106
  unless clients.empty?
@@ -112,7 +111,7 @@ module Sensu
112
111
  client_events[key] = JSON.parse(value)
113
112
  end
114
113
  current_events[client] = client_events unless client_events.empty?
115
- body current_events.to_json if index == clients.size-1
114
+ body current_events.to_json if index == clients.size - 1
116
115
  end
117
116
  end
118
117
  else
@@ -121,14 +120,54 @@ module Sensu
121
120
  end
122
121
  end
123
122
 
123
+ aget '/event/:client/:check' do |client, check|
124
+ EM.debug('[event] -- ' + request.ip + ' -- GET -- request for event -- ' + client + ' -- ' + check)
125
+ conn.redis.hgetall('events:' + client).callback do |events|
126
+ client_events = Hash[*events]
127
+ event = client_events[check]
128
+ status 404 if event.nil?
129
+ body event
130
+ end
131
+ end
132
+
124
133
  apost '/stash/*' do |path|
125
- conn.redis.set('stash:' + path, request.body.read).callback do
134
+ EM.debug('[stash] -- ' + request.ip + ' -- POST -- request for stash -- ' + path)
135
+ begin
136
+ stash = JSON.parse(request.body.read)
137
+ rescue JSON::ParserError
138
+ status 400
139
+ body nil
140
+ end
141
+ conn.redis.set('stash:' + path, stash.to_json).callback do
126
142
  status 201
127
143
  body nil
128
144
  end
129
145
  end
130
146
 
147
+ apost '/stashes' do
148
+ EM.debug('[stashes] -- ' + request.ip + ' -- POST -- request for multiple stashes')
149
+ begin
150
+ paths = JSON.parse(request.body.read)
151
+ rescue JSON::ParserError
152
+ status 400
153
+ body nil
154
+ end
155
+ stashes = Hash.new
156
+ if paths.is_a?(Array)
157
+ paths.each_with_index do |path, index|
158
+ conn.redis.get('stash:' + path).callback do |stash|
159
+ stashes[path] = JSON.parse(stash) unless stash.nil?
160
+ body stashes.to_json if index == paths.size - 1
161
+ end
162
+ end
163
+ else
164
+ status 400
165
+ body nil
166
+ end
167
+ end
168
+
131
169
  aget '/stash/*' do |path|
170
+ EM.debug('[stash] -- ' + request.ip + ' -- GET -- request for stash -- ' + path)
132
171
  conn.redis.get('stash:' + path).callback do |stash|
133
172
  status 404 if stash.nil?
134
173
  body stash
@@ -136,6 +175,7 @@ module Sensu
136
175
  end
137
176
 
138
177
  adelete '/stash/*' do |path|
178
+ EM.debug('[stash] -- ' + request.ip + ' -- DELETE -- request for stash -- ' + path)
139
179
  conn.redis.exists('stash:' + path).callback do |stash_exist|
140
180
  unless stash_exist == 0
141
181
  conn.redis.del('stash:' + path).callback do
@@ -150,6 +190,7 @@ module Sensu
150
190
  end
151
191
 
152
192
  apost '/test' do
193
+ EM.debug('[test] -- ' + request.ip + ' -- POST -- seeding for minitest')
153
194
  client = '{
154
195
  "name": "test",
155
196
  "address": "localhost",
data/lib/sensu/client.rb CHANGED
@@ -9,13 +9,15 @@ module Sensu
9
9
  client.setup_keepalives
10
10
  client.setup_subscriptions
11
11
  client.setup_queue_monitor
12
+ client.setup_socket
12
13
 
13
- Signal.trap('INT') do
14
- EM.stop
15
- end
16
-
17
- Signal.trap('TERM') do
18
- EM.stop
14
+ %w[INT TERM].each do |signal|
15
+ Signal.trap(signal) do
16
+ EM.warning('[process] -- ' + signal + ' -- stopping sensu client')
17
+ EM.add_timer(1) do
18
+ EM.stop
19
+ end
20
+ end
19
21
  end
20
22
  end
21
23
  end
@@ -23,24 +25,32 @@ module Sensu
23
25
  def initialize(options={})
24
26
  config = Sensu::Config.new(:config_file => options[:config_file])
25
27
  @settings = config.settings
28
+ EM.syslog_setup(@settings.syslog.host, @settings.syslog.port)
26
29
  end
27
30
 
28
31
  def setup_amqp
32
+ EM.debug("[amqp] -- connecting to rabbitmq")
29
33
  connection = AMQP.connect(@settings.rabbitmq.to_hash.symbolize_keys)
30
34
  @amq = MQ.new(connection)
31
35
  end
32
36
 
37
+ def publish_keepalive
38
+ EM.debug('[keepalive] -- publishing keepalive -- ' + @settings.client.timestamp.to_s)
39
+ @keepalive_queue ||= @amq.queue('keepalives')
40
+ @keepalive_queue.publish(@settings.client.to_json)
41
+ end
42
+
33
43
  def setup_keepalives
34
- keepalive_queue = @amq.queue('keepalives')
35
44
  @settings.client.timestamp = Time.now.to_i
36
- keepalive_queue.publish(@settings.client.to_json)
45
+ publish_keepalive
37
46
  EM.add_periodic_timer(30) do
38
47
  @settings.client.timestamp = Time.now.to_i
39
- keepalive_queue.publish(@settings.client.to_json)
48
+ publish_keepalive
40
49
  end
41
50
  end
42
51
 
43
52
  def publish_result(check)
53
+ EM.info('[result] -- publishing check result -- ' + check.name)
44
54
  @result_queue ||= @amq.queue('results')
45
55
  @result_queue.publish({
46
56
  :client => @settings.client.name,
@@ -72,6 +82,7 @@ module Sensu
72
82
  end
73
83
  EM.defer(execute, publish)
74
84
  else
85
+ EM.warning('[execute] -- missing client attributes -- ' + unmatched_tokens.join(', ') + ' -- ' + check.name)
75
86
  check.status = 3
76
87
  check.output = 'Missing client attributes: ' + unmatched_tokens.join(', ')
77
88
  check.internal = true
@@ -80,6 +91,7 @@ module Sensu
80
91
  end
81
92
  end
82
93
  else
94
+ EM.warning('[execute] -- unkown check -- ' + check.name)
83
95
  check.status = 3
84
96
  check.output = 'Unknown check'
85
97
  check.internal = true
@@ -91,10 +103,12 @@ module Sensu
91
103
  def setup_subscriptions
92
104
  @check_queue = @amq.queue(UUIDTools::UUID.random_create.to_s, :exclusive => true)
93
105
  @settings.client.subscriptions.each do |exchange|
106
+ EM.debug('[subscribe] -- queue binding to exchange -- ' + exchange)
94
107
  @check_queue.bind(@amq.fanout(exchange))
95
108
  end
96
109
  @check_queue.subscribe do |check_json|
97
110
  check = Hashie::Mash.new(JSON.parse(check_json))
111
+ EM.info('[subscribe] -- received check -- ' + check.name)
98
112
  execute_check(check)
99
113
  end
100
114
  end
@@ -102,6 +116,7 @@ module Sensu
102
116
  def setup_queue_monitor
103
117
  EM.add_periodic_timer(5) do
104
118
  unless @check_queue.subscribed?
119
+ EM.warning('[monitor] -- reconnecting to rabbitmq')
105
120
  @check_queue.delete
106
121
  EM.add_timer(1) do
107
122
  setup_subscriptions
@@ -109,5 +124,46 @@ module Sensu
109
124
  end
110
125
  end
111
126
  end
127
+
128
+ def setup_socket
129
+ EM.debug('[socket] -- starting up socket server')
130
+ EM.start_server('127.0.0.1', 3030, ClientSocket) do |socket|
131
+ socket.client_name = @settings.client.name
132
+ socket.result_queue = @amq.queue('results')
133
+ end
134
+ end
135
+ end
136
+
137
+ class ClientSocket < EM::Connection
138
+ attr_accessor :client_name, :result_queue
139
+
140
+ def post_init
141
+ EM.debug('[socket] -- client connected')
142
+ end
143
+
144
+ def receive_data(data)
145
+ begin
146
+ check = Hashie::Mash.new(JSON.parse(data))
147
+ validates = %w[name status output].all? do |key|
148
+ check.key?(key)
149
+ end
150
+ if validates
151
+ EM.info('[socket] -- publishing check result -- ' + check.name)
152
+ @result_queue.publish({
153
+ :client => @client_name,
154
+ :check => check.to_hash
155
+ }.to_json)
156
+ else
157
+ EM.warning('[socket] -- a check name, exit status, and output are required -- e.g. {name: x, status: 0, output: "y"}')
158
+ end
159
+ rescue JSON::ParserError
160
+ EM.warning('[socket] -- could not parse check result -- expecting JSON')
161
+ end
162
+ close_connection
163
+ end
164
+
165
+ def unbind
166
+ EM.debug('[socket] -- client disconnected')
167
+ end
112
168
  end
113
169
  end
data/lib/sensu/config.rb CHANGED
@@ -48,7 +48,7 @@ module Sensu
48
48
  exit
49
49
  end
50
50
  current_process = $0.split('/').last
51
- if current_process == 'sensu-server' || current_process == 'rake_test_loader.rb'
51
+ if current_process == 'sensu-server' || current_process == 'rake'
52
52
  options[:worker] = false
53
53
  opts.on('-w', '--worker', 'Only consume jobs, no check publishing (default: false)') do
54
54
  options[:worker] = true
data/lib/sensu/server.rb CHANGED
@@ -4,13 +4,11 @@ require 'em-hiredis'
4
4
  module Sensu
5
5
  class Server
6
6
  attr_accessor :redis, :is_worker
7
- alias :redis_connection :redis
8
7
 
9
8
  def self.run(options={})
10
- EM.threadpool_size = 15
9
+ EM.threadpool_size = 16
11
10
  EM.run do
12
11
  server = self.new(options)
13
- server.setup_logging
14
12
  server.setup_redis
15
13
  server.setup_amqp
16
14
  server.setup_keepalives
@@ -21,12 +19,13 @@ module Sensu
21
19
  end
22
20
  server.setup_queue_monitor
23
21
 
24
- Signal.trap('INT') do
25
- EM.stop
26
- end
27
-
28
- Signal.trap('TERM') do
29
- EM.stop
22
+ %w[INT TERM].each do |signal|
23
+ Signal.trap(signal) do
24
+ EM.warning('[process] -- ' + signal + ' -- stopping sensu server')
25
+ EM.add_timer(1) do
26
+ EM.stop
27
+ end
28
+ end
30
29
  end
31
30
  end
32
31
  end
@@ -35,17 +34,16 @@ module Sensu
35
34
  config = Sensu::Config.new(:config_file => options[:config_file])
36
35
  @settings = config.settings
37
36
  @is_worker = options[:worker]
38
- end
39
-
40
- def setup_logging
41
37
  EM.syslog_setup(@settings.syslog.host, @settings.syslog.port)
42
38
  end
43
39
 
44
40
  def setup_redis
41
+ EM.debug('[redis] -- connecting to redis')
45
42
  @redis = EM::Hiredis.connect('redis://' + @settings.redis.host + ':' + @settings.redis.port.to_s)
46
43
  end
47
44
 
48
45
  def setup_amqp
46
+ EM.debug('[amqp] -- connecting to rabbitmq')
49
47
  connection = AMQP.connect(@settings.rabbitmq.to_hash.symbolize_keys)
50
48
  @amq = MQ.new(connection)
51
49
  end
@@ -53,9 +51,10 @@ module Sensu
53
51
  def setup_keepalives
54
52
  @keepalive_queue = @amq.queue('keepalives')
55
53
  @keepalive_queue.subscribe do |keepalive_json|
56
- client_id = JSON.parse(keepalive_json)['name']
57
- @redis.set('client:' + client_id, keepalive_json).callback do
58
- @redis.sadd('clients', client_id)
54
+ client = Hashie::Mash.new(JSON.parse(keepalive_json))
55
+ EM.debug('[keepalive] -- received keepalive -- ' + client.name)
56
+ @redis.set('client:' + client.name, keepalive_json).callback do
57
+ @redis.sadd('clients', client.name)
59
58
  end
60
59
  end
61
60
  end
@@ -72,10 +71,15 @@ module Sensu
72
71
  end
73
72
  report = proc do |output|
74
73
  output.split(/\n+/).each do |line|
75
- EM.debug(line)
74
+ EM.info('[handler] -- ' + line)
76
75
  end
77
76
  end
78
- EM.defer(handler, report)
77
+ if @settings.handlers.key?(event.check.handler)
78
+ EM.debug('[event] -- handling event -- ' + [event.check.handler, event.client.name, event.check.name].join(' -- '))
79
+ EM.defer(handler, report)
80
+ else
81
+ EM.warning('[event] -- handler does not exist -- ' + event.check.handler)
82
+ end
79
83
  end
80
84
 
81
85
  def process_result(result)
@@ -132,6 +136,7 @@ module Sensu
132
136
  end
133
137
  end
134
138
  else
139
+ EM.debug('[result] -- check is flapping -- ' + client.name + ' -- ' + check.name)
135
140
  @redis.hset('events:' + client.name, check.name, previous_event.merge({'flapping' => true}).to_json)
136
141
  end
137
142
  elsif check['status'] != 0
@@ -163,6 +168,7 @@ module Sensu
163
168
  @result_queue = @amq.queue('results')
164
169
  @result_queue.subscribe do |result_json|
165
170
  result = Hashie::Mash.new(JSON.parse(result_json))
171
+ EM.info('[result] -- received result -- ' + result.client + ' -- ' + result.check.name)
166
172
  process_result(result)
167
173
  end
168
174
  end
@@ -179,8 +185,8 @@ module Sensu
179
185
  end
180
186
  interval = options[:test] ? 0.5 : details.interval
181
187
  EM.add_periodic_timer(interval) do
188
+ EM.info('[publisher] -- publishing check -- ' + name + ' -- ' + exchange)
182
189
  exchanges[exchange].publish({'name' => name, 'issued' => Time.now.to_i}.to_json)
183
- EM.debug('name="Published Check" event_id=server action="Published check ' + name + ' to the ' + exchange + ' exchange"')
184
190
  end
185
191
  end
186
192
  end
@@ -190,6 +196,7 @@ module Sensu
190
196
 
191
197
  def setup_keepalive_monitor
192
198
  EM.add_periodic_timer(30) do
199
+ EM.debug('[keepalive] -- checking for stale clients')
193
200
  @redis.smembers('clients').callback do |clients|
194
201
  clients.each do |client_id|
195
202
  @redis.get('client:' + client_id).callback do |client_json|
@@ -229,9 +236,11 @@ module Sensu
229
236
  def setup_queue_monitor
230
237
  EM.add_periodic_timer(5) do
231
238
  unless @keepalive_queue.subscribed?
239
+ EM.warning('[monitor] -- reconnecting to rabbitmq')
232
240
  setup_keepalives
233
241
  end
234
242
  unless @result_queue.subscribed?
243
+ EM.warning('[monitor] -- reconnecting to rabbitmq')
235
244
  setup_results
236
245
  end
237
246
  end
data/sensu.gemspec CHANGED
@@ -18,13 +18,14 @@ Gem::Specification.new do |s|
18
18
  s.add_dependency("uuidtools")
19
19
  s.add_dependency("em-syslog")
20
20
  s.add_dependency("em-hiredis")
21
+ s.add_dependency("rack", "~> 1.3.4")
21
22
  s.add_dependency("async_sinatra")
22
23
  s.add_dependency("thin")
23
24
 
24
- s.add_development_dependency('rake')
25
- s.add_development_dependency('minitest')
26
- s.add_development_dependency('em-ventually')
27
- s.add_development_dependency('rest-client')
25
+ s.add_development_dependency("rake")
26
+ s.add_development_dependency("minitest", "~> 2.7.0")
27
+ s.add_development_dependency("em-ventually")
28
+ s.add_development_dependency("rest-client")
28
29
 
29
30
  s.files = `git ls-files`.split("\n").reject {|f| f =~ /(dist|test|png)/}
30
31
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sensu
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 63
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 7
9
- - 2
10
- version: 0.7.2
8
+ - 8
9
+ - 0
10
+ version: 0.8.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Sean Porter
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-10-14 00:00:00 -07:00
19
+ date: 2011-10-31 00:00:00 -07:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -106,21 +106,23 @@ dependencies:
106
106
  type: :runtime
107
107
  version_requirements: *id006
108
108
  - !ruby/object:Gem::Dependency
109
- name: async_sinatra
109
+ name: rack
110
110
  prerelease: false
111
111
  requirement: &id007 !ruby/object:Gem::Requirement
112
112
  none: false
113
113
  requirements:
114
- - - ">="
114
+ - - ~>
115
115
  - !ruby/object:Gem::Version
116
- hash: 3
116
+ hash: 19
117
117
  segments:
118
- - 0
119
- version: "0"
118
+ - 1
119
+ - 3
120
+ - 4
121
+ version: 1.3.4
120
122
  type: :runtime
121
123
  version_requirements: *id007
122
124
  - !ruby/object:Gem::Dependency
123
- name: thin
125
+ name: async_sinatra
124
126
  prerelease: false
125
127
  requirement: &id008 !ruby/object:Gem::Requirement
126
128
  none: false
@@ -134,7 +136,7 @@ dependencies:
134
136
  type: :runtime
135
137
  version_requirements: *id008
136
138
  - !ruby/object:Gem::Dependency
137
- name: rake
139
+ name: thin
138
140
  prerelease: false
139
141
  requirement: &id009 !ruby/object:Gem::Requirement
140
142
  none: false
@@ -145,10 +147,10 @@ dependencies:
145
147
  segments:
146
148
  - 0
147
149
  version: "0"
148
- type: :development
150
+ type: :runtime
149
151
  version_requirements: *id009
150
152
  - !ruby/object:Gem::Dependency
151
- name: minitest
153
+ name: rake
152
154
  prerelease: false
153
155
  requirement: &id010 !ruby/object:Gem::Requirement
154
156
  none: false
@@ -162,9 +164,25 @@ dependencies:
162
164
  type: :development
163
165
  version_requirements: *id010
164
166
  - !ruby/object:Gem::Dependency
165
- name: em-ventually
167
+ name: minitest
166
168
  prerelease: false
167
169
  requirement: &id011 !ruby/object:Gem::Requirement
170
+ none: false
171
+ requirements:
172
+ - - ~>
173
+ - !ruby/object:Gem::Version
174
+ hash: 19
175
+ segments:
176
+ - 2
177
+ - 7
178
+ - 0
179
+ version: 2.7.0
180
+ type: :development
181
+ version_requirements: *id011
182
+ - !ruby/object:Gem::Dependency
183
+ name: em-ventually
184
+ prerelease: false
185
+ requirement: &id012 !ruby/object:Gem::Requirement
168
186
  none: false
169
187
  requirements:
170
188
  - - ">="
@@ -174,11 +192,11 @@ dependencies:
174
192
  - 0
175
193
  version: "0"
176
194
  type: :development
177
- version_requirements: *id011
195
+ version_requirements: *id012
178
196
  - !ruby/object:Gem::Dependency
179
197
  name: rest-client
180
198
  prerelease: false
181
- requirement: &id012 !ruby/object:Gem::Requirement
199
+ requirement: &id013 !ruby/object:Gem::Requirement
182
200
  none: false
183
201
  requirements:
184
202
  - - ">="
@@ -188,7 +206,7 @@ dependencies:
188
206
  - 0
189
207
  version: "0"
190
208
  type: :development
191
- version_requirements: *id012
209
+ version_requirements: *id013
192
210
  description: A server monitoring framework using the publish-subscribe model
193
211
  email:
194
212
  - sean.porter@sonian.net