flapjack 0.9.6 → 1.0.0rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rspec +6 -0
- data/.travis.yml +20 -16
- data/CHANGELOG.md +11 -25
- data/Dockerfile +8 -0
- data/Gemfile +2 -5
- data/bin/flapjack +24 -213
- data/etc/flapjack_config.yaml.example +6 -30
- data/features/cli.feature +16 -14
- data/features/cli_flapjack-feed-events.feature +12 -13
- data/features/cli_flapjack-nagios-receiver.feature +14 -15
- data/features/cli_flapjack-populator.feature +16 -15
- data/features/cli_flapper.feature +12 -12
- data/features/cli_receive-events.feature +6 -5
- data/features/cli_simulate-failed-check.feature +7 -6
- data/features/steps/cli_steps.rb +2 -2
- data/features/support/env.rb +1 -0
- data/flapjack.gemspec +1 -0
- data/lib/flapjack/cli/flapper.rb +200 -0
- data/lib/flapjack/cli/import.rb +102 -0
- data/lib/flapjack/cli/receiver.rb +656 -0
- data/lib/flapjack/cli/server.rb +256 -0
- data/lib/flapjack/cli/simulate.rb +180 -0
- data/lib/flapjack/configuration.rb +2 -0
- data/lib/flapjack/data/entity_check.rb +5 -22
- data/lib/flapjack/data/event.rb +7 -12
- data/lib/flapjack/gateways/email.rb +4 -1
- data/lib/flapjack/gateways/jabber.rb +12 -36
- data/lib/flapjack/gateways/jsonapi/check_presenter.rb +6 -6
- data/lib/flapjack/gateways/jsonapi/report_methods.rb +5 -3
- data/lib/flapjack/gateways/pagerduty.rb +1 -1
- data/lib/flapjack/gateways/web/public/js/backbone.jsonapi.js +1 -1
- data/lib/flapjack/gateways/web/public/js/modules/contact.js +2 -2
- data/lib/flapjack/gateways/web/public/js/modules/entity.js +2 -2
- data/lib/flapjack/gateways/web/public/js/modules/medium.js +4 -4
- data/lib/flapjack/gateways/web/public/js/self_stats.js +1 -1
- data/lib/flapjack/gateways/web/views/check.html.erb +7 -7
- data/lib/flapjack/gateways/web/views/checks.html.erb +2 -3
- data/lib/flapjack/gateways/web/views/contact.html.erb +4 -4
- data/lib/flapjack/gateways/web/views/contacts.html.erb +2 -2
- data/lib/flapjack/gateways/web/views/edit_contacts.html.erb +1 -1
- data/lib/flapjack/gateways/web/views/entities.html.erb +1 -1
- data/lib/flapjack/gateways/web/views/entity.html.erb +1 -1
- data/lib/flapjack/gateways/web/views/index.html.erb +2 -2
- data/lib/flapjack/gateways/web/views/layout.erb +10 -10
- data/lib/flapjack/gateways/web/views/self_stats.html.erb +1 -1
- data/lib/flapjack/gateways/web.rb +36 -7
- data/lib/flapjack/pikelet.rb +0 -2
- data/lib/flapjack/processor.rb +3 -1
- data/lib/flapjack/redis_pool.rb +2 -6
- data/lib/flapjack/version.rb +1 -1
- data/spec/lib/flapjack/coordinator_spec.rb +3 -3
- data/spec/lib/flapjack/data/entity_check_spec.rb +2 -6
- data/spec/lib/flapjack/data/event_spec.rb +0 -31
- data/spec/lib/flapjack/gateways/email_spec.rb +109 -0
- data/spec/lib/flapjack/gateways/jabber_spec.rb +18 -16
- data/spec/lib/flapjack/gateways/jsonapi/check_presenter_spec.rb +12 -24
- data/spec/lib/flapjack/gateways/pagerduty_spec.rb +1 -1
- data/spec/lib/flapjack/gateways/web/views/check.html.erb_spec.rb +2 -0
- data/spec/lib/flapjack/gateways/web/views/contact.html.erb_spec.rb +2 -0
- data/spec/lib/flapjack/gateways/web/views/index.html.erb_spec.rb +2 -0
- data/spec/lib/flapjack/gateways/web_spec.rb +194 -145
- data/spec/lib/flapjack/redis_pool_spec.rb +0 -1
- data/spec/support/profile_all_formatter.rb +44 -0
- data/spec/support/uncolored_doc_formatter.rb +9 -0
- data/tasks/benchmarks.rake +0 -4
- metadata +28 -38
- data/.ruby-version +0 -1
- data/Gemfile-ruby1.9 +0 -28
- data/Gemfile-ruby1.9.lock +0 -227
- data/bin/flapjack-feed-events +0 -124
- data/bin/flapjack-nagios-receiver +0 -246
- data/bin/flapjack-nsca-receiver +0 -246
- data/bin/flapjack-populator +0 -132
- data/bin/flapper +0 -152
- data/bin/receive-events +0 -179
- data/bin/simulate-failed-check +0 -151
- data/lib/flapjack/data/migration.rb +0 -36
- data/lib/flapjack/gateways/api/contact_methods.rb +0 -369
- data/lib/flapjack/gateways/api/entity_check_presenter.rb +0 -218
- data/lib/flapjack/gateways/api/entity_methods.rb +0 -361
- data/lib/flapjack/gateways/api/entity_presenter.rb +0 -75
- data/lib/flapjack/gateways/api/rack/json_params_parser.rb +0 -26
- data/lib/flapjack/gateways/api.rb +0 -124
- data/spec/lib/flapjack/gateways/api/contact_methods_spec.rb +0 -772
- data/spec/lib/flapjack/gateways/api/entity_check_presenter_spec.rb +0 -211
- data/spec/lib/flapjack/gateways/api/entity_methods_spec.rb +0 -863
- data/spec/lib/flapjack/gateways/api/entity_presenter_spec.rb +0 -108
- data/spec/lib/flapjack/gateways/api_spec.rb +0 -30
@@ -0,0 +1,256 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'dante'
|
4
|
+
|
5
|
+
require 'oj'
|
6
|
+
Oj.mimic_JSON
|
7
|
+
Oj.default_options = { :indent => 0, :mode => :strict }
|
8
|
+
require 'active_support/json'
|
9
|
+
|
10
|
+
require 'flapjack/coordinator'
|
11
|
+
|
12
|
+
module Flapjack
|
13
|
+
module CLI
|
14
|
+
class Server
|
15
|
+
|
16
|
+
def initialize(global_options, options)
|
17
|
+
@global_options = global_options
|
18
|
+
@options = options
|
19
|
+
|
20
|
+
@config = Flapjack::Configuration.new
|
21
|
+
@config.load(global_options[:config])
|
22
|
+
@config_env = @config.all
|
23
|
+
|
24
|
+
if @config_env.nil? || @config_env.empty?
|
25
|
+
puts "No config data for environment '#{FLAPJACK_ENV}' found in '#{global_options[:config]}'"
|
26
|
+
exit 1
|
27
|
+
end
|
28
|
+
|
29
|
+
if options[:rbtrace]
|
30
|
+
require 'rbtrace'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def start
|
35
|
+
if runner.daemon_running?
|
36
|
+
puts "Flapjack is already running."
|
37
|
+
else
|
38
|
+
print "Flapjack starting..."
|
39
|
+
print "\n" unless @options[:daemonize]
|
40
|
+
return_value = nil
|
41
|
+
runner.execute(:daemonize => @options[:daemonize]) {
|
42
|
+
return_value = start_server
|
43
|
+
}
|
44
|
+
puts " done."
|
45
|
+
exit(return_value) unless return_value.nil?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def stop
|
50
|
+
if runner.daemon_running?
|
51
|
+
print "Flapjack stopping..."
|
52
|
+
runner.execute(:kill => true)
|
53
|
+
puts " done."
|
54
|
+
else
|
55
|
+
puts "Flapjack is not running."
|
56
|
+
end
|
57
|
+
exit 1 unless wait_pid_gone(get_pid)
|
58
|
+
end
|
59
|
+
|
60
|
+
def restart
|
61
|
+
if runner.daemon_running?
|
62
|
+
print "Flapjack stopping..."
|
63
|
+
runner.execute(:kill => true)
|
64
|
+
puts " done."
|
65
|
+
end
|
66
|
+
exit 1 unless wait_pid_gone(get_pid)
|
67
|
+
|
68
|
+
@runner = nil
|
69
|
+
|
70
|
+
print "Flapjack starting..."
|
71
|
+
runner.execute(:daemonize => true) {
|
72
|
+
start_server
|
73
|
+
}
|
74
|
+
puts " done."
|
75
|
+
end
|
76
|
+
|
77
|
+
def reload
|
78
|
+
if runner.daemon_running?
|
79
|
+
pid = get_pid
|
80
|
+
print "Reloading Flapjack configuration..."
|
81
|
+
begin
|
82
|
+
Process.kill('HUP', pid)
|
83
|
+
puts " sent HUP to pid #{pid}."
|
84
|
+
rescue => e
|
85
|
+
puts " couldn't send HUP to pid '#{pid}'."
|
86
|
+
end
|
87
|
+
else
|
88
|
+
puts "Flapjack is not running daemonized."
|
89
|
+
exit 1
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def status
|
94
|
+
pidfile = @options[:pidfile] || @config_env['pid_file'] ||
|
95
|
+
"/var/run/flapjack/flapjack.pid"
|
96
|
+
|
97
|
+
uptime = (runner.daemon_running?) ? Time.now - File.stat(pidfile).ctime : 0
|
98
|
+
if runner.daemon_running?
|
99
|
+
pid = get_pid
|
100
|
+
puts "Flapjack is running: pid #{pid}, uptime #{uptime}"
|
101
|
+
else
|
102
|
+
puts "Flapjack is not running"
|
103
|
+
exit 3
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
def runner
|
110
|
+
return @runner if @runner
|
111
|
+
|
112
|
+
self.class.skip_dante_traps
|
113
|
+
|
114
|
+
pidfile = @options[:pidfile].nil? ?
|
115
|
+
(@config_env['pid_file'] || "/var/run/flapjack/flapjack.pid") :
|
116
|
+
@options[:pidfile]
|
117
|
+
|
118
|
+
logfile = @options[:logfile].nil? ?
|
119
|
+
(@config_env['log_file'] || "/var/log/flapjack/flapjack.log") :
|
120
|
+
@options[:logfile]
|
121
|
+
|
122
|
+
@runner = Dante::Runner.new('flapjack', :pid_path => pidfile,
|
123
|
+
:log_path => logfile)
|
124
|
+
@runner
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.skip_dante_traps
|
128
|
+
return if Dante::Runner.respond_to?(:orig_start)
|
129
|
+
Dante::Runner.send(:alias_method, :orig_start, :start)
|
130
|
+
Dante::Runner.send(:define_method, :start) do
|
131
|
+
if log_path = options[:log_path] && options[:daemonize].nil?
|
132
|
+
redirect_output!
|
133
|
+
end
|
134
|
+
|
135
|
+
# skip signal traps
|
136
|
+
@startup_command.call(self.options) if @startup_command
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def start_server
|
141
|
+
@coordinator = Flapjack::Coordinator.new(@config)
|
142
|
+
@coordinator.start(:signals => true)
|
143
|
+
end
|
144
|
+
|
145
|
+
def process_exists(pid)
|
146
|
+
return unless pid
|
147
|
+
begin
|
148
|
+
Process.kill(0, pid)
|
149
|
+
return true
|
150
|
+
rescue Errno::ESRCH
|
151
|
+
return false
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# wait until the specified pid no longer exists, or until a timeout is reached
|
156
|
+
def wait_pid_gone(pid, timeout = 30)
|
157
|
+
print "waiting for a max of #{timeout} seconds for process #{pid} to exit" if process_exists(pid)
|
158
|
+
started_at = Time.now.to_i
|
159
|
+
while process_exists(pid)
|
160
|
+
break unless (Time.now.to_i - started_at < timeout)
|
161
|
+
print '.'
|
162
|
+
sleep 1
|
163
|
+
end
|
164
|
+
puts ''
|
165
|
+
!process_exists(pid)
|
166
|
+
end
|
167
|
+
|
168
|
+
def get_pid
|
169
|
+
IO.read(pidfile).chomp.to_i
|
170
|
+
rescue StandardError
|
171
|
+
pid = nil
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
desc 'Server for running components (e.g. processor, notifier, gateways)'
|
179
|
+
command :server do |server|
|
180
|
+
|
181
|
+
server.desc 'Start the server'
|
182
|
+
|
183
|
+
server.command :start do |start|
|
184
|
+
|
185
|
+
start.switch [:d, 'daemonize'], :desc => 'Daemonize',
|
186
|
+
:default_value => true
|
187
|
+
|
188
|
+
start.flag [:p, 'pidfile'], :desc => 'PATH of the pidfile to write to'
|
189
|
+
|
190
|
+
start.flag [:l, 'logfile'], :desc => 'PATH of the logfile to write to'
|
191
|
+
|
192
|
+
start.flag [:r, 'rbtrace'], :desc => 'Enable rbtrace profiling'
|
193
|
+
|
194
|
+
start.action do |global_options,options,args|
|
195
|
+
server = Flapjack::CLI::Server.new(global_options, options)
|
196
|
+
server.start
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
server.desc 'Stop the server'
|
201
|
+
server.command :stop do |stop|
|
202
|
+
|
203
|
+
stop.flag [:p, 'pidfile'], :desc => 'PATH of the pidfile to write to'
|
204
|
+
|
205
|
+
stop.flag [:l, 'logfile'], :desc => 'PATH of the logfile to write to'
|
206
|
+
|
207
|
+
stop.action do |global_options,options,args|
|
208
|
+
server = Flapjack::CLI::Server.new(global_options, options)
|
209
|
+
server.stop
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
server.desc 'Restart the server'
|
214
|
+
server.command :restart do |restart|
|
215
|
+
|
216
|
+
restart.flag [:p, 'pidfile'], :desc => 'PATH of the pidfile to write to'
|
217
|
+
|
218
|
+
restart.flag [:l, 'logfile'], :desc => 'PATH of the logfile to write to'
|
219
|
+
|
220
|
+
restart.flag [:r, 'rbtrace'], :desc => 'Enable rbtrace profiling'
|
221
|
+
|
222
|
+
restart.action do |global_options,options,args|
|
223
|
+
server = Flapjack::CLI::Server.new(global_options, options)
|
224
|
+
server.restart
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
server.desc 'Reload the server configuration'
|
229
|
+
server.command :reload do |reload|
|
230
|
+
|
231
|
+
reload.flag [:p, 'pidfile'], :desc => 'PATH of the pidfile to write to'
|
232
|
+
|
233
|
+
reload.flag [:l, 'logfile'], :desc => 'PATH of the logfile to write to'
|
234
|
+
|
235
|
+
reload.action do |global_options,options,args|
|
236
|
+
server = Flapjack::CLI::Server.new(global_options, options)
|
237
|
+
server.reload
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
server.desc 'Get server status'
|
242
|
+
server.command :status do |status|
|
243
|
+
|
244
|
+
status.flag [:p, 'pidfile'], :desc => 'PATH of the pidfile to write to'
|
245
|
+
|
246
|
+
status.flag [:l, 'logfile'], :desc => 'PATH of the logfile to write to'
|
247
|
+
|
248
|
+
status.action do |global_options,options,args|
|
249
|
+
server = Flapjack::CLI::Server.new(global_options, options)
|
250
|
+
server.status
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
|
@@ -0,0 +1,180 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'redis'
|
4
|
+
|
5
|
+
require 'flapjack/configuration'
|
6
|
+
require 'flapjack/data/event'
|
7
|
+
|
8
|
+
module Flapjack
|
9
|
+
module CLI
|
10
|
+
class Simulate
|
11
|
+
|
12
|
+
def initialize(global_options, options)
|
13
|
+
@global_options = global_options
|
14
|
+
@options = options
|
15
|
+
|
16
|
+
config = Flapjack::Configuration.new
|
17
|
+
config.load(global_options[:config])
|
18
|
+
@config_env = config.all
|
19
|
+
|
20
|
+
if @config_env.nil? || @config_env.empty?
|
21
|
+
puts "No config data for environment '#{FLAPJACK_ENV}' found in '#{global_options[:config]}'"
|
22
|
+
exit 1
|
23
|
+
end
|
24
|
+
|
25
|
+
@redis_options = config.for_redis
|
26
|
+
end
|
27
|
+
|
28
|
+
def _fail
|
29
|
+
events(:state => @options[:state], :recover => false,
|
30
|
+
:entity => @options[:entity], :check => @options[:check],
|
31
|
+
:tags => @options[:tags],
|
32
|
+
:minutes => @options[:time].to_f, :interval => @options[:interval].to_f)
|
33
|
+
end
|
34
|
+
|
35
|
+
def fail_and_recover
|
36
|
+
events(:state => @options[:state], :recover => true,
|
37
|
+
:entity => @options[:entity], :check => @options[:check],
|
38
|
+
:tags => @options[:tags],
|
39
|
+
:minutes => @options[:time].to_f, :interval => @options[:interval].to_f)
|
40
|
+
end
|
41
|
+
|
42
|
+
def ok
|
43
|
+
events(:state => 'ok', :recover => false,
|
44
|
+
:entity => @options[:entity], :check => @options[:check],
|
45
|
+
:tags => @options[:tags],
|
46
|
+
:minutes => @options[:time].to_f, :interval => @options[:interval].to_f)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def redis
|
52
|
+
@redis ||= Redis.new(@redis_options)
|
53
|
+
end
|
54
|
+
|
55
|
+
def events(opts = {})
|
56
|
+
stop_after = (opts[:minutes] * 60).to_i
|
57
|
+
recover = opts[:recover]
|
58
|
+
state = opts[:state] || 'critical'
|
59
|
+
event = {
|
60
|
+
'entity' => opts[:entity] || 'foo-app-01',
|
61
|
+
'check' => opts[:check] || 'HTTP',
|
62
|
+
'tags' => opts[:tags] || [],
|
63
|
+
'type' => 'service'
|
64
|
+
}
|
65
|
+
failure = event.merge('state' => state, 'summary' => 'Simulated check output (test by operator)')
|
66
|
+
recovery = event.merge('state' => 'ok', 'summary' => 'Simulated check output (test by operator)')
|
67
|
+
key = "#{event['entity']}:#{event['check']}"
|
68
|
+
|
69
|
+
puts "#{Time.now}: sending failure event (#{state}) for #{key}"
|
70
|
+
Flapjack::Data::Event.add(failure, :redis => redis)
|
71
|
+
|
72
|
+
EM.run do
|
73
|
+
|
74
|
+
EM.add_timer(stop_after) do
|
75
|
+
puts "#{Time.now}: stopping"
|
76
|
+
if recover
|
77
|
+
puts "#{Time.now}: sending recovery event for #{key}"
|
78
|
+
Flapjack::Data::Event.add(recovery.merge('time' => Time.now.to_i),
|
79
|
+
:redis => redis)
|
80
|
+
end
|
81
|
+
EM.stop
|
82
|
+
end
|
83
|
+
|
84
|
+
EM.add_periodic_timer(opts[:interval]) do
|
85
|
+
puts "#{Time.now}: sending failure event (#{state}) for #{key}"
|
86
|
+
Flapjack::Data::Event.add(failure.merge('time' => Time.now.to_i),
|
87
|
+
:redis => redis)
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
desc 'Generate streams of events in various states'
|
98
|
+
command :simulate do |simulate|
|
99
|
+
|
100
|
+
simulate.desc 'Generate a stream of failure events'
|
101
|
+
simulate.command :fail do |_fail|
|
102
|
+
# Because `fail` is a keyword (that you can actually override in a block,
|
103
|
+
# but we want to be good Ruby citizens).
|
104
|
+
|
105
|
+
_fail.flag [:t, 'time'], :desc => "MINUTES to generate failure events for (0.75)",
|
106
|
+
:default_value => 0.75
|
107
|
+
|
108
|
+
_fail.flag [:i, 'interval'], :desc => "SECONDS between events, can be decimal eg 0.1 (10)",
|
109
|
+
:default_value => 10
|
110
|
+
|
111
|
+
_fail.flag [:e, 'entity'], :desc => "ENTITY to generate failure events for ('foo-app-01')",
|
112
|
+
:default_value => 'foo-app-01'
|
113
|
+
|
114
|
+
_fail.flag [:k, 'check'], :desc => "CHECK to generate failure events for ('HTTP')",
|
115
|
+
:default_value => 'HTTP'
|
116
|
+
|
117
|
+
_fail.flag [:s, 'state'], :desc => "STATE to generate failure events with ('critical')",
|
118
|
+
:default_value => 'critical'
|
119
|
+
|
120
|
+
_fail.flag [:T, 'tags'], :desc => "optional comma-separated list of TAGS to include as part of the event",
|
121
|
+
:type => Array, :default_value => []
|
122
|
+
|
123
|
+
_fail.action do |global_options,options,args|
|
124
|
+
simulate = Flapjack::CLI::Simulate.new(global_options, options)
|
125
|
+
simulate._fail
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
simulate.desc 'Generate a stream of failure events, and one final recovery'
|
130
|
+
simulate.command :fail_and_recover do |fail_and_recover|
|
131
|
+
|
132
|
+
fail_and_recover.flag [:t, 'time'], :desc => "MINUTES to generate failure events for (0.75)",
|
133
|
+
:default_value => 0.75
|
134
|
+
|
135
|
+
fail_and_recover.flag [:i, 'interval'], :desc => "SECONDS between events, can be decimal eg 0.1 (10)",
|
136
|
+
:default_value => 10
|
137
|
+
|
138
|
+
fail_and_recover.flag [:e, 'entity'], :desc => "ENTITY to generate failure events for ('foo-app-01')",
|
139
|
+
:default_value => 'foo-app-01'
|
140
|
+
|
141
|
+
fail_and_recover.flag [:k, 'check'], :desc => "CHECK to generate failure events for ('HTTP')",
|
142
|
+
:default_value => 'HTTP'
|
143
|
+
|
144
|
+
fail_and_recover.flag [:s, 'state'], :desc => "STATE to generate failure events with ('critical')",
|
145
|
+
:default_value => 'critical'
|
146
|
+
|
147
|
+
fail_and_recover.flag [:T, 'tags'], :desc => "optional comma-separated list of TAGS to include as part of the event",
|
148
|
+
:type => Array, :default_value => []
|
149
|
+
|
150
|
+
fail_and_recover.action do |global_options,options,args|
|
151
|
+
simulate = Flapjack::CLI::Simulate.new(global_options, options)
|
152
|
+
simulate.fail_and_recover
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
simulate.desc 'Generate a stream of ok events'
|
157
|
+
simulate.command :ok do |ok|
|
158
|
+
|
159
|
+
ok.flag [:t, 'time'], :desc => "MINUTES to generate ok events for (0.75)",
|
160
|
+
:default_value => 0.75
|
161
|
+
|
162
|
+
ok.flag [:i, 'interval'], :desc => "SECONDS between events, can be decimal eg 0.1 (10)",
|
163
|
+
:default_value => 10
|
164
|
+
|
165
|
+
ok.flag [:e, 'entity'], :desc => "ENTITY to generate ok events for ('foo-app-01')",
|
166
|
+
:default_value => 'foo-app-01'
|
167
|
+
|
168
|
+
ok.flag [:k, 'check'], :desc => "CHECK to generate ok events for ('HTTP')",
|
169
|
+
:default_value => 'HTTP'
|
170
|
+
|
171
|
+
ok.flag [:T, 'tags'], :desc => "optional comma-separated list of TAGS to include as part of the event",
|
172
|
+
:type => Array, :default_value => []
|
173
|
+
|
174
|
+
ok.action do |global_options,options,args|
|
175
|
+
simulate = Flapjack::CLI::Simulate.new(global_options, options)
|
176
|
+
simulate.ok
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
@@ -30,23 +30,10 @@ module Flapjack
|
|
30
30
|
def self.for_event_id(event_id, options = {})
|
31
31
|
raise "Redis connection not set" unless redis = options[:redis]
|
32
32
|
entity_name, check_name = event_id.split(':', 2)
|
33
|
-
logger = options[:logger]
|
34
|
-
if logger
|
35
|
-
logger.debug("Flapjack::Data::EntityCheck#self.for_event_id called for event_id: #{event_id}")
|
36
|
-
logger.debug("Flapjack::Data::EntityCheck#self.for_event_id found entity_name: #{entity_name}, check_name: #{check_name}")
|
37
|
-
end
|
38
33
|
create_entity = options[:create_entity]
|
34
|
+
logger = options[:logger]
|
39
35
|
entity = Flapjack::Data::Entity.find_by_name(entity_name,
|
40
36
|
:create => create_entity, :logger => logger, :redis => redis)
|
41
|
-
if logger
|
42
|
-
logger.debug("Flapjack::Data::EntityCheck#self.for_event_id found entity by name(#{entity_name}): #{entity.inspect}")
|
43
|
-
end
|
44
|
-
unless entity
|
45
|
-
if logger
|
46
|
-
logger.error("entity can't be instantiated for #{entity_name}!")
|
47
|
-
end
|
48
|
-
return nil
|
49
|
-
end
|
50
37
|
self.new(entity, check_name, :logger => logger, :redis => redis)
|
51
38
|
end
|
52
39
|
|
@@ -127,13 +114,12 @@ module Flapjack
|
|
127
114
|
|
128
115
|
def self.unacknowledged_failing(options = {})
|
129
116
|
raise "Redis connection not set" unless redis = options[:redis]
|
130
|
-
logger = options[:logger]
|
131
117
|
|
132
118
|
redis.zrange('failed_checks', '0', '-1').reject {|entity_check|
|
133
119
|
redis.exists(entity_check + ':unscheduled_maintenance')
|
134
120
|
}.collect {|entity_check|
|
135
|
-
Flapjack::Data::EntityCheck.for_event_id(entity_check, :redis => redis
|
136
|
-
}
|
121
|
+
Flapjack::Data::EntityCheck.for_event_id(entity_check, :redis => redis)
|
122
|
+
}
|
137
123
|
end
|
138
124
|
|
139
125
|
def self.conflate_to_keys(entity_checks_hash)
|
@@ -329,11 +315,8 @@ module Flapjack
|
|
329
315
|
# if multiple scheduled maintenances found, find the end_time furthest in the future
|
330
316
|
most_futuristic = current_sched_ms.max {|sm| sm[:end_time] }
|
331
317
|
start_time = most_futuristic[:start_time]
|
332
|
-
|
333
|
-
|
334
|
-
if duration > 0
|
335
|
-
@redis.setex("#{@key}:scheduled_maintenance", duration.to_i, start_time)
|
336
|
-
end
|
318
|
+
duration = most_futuristic[:duration]
|
319
|
+
@redis.setex("#{@key}:scheduled_maintenance", duration.to_i, start_time)
|
337
320
|
end
|
338
321
|
|
339
322
|
# TODO allow summary to be changed as part of the termination
|
data/lib/flapjack/data/event.rb
CHANGED
@@ -3,8 +3,6 @@
|
|
3
3
|
require 'oj'
|
4
4
|
require 'flapjack/data/tag_set'
|
5
5
|
|
6
|
-
require 'flapjack/data/migration'
|
7
|
-
|
8
6
|
module Flapjack
|
9
7
|
module Data
|
10
8
|
class Event
|
@@ -80,27 +78,24 @@ module Flapjack
|
|
80
78
|
:events_archive_maxage => (3 * 60 * 60) }
|
81
79
|
options = defaults.merge(opts)
|
82
80
|
|
83
|
-
archive_dest
|
81
|
+
archive_dest = nil
|
84
82
|
base_time_str = Time.now.utc.strftime("%Y%m%d%H")
|
85
83
|
|
86
84
|
if options[:archive_events]
|
87
85
|
archive_dest = "events_archive:#{base_time_str}"
|
88
|
-
unless @previous_base_time_str == base_time_str
|
89
|
-
Flapjack::Data::Migration.purge_expired_archive_index(:redis => redis)
|
90
|
-
end
|
91
|
-
@previous_base_time_str = base_time_str
|
92
86
|
if options[:block]
|
93
87
|
raw = redis.brpoplpush(queue, archive_dest, 0)
|
94
88
|
else
|
95
89
|
raw = redis.rpoplpush(queue, archive_dest)
|
96
90
|
return unless raw
|
97
91
|
end
|
98
|
-
redis.sadd("known_events_archive_keys", archive_dest)
|
99
|
-
elsif options[:block]
|
100
|
-
raw = redis.brpop(queue, 0)[1]
|
101
92
|
else
|
102
|
-
|
103
|
-
|
93
|
+
if options[:block]
|
94
|
+
raw = redis.brpop(queue, 0)[1]
|
95
|
+
else
|
96
|
+
raw = redis.rpop(queue)
|
97
|
+
return unless raw
|
98
|
+
end
|
104
99
|
end
|
105
100
|
parsed = parse_and_validate(raw, :logger => options[:logger])
|
106
101
|
if parsed.nil?
|
@@ -52,6 +52,7 @@ module Flapjack
|
|
52
52
|
port = @smtp_config ? @smtp_config['port'] : nil
|
53
53
|
starttls = @smtp_config ? !! @smtp_config['starttls'] : nil
|
54
54
|
m_from = @smtp_config ? @smtp_config['from'] : "flapjack@#{@fqdn}"
|
55
|
+
m_reply_to = @smtp_config ? ( @smtp_config['reply_to'] ||= m_from ) : "flapjack@#{@fqdn}"
|
55
56
|
if @smtp_config
|
56
57
|
if auth_config = @smtp_config['auth']
|
57
58
|
auth = {}
|
@@ -64,6 +65,7 @@ module Flapjack
|
|
64
65
|
@logger.debug("flapjack_mailer: set from to #{m_from}")
|
65
66
|
|
66
67
|
mail = prepare_email(:from => m_from,
|
68
|
+
:reply_to => m_reply_to,
|
67
69
|
:to => alert.address,
|
68
70
|
:message_id => "<#{alert.notification_id}@#{@fqdn}>",
|
69
71
|
:alert => alert)
|
@@ -103,6 +105,7 @@ module Flapjack
|
|
103
105
|
# returns a Mail object
|
104
106
|
def prepare_email(opts = {})
|
105
107
|
from = opts[:from]
|
108
|
+
reply_to = opts[:reply_to]
|
106
109
|
to = opts[:to]
|
107
110
|
message_id = opts[:message_id]
|
108
111
|
alert = opts[:alert]
|
@@ -157,7 +160,7 @@ module Flapjack
|
|
157
160
|
from from
|
158
161
|
to to
|
159
162
|
subject subject
|
160
|
-
reply_to
|
163
|
+
reply_to reply_to
|
161
164
|
message_id message_id
|
162
165
|
|
163
166
|
text_part do
|