flapjack 0.7.0 → 0.7.1
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.md +17 -7
- data/bin/flapjack-nagios-receiver +1 -1
- data/etc/flapjack_config.yaml.example +5 -22
- data/lib/flapjack/data/contact.rb +5 -1
- data/lib/flapjack/data/event.rb +20 -7
- data/lib/flapjack/executive.rb +6 -1
- data/lib/flapjack/gateways/api.rb +5 -1
- data/lib/flapjack/pikelet.rb +10 -0
- data/lib/flapjack/version.rb +1 -1
- data/spec/lib/flapjack/gateways/api_spec.rb +89 -3
- metadata +8 -2
data/README.md
CHANGED
@@ -5,6 +5,8 @@
|
|
5
5
|
[id_travis_link]: https://secure.travis-ci.org/#!/flpjck/flapjack
|
6
6
|
[id_travis_img]: https://secure.travis-ci.org/flpjck/flapjack.png
|
7
7
|
|
8
|
+
[flapjack-project.com](http://flapjack-project.com/)
|
9
|
+
|
8
10
|
Flapjack is a highly scalable and distributed monitoring notification system.
|
9
11
|
|
10
12
|
Flapjack provides a scalable method for dealing with events representing changes in system state (OK -> WARNING -> CRITICAL transitions) and alerting appropriate people as necessary.
|
@@ -16,17 +18,13 @@ Flapjack's `executive` component picks up the events and processes them -- decid
|
|
16
18
|
Additional check engines can be supported by adding additional receiver processes similar to the nagios receiver.
|
17
19
|
|
18
20
|
|
19
|
-
## Using
|
20
|
-
|
21
|
-
### Quickstart
|
22
|
-
|
23
|
-
TODO numbered list for simplest possible Flapjack run.
|
21
|
+
## Using
|
24
22
|
|
25
|
-
For more information, including full specification of the configuration file and the data import formats, please refer to the [
|
23
|
+
For more information, including full specification of the configuration file and the data import formats, please refer to the [USING](https://github.com/flpjck/flapjack/wiki/USING) section of the Flapjack wiki
|
26
24
|
|
27
25
|
## Developing Flapjack
|
28
26
|
|
29
|
-
Information on developing more Flapjack components or contributing to core Flapjack development can be found in the [
|
27
|
+
Information on developing more Flapjack components or contributing to core Flapjack development can be found in the [DEVELOPING](https://github.com/flpjck/flapjack/wiki/DEVELOPING) section of the Flapjack wiki
|
30
28
|
|
31
29
|
## Documentation Submodule
|
32
30
|
|
@@ -43,4 +41,16 @@ If you make changes to the documentation locally, here's how to publish them:
|
|
43
41
|
* git add, commit and push from inside the doc subdir
|
44
42
|
* Add, commit and push the doc dir from the root (this updates the pointer in the main git repo to the correct ref in the doc repo, we think...)
|
45
43
|
|
44
|
+
## More on the wiki
|
45
|
+
|
46
|
+
https://github.com/flpjck/flapjack/wiki has even more goodies:
|
47
|
+
|
48
|
+
- [Using Flapjack](https://github.com/flpjck/flapjack/wiki/USING)
|
49
|
+
- [Developing Flapjack](https://github.com/flpjck/flapjack/wiki/DEVELOPING)
|
50
|
+
- [Redis Data Structure](https://github.com/flpjck/flapjack/wiki/DATA_STRUCTURES)
|
51
|
+
- [API](https://github.com/flpjck/flapjack/wiki/API)
|
52
|
+
- [Importing](https://github.com/flpjck/flapjack/wiki/IMPORTING)
|
53
|
+
- [Debugging Flapjack](https://github.com/flpjck/flapjack/wiki/DEBUGGING)
|
54
|
+
- [Flapjack Glossary](https://github.com/flpjck/flapjack/wiki/GLOSSARY)
|
55
|
+
|
46
56
|
|
@@ -51,7 +51,7 @@ def process_input(opts)
|
|
51
51
|
'summary' => check_output,
|
52
52
|
'timestamp' => timestamp,
|
53
53
|
}.to_json
|
54
|
-
redis.
|
54
|
+
redis.lpush 'events', event
|
55
55
|
end
|
56
56
|
rescue Redis::CannotConnectError
|
57
57
|
puts "Error, unable to to connect to the redis server (#{$!})"
|
@@ -1,26 +1,5 @@
|
|
1
1
|
---
|
2
2
|
|
3
|
-
quickstart:
|
4
|
-
redis:
|
5
|
-
host: 127.0.0.1
|
6
|
-
port: 6379
|
7
|
-
db: 6
|
8
|
-
executive:
|
9
|
-
enabled: yes
|
10
|
-
email_queue: email_notifications
|
11
|
-
notification_log_file: log/flapjack-notification.log
|
12
|
-
gateways:
|
13
|
-
email:
|
14
|
-
enabled: yes
|
15
|
-
queue: email_notifications
|
16
|
-
smtp_config:
|
17
|
-
address: "localhost"
|
18
|
-
domain: 'localhost.localdomain'
|
19
|
-
port: 25
|
20
|
-
web:
|
21
|
-
enabled: yes
|
22
|
-
port: 5080
|
23
|
-
|
24
3
|
development:
|
25
4
|
pid_file: tmp/pids/flapjack.pid
|
26
5
|
log_file: log/flapjack.log
|
@@ -34,7 +13,11 @@ development:
|
|
34
13
|
email_queue: email_notifications
|
35
14
|
sms_queue: sms_notifications
|
36
15
|
jabber_queue: jabber_notifications
|
37
|
-
|
16
|
+
pagerduty_queue: pagerduty_notifications
|
17
|
+
notification_log_file: log/notification.log
|
18
|
+
default_contact_timezone: Australia/Broken_Hill
|
19
|
+
archive_events: true
|
20
|
+
events_archive_maxage: 10800
|
38
21
|
logger:
|
39
22
|
level: INFO
|
40
23
|
gateways:
|
@@ -276,6 +276,8 @@ module Flapjack
|
|
276
276
|
|
277
277
|
# return the timezone of the contact, or the system default if none is set
|
278
278
|
def timezone(opts = {})
|
279
|
+
logger = opts[:logger]
|
280
|
+
|
279
281
|
tz_string = @redis.get("contact_tz:#{self.id}")
|
280
282
|
tz = opts[:default] if (tz_string.nil? || tz_string.empty?)
|
281
283
|
|
@@ -283,7 +285,9 @@ module Flapjack
|
|
283
285
|
begin
|
284
286
|
tz = ActiveSupport::TimeZone.new(tz_string)
|
285
287
|
rescue ArgumentError
|
286
|
-
logger
|
288
|
+
if logger
|
289
|
+
logger.warn("Invalid timezone string set for contact #{self.id} or TZ (#{tz_string}), using 'UTC'!")
|
290
|
+
end
|
287
291
|
tz = ActiveSupport::TimeZone.new('UTC')
|
288
292
|
end
|
289
293
|
end
|
data/lib/flapjack/data/event.rb
CHANGED
@@ -21,17 +21,30 @@ module Flapjack
|
|
21
21
|
def self.next(opts={})
|
22
22
|
raise "Redis connection not set" unless redis = opts[:redis]
|
23
23
|
|
24
|
-
defaults = { :block => true
|
24
|
+
defaults = { :block => true,
|
25
|
+
:archive_events => false,
|
26
|
+
:events_archive_maxage => (3 * 60 * 60) }
|
25
27
|
options = defaults.merge(opts)
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
-
|
29
|
+
if options[:archive_events]
|
30
|
+
dest = "events_archive:#{Time.now.utc.strftime "%Y%m%d%H"}"
|
31
|
+
if options[:block]
|
32
|
+
raw = redis.brpoplpush('events', dest, 0)
|
33
|
+
else
|
34
|
+
raw = redis.rpoplpush('events', dest)
|
35
|
+
return unless raw
|
36
|
+
end
|
37
|
+
redis.expire(dest, options[:events_archive_maxage])
|
38
|
+
else
|
39
|
+
if options[:block]
|
40
|
+
raw = redis.brpop('events', 0)[1]
|
41
|
+
else
|
42
|
+
raw = redis.rpop('events')
|
43
|
+
return unless raw
|
44
|
+
end
|
30
45
|
end
|
46
|
+
return self.new( ::JSON.parse( raw ) )
|
31
47
|
|
32
|
-
# In testing, we take care that there are no events on the queue.
|
33
|
-
return unless raw = redis.lpop('events')
|
34
|
-
self.new( ::JSON.parse(raw) )
|
35
48
|
end
|
36
49
|
|
37
50
|
# creates, or modifies, an event object and adds it to the events list in redis
|
data/lib/flapjack/executive.rb
CHANGED
@@ -57,6 +57,9 @@ module Flapjack
|
|
57
57
|
end
|
58
58
|
@default_contact_timezone = tz
|
59
59
|
|
60
|
+
@archive_events = @config['archive_events'] || false
|
61
|
+
@events_archive_maxage = @config['events_archive_maxage']
|
62
|
+
|
60
63
|
# FIXME: Put loading filters into separate method
|
61
64
|
# FIXME: should we make the filters more configurable by the end user?
|
62
65
|
options = { :log => opts[:logger], :persistence => @redis }
|
@@ -100,7 +103,9 @@ module Flapjack
|
|
100
103
|
|
101
104
|
until @should_quit
|
102
105
|
@logger.debug("Waiting for event...")
|
103
|
-
event = Flapjack::Data::Event.next(:redis => @redis
|
106
|
+
event = Flapjack::Data::Event.next(:redis => @redis,
|
107
|
+
:archive_events => @archive_events,
|
108
|
+
:events_archive_maxage => @events_archive_maxage)
|
104
109
|
process_event(event) unless event.nil?
|
105
110
|
end
|
106
111
|
|
@@ -100,7 +100,7 @@ module Flapjack
|
|
100
100
|
entity.check_list.to_json
|
101
101
|
end
|
102
102
|
|
103
|
-
get %r{/status/([a-zA-Z0-9][a-zA-Z0-9\.\-]*[a-zA-Z0-9])(?:/(
|
103
|
+
get %r{/status/([a-zA-Z0-9][a-zA-Z0-9\.\-]*[a-zA-Z0-9])(?:/(.+))?} do
|
104
104
|
content_type :json
|
105
105
|
|
106
106
|
entity_name = params[:captures][0]
|
@@ -119,6 +119,10 @@ module Flapjack
|
|
119
119
|
entity_check_status(entity, c)
|
120
120
|
}
|
121
121
|
end
|
122
|
+
if ret.nil?
|
123
|
+
status 404
|
124
|
+
return
|
125
|
+
end
|
122
126
|
ret.to_json
|
123
127
|
end
|
124
128
|
|
data/lib/flapjack/pikelet.rb
CHANGED
@@ -26,6 +26,16 @@ require 'flapjack/gateways/email'
|
|
26
26
|
require 'flapjack/gateways/sms_messagenet'
|
27
27
|
require 'flapjack/gateways/web'
|
28
28
|
require 'flapjack/logger'
|
29
|
+
require 'thin/version'
|
30
|
+
|
31
|
+
|
32
|
+
module Thin
|
33
|
+
# disable Thin's loading of daemons
|
34
|
+
# workaround for https://github.com/flpjck/flapjack/issues/133
|
35
|
+
def self.win?
|
36
|
+
true
|
37
|
+
end
|
38
|
+
end
|
29
39
|
|
30
40
|
module Flapjack
|
31
41
|
|
data/lib/flapjack/version.rb
CHANGED
@@ -74,14 +74,100 @@ describe 'Flapjack::Gateways::API', :sinatra => true, :logger => true, :json =>
|
|
74
74
|
end
|
75
75
|
|
76
76
|
it "returns a list of checks for an entity" do
|
77
|
-
check_list
|
78
|
-
entity.should_receive(:check_list).and_return(check_list)
|
77
|
+
entity.should_receive(:check_list).and_return([check])
|
79
78
|
Flapjack::Data::Entity.should_receive(:find_by_name).
|
80
79
|
with(entity_name, :redis => redis).and_return(entity)
|
81
80
|
|
82
81
|
get "/checks/#{entity_name_esc}"
|
83
82
|
last_response.should be_ok
|
84
|
-
last_response.body.should ==
|
83
|
+
last_response.body.should == [check].to_json
|
84
|
+
end
|
85
|
+
|
86
|
+
it "returns the status for all checks on an entity" do
|
87
|
+
entity.should_receive(:check_list).and_return([check])
|
88
|
+
Flapjack::Data::Entity.should_receive(:find_by_name).
|
89
|
+
with(entity_name, :redis => redis).and_return(entity)
|
90
|
+
|
91
|
+
now = Time.now.to_i
|
92
|
+
|
93
|
+
entity_check.should_receive(:state).and_return('OK')
|
94
|
+
entity_check.should_receive(:in_unscheduled_maintenance?).and_return(false)
|
95
|
+
entity_check.should_receive(:in_scheduled_maintenance?).and_return(false)
|
96
|
+
entity_check.should_receive(:last_update).and_return(now - 30)
|
97
|
+
entity_check.should_receive(:last_problem_notification).and_return(now - 60)
|
98
|
+
entity_check.should_receive(:last_recovery_notification).and_return(now - 30)
|
99
|
+
entity_check.should_receive(:last_acknowledgement_notification).and_return(now - 45)
|
100
|
+
Flapjack::Data::EntityCheck.should_receive(:for_entity).
|
101
|
+
with(entity, check, :redis => redis).and_return(entity_check)
|
102
|
+
|
103
|
+
get "/status/#{entity_name_esc}"
|
104
|
+
last_response.should be_ok
|
105
|
+
last_response.body.should == [{'name' => check,
|
106
|
+
'state' => 'OK',
|
107
|
+
'in_unscheduled_maintenance' => false,
|
108
|
+
'in_scheduled_maintenance' => false,
|
109
|
+
'last_update' => (now - 30),
|
110
|
+
'last_problem_notification' => (now - 60),
|
111
|
+
'last_recovery_notification' => (now - 30),
|
112
|
+
'last_acknowledgement_notification' => (now - 45)
|
113
|
+
}].to_json
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should not show the status for an entity that's not found" do
|
117
|
+
Flapjack::Data::Entity.should_receive(:find_by_name).
|
118
|
+
with(entity_name, :redis => redis).and_return(nil)
|
119
|
+
|
120
|
+
get "/status/#{entity_name_esc}"
|
121
|
+
last_response.should be_not_found
|
122
|
+
end
|
123
|
+
|
124
|
+
it "returns the status for a check (with non-word characters) on an entity" do
|
125
|
+
nw_check = "HTTP Port 443"
|
126
|
+
Flapjack::Data::Entity.should_receive(:find_by_name).
|
127
|
+
with(entity_name, :redis => redis).and_return(entity)
|
128
|
+
|
129
|
+
now = Time.now.to_i
|
130
|
+
|
131
|
+
entity_check.should_receive(:state).and_return('OK')
|
132
|
+
entity_check.should_receive(:in_unscheduled_maintenance?).and_return(false)
|
133
|
+
entity_check.should_receive(:in_scheduled_maintenance?).and_return(false)
|
134
|
+
entity_check.should_receive(:last_update).and_return(now - 30)
|
135
|
+
entity_check.should_receive(:last_problem_notification).and_return(now - 60)
|
136
|
+
entity_check.should_receive(:last_recovery_notification).and_return(now - 30)
|
137
|
+
entity_check.should_receive(:last_acknowledgement_notification).and_return(now - 45)
|
138
|
+
Flapjack::Data::EntityCheck.should_receive(:for_entity).
|
139
|
+
with(entity, nw_check, :redis => redis).and_return(entity_check)
|
140
|
+
|
141
|
+
get "/status/#{entity_name_esc}/#{URI.escape(nw_check)}"
|
142
|
+
last_response.should be_ok
|
143
|
+
last_response.body.should == {'name' => nw_check,
|
144
|
+
'state' => 'OK',
|
145
|
+
'in_unscheduled_maintenance' => false,
|
146
|
+
'in_scheduled_maintenance' => false,
|
147
|
+
'last_update' => (now - 30),
|
148
|
+
'last_problem_notification' => (now - 60),
|
149
|
+
'last_recovery_notification' => (now - 30),
|
150
|
+
'last_acknowledgement_notification' => (now - 45)
|
151
|
+
}.to_json
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should not show the status for a check on an entity that's not found" do
|
155
|
+
Flapjack::Data::Entity.should_receive(:find_by_name).
|
156
|
+
with(entity_name, :redis => redis).and_return(nil)
|
157
|
+
|
158
|
+
get "/status/#{entity_name_esc}/#{check}"
|
159
|
+
last_response.should be_not_found
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should not show the status for a check that's not found on an entity" do
|
163
|
+
Flapjack::Data::Entity.should_receive(:find_by_name).
|
164
|
+
with(entity_name, :redis => redis).and_return(entity)
|
165
|
+
|
166
|
+
Flapjack::Data::EntityCheck.should_receive(:for_entity).
|
167
|
+
with(entity, check, :redis => redis).and_return(nil)
|
168
|
+
|
169
|
+
get "/status/#{entity_name_esc}/#{check}"
|
170
|
+
last_response.should be_not_found
|
85
171
|
end
|
86
172
|
|
87
173
|
it "returns a list of scheduled maintenance periods for an entity" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flapjack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-04-
|
14
|
+
date: 2013-04-24 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: dante
|
@@ -534,12 +534,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
534
534
|
- - ! '>='
|
535
535
|
- !ruby/object:Gem::Version
|
536
536
|
version: '0'
|
537
|
+
segments:
|
538
|
+
- 0
|
539
|
+
hash: 308146534625742434
|
537
540
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
538
541
|
none: false
|
539
542
|
requirements:
|
540
543
|
- - ! '>='
|
541
544
|
- !ruby/object:Gem::Version
|
542
545
|
version: '0'
|
546
|
+
segments:
|
547
|
+
- 0
|
548
|
+
hash: 308146534625742434
|
543
549
|
requirements: []
|
544
550
|
rubyforge_project:
|
545
551
|
rubygems_version: 1.8.23
|