sensu 0.6.8 → 0.6.9
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/.gitignore +1 -0
- data/README.org +13 -46
- data/lib/sensu.rb +1 -1
- data/lib/sensu/api.rb +0 -0
- data/lib/sensu/client.rb +2 -2
- data/lib/sensu/server.rb +61 -22
- metadata +111 -164
data/.gitignore
CHANGED
data/README.org
CHANGED
@@ -1,61 +1,28 @@
|
|
1
1
|
* Welcome to Sensu
|
2
|
-
Sensu is a monitoring system framework
|
2
|
+
Sensu is a monitoring system framework.
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
Check results are handled by user created handlers.
|
4
|
+
[[https://github.com/sonian/sensu/raw/master/sensu-logo.png]]
|
7
5
|
|
8
|
-
|
6
|
+
Checks can utilize user created plugins, returning an exit status code and outputting to STDOUT.
|
9
7
|
|
8
|
+
Check results are handled by user created handlers, receiving JSON formatted event data from STDIN.
|
9
|
+
* Documentation
|
10
|
+
Documentation can be found [[https://github.com/sonian/sensu/wiki][HERE]].
|
10
11
|
* License
|
11
12
|
Sensu is released under the [[https://github.com/sonian/sensu/blob/master/MIT-LICENSE.txt][MIT license]].
|
12
|
-
|
13
13
|
* Contributing
|
14
14
|
- [[http://help.github.com/fork-a-repo/][Fork]] [[https://github.com/sonian/sensu][Sensu]]
|
15
15
|
- Use a [[https://github.com/dchelimsky/rspec/wiki/Topic-Branches][topic branch]]
|
16
16
|
- Create a [[http://help.github.com/send-pull-requests/][pull request]]
|
17
17
|
|
18
18
|
Keep it simple.
|
19
|
-
|
20
|
-
** Readme Driven Development
|
21
|
-
*** A Client Will
|
22
|
-
- Have a set of attributes to describe it, including its responsibilities
|
23
|
-
- Send keep-alives to a server
|
24
|
-
- Subscribe to a queue bound to a set of fanout exchanges, determined by its responsibilities
|
25
|
-
- Substitute tokens in check commands with their matching client attribute
|
26
|
-
- Report when it does not have a client attribute for token substitution
|
27
|
-
- Receive checks from subscriptions, execute them, and publish the results to a queue with its client name
|
28
|
-
- Not allow overlapping check executions of the same name
|
29
|
-
- Report when it is unaware of a check it received from a subscription
|
30
|
-
|
31
|
-
*** A Server Will
|
32
|
-
- Subscribe to a queue for check results, another for keep-alives
|
33
|
-
- Pull keep-alives, storing client details
|
34
|
-
- Publish checks on defined intervals to their associated fanout exchanges
|
35
|
-
- Pull check results, storing the latest events for clients, a good result will flush a previous event for that client
|
36
|
-
- Create an event when it stops receiving keep-alives from a client, a new keep-alive for the client will clear the event
|
37
|
-
- Trigger a event handler, either the default handler or one specified for the check, providing it with a JSON event file
|
38
|
-
|
39
|
-
*** An API Will
|
40
|
-
- List all current events
|
41
|
-
- List all clients and their attributes
|
42
|
-
- Show a client and its attributes
|
43
|
-
- Remove a client and resolve associated events
|
44
|
-
|
45
|
-
*** A Plugin Will
|
46
|
-
- Output to STDOUT
|
47
|
-
- Return a valid exit status code
|
48
|
-
|
49
|
-
*** A Handler Will
|
50
|
-
- Accept a command line argument "-f", for an event file path
|
51
|
-
- Parse the JSON event file
|
52
|
-
- Handle the event as it wishes
|
53
|
-
|
54
19
|
** Testing
|
55
20
|
*** Requirements
|
56
|
-
- RabbitMQ
|
57
|
-
- Redis
|
58
|
-
|
59
|
-
|
60
|
-
|
21
|
+
- RabbitMQ
|
22
|
+
- Redis
|
23
|
+
*** Running
|
24
|
+
: bundle install
|
61
25
|
: rake test
|
26
|
+
* Contributors
|
27
|
+
- Sean Porter ([[https://twitter.com/#!/portertech][@portertech]])
|
28
|
+
- Justin Kolberg ([[https://twitter.com/#!/amdprophet][@amdprophet]])
|
data/lib/sensu.rb
CHANGED
data/lib/sensu/api.rb
CHANGED
File without changes
|
data/lib/sensu/client.rb
CHANGED
@@ -8,7 +8,7 @@ module Sensu
|
|
8
8
|
client.setup_amqp
|
9
9
|
client.setup_keepalives
|
10
10
|
client.setup_subscriptions
|
11
|
-
client.
|
11
|
+
client.setup_queue_monitor
|
12
12
|
|
13
13
|
Signal.trap('INT') do
|
14
14
|
EM.stop
|
@@ -90,7 +90,7 @@ module Sensu
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
-
def
|
93
|
+
def setup_queue_monitor
|
94
94
|
EM.add_periodic_timer(5) do
|
95
95
|
unless @check_queue.subscribed?
|
96
96
|
@check_queue.delete
|
data/lib/sensu/server.rb
CHANGED
@@ -19,7 +19,7 @@ module Sensu
|
|
19
19
|
server.setup_publisher
|
20
20
|
server.setup_keepalive_monitor
|
21
21
|
end
|
22
|
-
server.
|
22
|
+
server.setup_queue_monitor
|
23
23
|
|
24
24
|
Signal.trap('INT') do
|
25
25
|
EM.stop
|
@@ -83,29 +83,68 @@ module Sensu
|
|
83
83
|
unless client_json.nil?
|
84
84
|
client = JSON.parse(client_json)
|
85
85
|
check = result['check']
|
86
|
-
|
86
|
+
if @settings['checks'][check['name']]
|
87
|
+
check.merge!(@settings['checks'][check['name']])
|
88
|
+
end
|
87
89
|
check['handler'] ||= 'default'
|
88
90
|
event = {'client' => client, 'check' => check, 'occurrences' => 1}
|
89
91
|
if check['type'] == 'metric'
|
90
92
|
handle_event(event)
|
91
93
|
else
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
94
|
+
history_key = 'history:' + client['name'] + ':' + check['name']
|
95
|
+
@redis.rpush(history_key, check['status']).callback do
|
96
|
+
@redis.lrange(history_key, -21, -1).callback do |history|
|
97
|
+
total_state_change = 0
|
98
|
+
unless history.count < 21
|
99
|
+
state_changes = 0
|
100
|
+
change_weight = 0.8
|
101
|
+
history.each do |status|
|
102
|
+
previous_status ||= status
|
103
|
+
unless status == previous_status
|
104
|
+
state_changes += change_weight
|
105
|
+
end
|
106
|
+
change_weight += 0.02
|
107
|
+
previous_status = status
|
108
|
+
end
|
109
|
+
total_state_change = (state_changes.fdiv(20) * 100).to_i
|
110
|
+
@redis.lpop(history_key)
|
101
111
|
end
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
112
|
+
high_flap_threshold = check['high_flap_threshold'] || 50
|
113
|
+
low_flap_threshold = check['low_flap_threshold'] || 40
|
114
|
+
@redis.hget('events:' + client['name'], check['name']).callback do |event_json|
|
115
|
+
previous_event = event_json ? JSON.parse(event_json) : false
|
116
|
+
flapping = previous_event ? previous_event['flapping'] : false
|
117
|
+
check['flapping'] = case
|
118
|
+
when total_state_change >= high_flap_threshold
|
119
|
+
true
|
120
|
+
when flapping && total_state_change <= low_flap_threshold
|
121
|
+
false
|
122
|
+
else
|
123
|
+
flapping
|
124
|
+
end
|
125
|
+
if previous_event && check['status'] == 0
|
126
|
+
unless check['flapping']
|
127
|
+
@redis.hdel('events:' + client['name'], check['name']).callback do
|
128
|
+
event['action'] = 'resolve'
|
129
|
+
handle_event(event)
|
130
|
+
end
|
131
|
+
else
|
132
|
+
@redis.hset('events:' + client['name'], check['name'], previous_event.merge({'flapping' => true}).to_json)
|
133
|
+
end
|
134
|
+
elsif check['status'] != 0
|
135
|
+
if previous_event && check['status'] == previous_event['status']
|
136
|
+
event['occurrences'] = previous_event['occurrences'] += 1
|
137
|
+
end
|
138
|
+
@redis.hset('events:' + client['name'], check['name'], {
|
139
|
+
'status' => check['status'],
|
140
|
+
'output' => check['output'],
|
141
|
+
'flapping' => check['flapping'],
|
142
|
+
'occurrences' => event['occurrences']
|
143
|
+
}.to_json).callback do
|
144
|
+
event['action'] = 'create'
|
145
|
+
handle_event(event)
|
146
|
+
end
|
147
|
+
end
|
109
148
|
end
|
110
149
|
end
|
111
150
|
end
|
@@ -153,17 +192,17 @@ module Sensu
|
|
153
192
|
when time_since_last_check >= 180
|
154
193
|
result['check']['status'] = 2
|
155
194
|
result['check']['output'] = 'No keep-alive sent from host in over 180 seconds'
|
156
|
-
|
195
|
+
process_result(result)
|
157
196
|
when time_since_last_check >= 120
|
158
197
|
result['check']['status'] = 1
|
159
198
|
result['check']['output'] = 'No keep-alive sent from host in over 120 seconds'
|
160
|
-
|
199
|
+
process_result(result)
|
161
200
|
else
|
162
201
|
@redis.hexists('events:' + client_id, 'keepalive').callback do |exists|
|
163
202
|
if exists == 1
|
164
203
|
result['check']['status'] = 0
|
165
204
|
result['check']['output'] = 'Keep-alive sent from host'
|
166
|
-
|
205
|
+
process_result(result)
|
167
206
|
end
|
168
207
|
end
|
169
208
|
end
|
@@ -173,7 +212,7 @@ module Sensu
|
|
173
212
|
end
|
174
213
|
end
|
175
214
|
|
176
|
-
def
|
215
|
+
def setup_queue_monitor
|
177
216
|
EM.add_periodic_timer(5) do
|
178
217
|
unless @keepalive_queue.subscribed?
|
179
218
|
setup_keepalives
|
metadata
CHANGED
@@ -1,193 +1,149 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: sensu
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 6
|
9
|
-
- 8
|
10
|
-
version: 0.6.8
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.6.9
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Sean Porter
|
14
9
|
- Justin Kolberg
|
15
10
|
autorequire:
|
16
11
|
bindir: bin
|
17
12
|
cert_chain: []
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
dependencies:
|
22
|
-
- !ruby/object:Gem::Dependency
|
13
|
+
date: 2011-10-13 00:00:00.000000000Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
23
16
|
name: amqp
|
24
|
-
|
25
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: &70143497848320 !ruby/object:Gem::Requirement
|
26
18
|
none: false
|
27
|
-
requirements:
|
28
|
-
- -
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
hash: 11
|
31
|
-
segments:
|
32
|
-
- 0
|
33
|
-
- 7
|
34
|
-
- 4
|
19
|
+
requirements:
|
20
|
+
- - =
|
21
|
+
- !ruby/object:Gem::Version
|
35
22
|
version: 0.7.4
|
36
23
|
type: :runtime
|
37
|
-
version_requirements: *id001
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
|
-
name: json
|
40
24
|
prerelease: false
|
41
|
-
|
25
|
+
version_requirements: *70143497848320
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: json
|
28
|
+
requirement: &70143497846580 !ruby/object:Gem::Requirement
|
42
29
|
none: false
|
43
|
-
requirements:
|
44
|
-
- -
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
|
47
|
-
segments:
|
48
|
-
- 0
|
49
|
-
version: "0"
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
50
34
|
type: :runtime
|
51
|
-
version_requirements: *id002
|
52
|
-
- !ruby/object:Gem::Dependency
|
53
|
-
name: uuidtools
|
54
35
|
prerelease: false
|
55
|
-
|
36
|
+
version_requirements: *70143497846580
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: uuidtools
|
39
|
+
requirement: &70143497845280 !ruby/object:Gem::Requirement
|
56
40
|
none: false
|
57
|
-
requirements:
|
58
|
-
- -
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
|
61
|
-
segments:
|
62
|
-
- 0
|
63
|
-
version: "0"
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
64
45
|
type: :runtime
|
65
|
-
version_requirements: *id003
|
66
|
-
- !ruby/object:Gem::Dependency
|
67
|
-
name: em-syslog
|
68
46
|
prerelease: false
|
69
|
-
|
47
|
+
version_requirements: *70143497845280
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: em-syslog
|
50
|
+
requirement: &70143497844500 !ruby/object:Gem::Requirement
|
70
51
|
none: false
|
71
|
-
requirements:
|
72
|
-
- -
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
|
75
|
-
segments:
|
76
|
-
- 0
|
77
|
-
version: "0"
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
78
56
|
type: :runtime
|
79
|
-
version_requirements: *id004
|
80
|
-
- !ruby/object:Gem::Dependency
|
81
|
-
name: em-hiredis
|
82
57
|
prerelease: false
|
83
|
-
|
58
|
+
version_requirements: *70143497844500
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: em-hiredis
|
61
|
+
requirement: &70143497843400 !ruby/object:Gem::Requirement
|
84
62
|
none: false
|
85
|
-
requirements:
|
86
|
-
- -
|
87
|
-
- !ruby/object:Gem::Version
|
88
|
-
|
89
|
-
segments:
|
90
|
-
- 0
|
91
|
-
version: "0"
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
92
67
|
type: :runtime
|
93
|
-
version_requirements: *id005
|
94
|
-
- !ruby/object:Gem::Dependency
|
95
|
-
name: async_sinatra
|
96
68
|
prerelease: false
|
97
|
-
|
69
|
+
version_requirements: *70143497843400
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: async_sinatra
|
72
|
+
requirement: &70143497842460 !ruby/object:Gem::Requirement
|
98
73
|
none: false
|
99
|
-
requirements:
|
100
|
-
- -
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
|
103
|
-
segments:
|
104
|
-
- 0
|
105
|
-
version: "0"
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
106
78
|
type: :runtime
|
107
|
-
version_requirements: *id006
|
108
|
-
- !ruby/object:Gem::Dependency
|
109
|
-
name: thin
|
110
79
|
prerelease: false
|
111
|
-
|
80
|
+
version_requirements: *70143497842460
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: thin
|
83
|
+
requirement: &70143497841880 !ruby/object:Gem::Requirement
|
112
84
|
none: false
|
113
|
-
requirements:
|
114
|
-
- -
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
|
117
|
-
segments:
|
118
|
-
- 0
|
119
|
-
version: "0"
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
120
89
|
type: :runtime
|
121
|
-
version_requirements: *id007
|
122
|
-
- !ruby/object:Gem::Dependency
|
123
|
-
name: rake
|
124
90
|
prerelease: false
|
125
|
-
|
91
|
+
version_requirements: *70143497841880
|
92
|
+
- !ruby/object:Gem::Dependency
|
93
|
+
name: rake
|
94
|
+
requirement: &70143497841300 !ruby/object:Gem::Requirement
|
126
95
|
none: false
|
127
|
-
requirements:
|
128
|
-
- -
|
129
|
-
- !ruby/object:Gem::Version
|
130
|
-
|
131
|
-
segments:
|
132
|
-
- 0
|
133
|
-
version: "0"
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
134
100
|
type: :development
|
135
|
-
version_requirements: *id008
|
136
|
-
- !ruby/object:Gem::Dependency
|
137
|
-
name: minitest
|
138
101
|
prerelease: false
|
139
|
-
|
102
|
+
version_requirements: *70143497841300
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: minitest
|
105
|
+
requirement: &70143497840860 !ruby/object:Gem::Requirement
|
140
106
|
none: false
|
141
|
-
requirements:
|
142
|
-
- -
|
143
|
-
- !ruby/object:Gem::Version
|
144
|
-
|
145
|
-
segments:
|
146
|
-
- 0
|
147
|
-
version: "0"
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
148
111
|
type: :development
|
149
|
-
version_requirements: *id009
|
150
|
-
- !ruby/object:Gem::Dependency
|
151
|
-
name: em-ventually
|
152
112
|
prerelease: false
|
153
|
-
|
113
|
+
version_requirements: *70143497840860
|
114
|
+
- !ruby/object:Gem::Dependency
|
115
|
+
name: em-ventually
|
116
|
+
requirement: &70143497840360 !ruby/object:Gem::Requirement
|
154
117
|
none: false
|
155
|
-
requirements:
|
156
|
-
- -
|
157
|
-
- !ruby/object:Gem::Version
|
158
|
-
|
159
|
-
segments:
|
160
|
-
- 0
|
161
|
-
version: "0"
|
118
|
+
requirements:
|
119
|
+
- - ! '>='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
162
122
|
type: :development
|
163
|
-
version_requirements: *id010
|
164
|
-
- !ruby/object:Gem::Dependency
|
165
|
-
name: rest-client
|
166
123
|
prerelease: false
|
167
|
-
|
124
|
+
version_requirements: *70143497840360
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rest-client
|
127
|
+
requirement: &70143497839760 !ruby/object:Gem::Requirement
|
168
128
|
none: false
|
169
|
-
requirements:
|
170
|
-
- -
|
171
|
-
- !ruby/object:Gem::Version
|
172
|
-
|
173
|
-
segments:
|
174
|
-
- 0
|
175
|
-
version: "0"
|
129
|
+
requirements:
|
130
|
+
- - ! '>='
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
176
133
|
type: :development
|
177
|
-
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: *70143497839760
|
178
136
|
description: A server monitoring framework using the publish-subscribe model
|
179
|
-
email:
|
137
|
+
email:
|
180
138
|
- sean.porter@sonian.net
|
181
139
|
- justin.kolberg@sonian.net
|
182
|
-
executables:
|
140
|
+
executables:
|
183
141
|
- sensu-api
|
184
142
|
- sensu-client
|
185
143
|
- sensu-server
|
186
144
|
extensions: []
|
187
|
-
|
188
145
|
extra_rdoc_files: []
|
189
|
-
|
190
|
-
files:
|
146
|
+
files:
|
191
147
|
- .gitignore
|
192
148
|
- Gemfile
|
193
149
|
- Gemfile.lock
|
@@ -203,41 +159,32 @@ files:
|
|
203
159
|
- lib/sensu/config.rb
|
204
160
|
- lib/sensu/helpers.rb
|
205
161
|
- lib/sensu/server.rb
|
162
|
+
- sensu-logo.png
|
206
163
|
- sensu.gemspec
|
207
164
|
- sensu.windows
|
208
|
-
has_rdoc: true
|
209
165
|
homepage: https://github.com/sonian/sensu
|
210
|
-
licenses:
|
166
|
+
licenses:
|
211
167
|
- MIT
|
212
168
|
post_install_message:
|
213
169
|
rdoc_options: []
|
214
|
-
|
215
|
-
require_paths:
|
170
|
+
require_paths:
|
216
171
|
- lib
|
217
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
172
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
218
173
|
none: false
|
219
|
-
requirements:
|
220
|
-
- -
|
221
|
-
- !ruby/object:Gem::Version
|
222
|
-
|
223
|
-
|
224
|
-
- 0
|
225
|
-
version: "0"
|
226
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ! '>='
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
227
179
|
none: false
|
228
|
-
requirements:
|
229
|
-
- -
|
230
|
-
- !ruby/object:Gem::Version
|
231
|
-
|
232
|
-
segments:
|
233
|
-
- 0
|
234
|
-
version: "0"
|
180
|
+
requirements:
|
181
|
+
- - ! '>='
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: '0'
|
235
184
|
requirements: []
|
236
|
-
|
237
185
|
rubyforge_project:
|
238
|
-
rubygems_version: 1.
|
186
|
+
rubygems_version: 1.8.10
|
239
187
|
signing_key:
|
240
188
|
specification_version: 3
|
241
189
|
summary: A server monitoring framework
|
242
190
|
test_files: []
|
243
|
-
|