sensu 0.7.2 → 0.8.0

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