flapjack 0.7.29 → 0.7.30

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/CHANGELOG.md +8 -0
  2. data/bin/flapjack-nagios-receiver +20 -15
  3. data/bin/flapjack-populator +30 -13
  4. data/bin/flapper +1 -1
  5. data/bin/receive-events +13 -10
  6. data/bin/simulate-failed-check +13 -3
  7. data/dist/etc/init.d/flapjack +5 -42
  8. data/dist/etc/init.d/flapjack-nagios-receiver +3 -17
  9. data/dist/etc/init.d/flapper +3 -12
  10. data/etc/flapjack_config.yaml.example +81 -52
  11. data/features/cli.feature +30 -13
  12. data/features/cli_flapjack-nagios-receiver.feature +66 -0
  13. data/features/cli_flapjack-populator.feature +80 -0
  14. data/features/cli_flapper.feature +45 -0
  15. data/features/cli_receive-events.feature +27 -0
  16. data/features/cli_simulate-failed-check.feature +31 -0
  17. data/features/events.feature +3 -6
  18. data/features/packaging-lintian.feature +2 -2
  19. data/features/rollup.feature +2 -4
  20. data/features/steps/cli_steps.rb +25 -7
  21. data/features/steps/packaging-lintian_steps.rb +12 -6
  22. data/features/support/daemons.rb +11 -1
  23. data/features/support/env.rb +16 -4
  24. data/lib/flapjack/coordinator.rb +1 -1
  25. data/lib/flapjack/filters/delays.rb +1 -1
  26. data/lib/flapjack/gateways/email/alert.html.erb +1 -1
  27. data/lib/flapjack/gateways/email/alert.text.erb +1 -1
  28. data/lib/flapjack/gateways/email/rollup.html.erb +1 -1
  29. data/lib/flapjack/gateways/email/rollup.text.erb +1 -1
  30. data/lib/flapjack/gateways/web/views/check.html.erb +1 -1
  31. data/lib/flapjack/gateways/web/views/contact.html.erb +37 -32
  32. data/lib/flapjack/gateways/web.rb +7 -7
  33. data/lib/flapjack/logger.rb +25 -45
  34. data/lib/flapjack/version.rb +1 -1
  35. data/spec/lib/flapjack/coordinator_spec.rb +9 -7
  36. data/spec/lib/flapjack/logger_spec.rb +19 -13
  37. data/tasks/benchmarks.rake +1 -1
  38. data/tasks/support/flapjack_config_benchmark.yaml +1 -29
  39. metadata +97 -47
  40. checksums.yaml +0 -7
  41. data/bin/flapjack-netsaint-parser +0 -432
  42. data/dist/puppet/flapjack/files/.stub +0 -0
  43. data/dist/puppet/flapjack/manifests/common.pp +0 -61
  44. data/dist/puppet/flapjack/manifests/notifier.pp +0 -13
  45. data/dist/puppet/flapjack/manifests/worker.pp +0 -13
  46. data/dist/puppet/flapjack/templates/.stub +0 -0
  47. data/dist/puppet/ruby/manifests/dev.pp +0 -5
  48. data/dist/puppet/ruby/manifests/rubygems.pp +0 -14
  49. data/dist/puppet/sqlite3/manifests/dev.pp +0 -5
@@ -30,7 +30,8 @@
30
30
  <th>Summary Threshold</th>
31
31
  </tr>
32
32
  <% @contact.media.each_pair do |mk, mv| %>
33
- <% alerting[mk] = @contact.alerting_checks_for_media(mk) %>
33
+ <% alerting_checks = @contact.alerting_checks_for_media(mk) %>
34
+ <% alerting[mk] = alerting_checks unless (alerting_checks.nil? || alerting_checks.empty?) %>
34
35
  <tr>
35
36
  <% if 'pagerduty'.eql?(mk) %>
36
37
  <td>PagerDuty</td>
@@ -53,18 +54,20 @@
53
54
  <% end %>
54
55
  </td>
55
56
  <td>
56
- <% if alerting[mk].length >= @contact.media_rollup_thresholds[mk].to_i %>
57
- Yes -
58
- <% else %>
57
+ <% rollup_threshold = @contact.media_rollup_thresholds[mk] %>
58
+ <% num_alerting = alerting[mk].nil? ? 0 : alerting[mk].length %>
59
+ <% if rollup_threshold.nil? || (num_alerting < rollup_threshold.to_i) %>
59
60
  No -
61
+ <% else %>
62
+ Yes -
60
63
  <% end %>
61
- <%= alerting[mk].length %> alerting
64
+ <%= num_alerting %> alerting
62
65
  </td>
63
66
  <td>
64
- <% if @contact.media_rollup_thresholds[mk] %>
65
- <%= h @contact.media_rollup_thresholds[mk] %>
66
- <% else %>
67
+ <% if rollup_threshold.nil? %>
67
68
  -
69
+ <% else %>
70
+ <%= h rollup_threshold %>
68
71
  <% end %>
69
72
  </td>
70
73
  <% end %>
@@ -74,32 +77,34 @@
74
77
  <% end %>
75
78
 
76
79
  <h3>Alerting Checks</h3>
77
- <p>These failing checks are currently alerting because they are not acknowledged, not in scheduled maintenance, and currently allowed by this contact's notification rules.</p>
80
+ <p>Alerting checks are any that are failing, not acknowledged, not in scheduled maintenance, and currently allowed by this contact's notification rules.</p>
78
81
 
79
- <table class="table table-bordered table-hover table-condensed">
80
- <tr>
81
- <th>Media</th>
82
- <th>Alerting Checks</th>
83
- </tr>
84
- <% alerting.each_pair do |media, checks| %>
85
- <% if checks.length > 0 %>
86
- <tr>
87
- <td><%= h media.capitalize %></td>
88
- <td>
89
- <% checks.each do |entity_check| %>
90
- <% entity, check = entity_check.split(':', 2) %>
91
- <% check_link = "<a href=\"/check?entity=#{u(entity)}&amp;check=#{u(check)}\" title=\"check status\">" +
92
- h(check) + "</a>"%>
93
- <a href="/entity/<%= u(entity) %>" title="entity status"><%= h entity %></a> ::
94
- <%= check_link %> <br />
95
- <% end %>
96
- </td>
97
- </tr>
98
- <% else %>
99
- <tr><td colspan="2">No alerting checks, yay!</td></tr>
82
+ <% if alerting.empty? %>
83
+ <p><em>There are no currently alerting checks.</em></p>
84
+ <% else %>
85
+ <table class="table table-bordered table-hover table-condensed">
86
+ <tr>
87
+ <th>Media</th>
88
+ <th>Alerting Checks</th>
89
+ </tr>
90
+ <% alerting.each_pair do |media, checks| %>
91
+ <% if checks.length > 0 %>
92
+ <tr>
93
+ <td><%= h media.capitalize %></td>
94
+ <td>
95
+ <% checks.each do |entity_check| %>
96
+ <% entity, check = entity_check.split(':', 2) %>
97
+ <% check_link = "<a href=\"/check?entity=#{u(entity)}&amp;check=#{u(check)}\" title=\"check status\">" +
98
+ h(check) + "</a>"%>
99
+ <a href="/entity/<%= u(entity) %>" title="entity status"><%= h entity %></a> ::
100
+ <%= check_link %> <br />
101
+ <% end %>
102
+ </td>
103
+ </tr>
104
+ <% end %>
100
105
  <% end %>
101
- <% end %>
102
- </table>
106
+ </table>
107
+ <% end %>
103
108
 
104
109
  <h3>All Entities and Checks</h3>
105
110
  <% if !@entities_and_checks || @entities_and_checks.empty? %>
@@ -347,16 +347,16 @@ module Flapjack
347
347
  }.max_by {|n| n[1] || 0}
348
348
 
349
349
  lc = entity_check.last_change
350
- last_change = lc ? ChronicDuration.output(Time.now.to_i - lc.to_i,
351
- :format => :short, :keep_zero => true, :units => 2) : 'never'
350
+ last_change = lc ? (ChronicDuration.output(Time.now.to_i - lc.to_i,
351
+ :format => :short, :keep_zero => true, :units => 2) || '0s') : 'never'
352
352
 
353
353
  lu = entity_check.last_update
354
- last_update = lu ? ChronicDuration.output(Time.now.to_i - lu.to_i,
355
- :format => :short, :keep_zero => true, :units => 2) : 'never'
354
+ last_update = lu ? (ChronicDuration.output(Time.now.to_i - lu.to_i,
355
+ :format => :short, :keep_zero => true, :units => 2) || '0s') : 'never'
356
356
 
357
357
  ln = latest_notif[1]
358
- last_notified = ln ? ChronicDuration.output(Time.now.to_i - ln.to_i,
359
- :format => :short, :keep_zero => true, :units => 2) + ", #{latest_notif[0]}" : 'never'
358
+ last_notified = ln ? (ChronicDuration.output(Time.now.to_i - ln.to_i,
359
+ :format => :short, :keep_zero => true, :units => 2) || '0s') + ", #{latest_notif[0]}" : 'never'
360
360
 
361
361
  [(entity_check.state || '-'),
362
362
  (summary || '-'),
@@ -377,7 +377,7 @@ module Flapjack
377
377
  instance_id = i.match(/executive_instance:(.*)/)[1]
378
378
  boot_time = redis.hget(i, 'boot_time').to_i
379
379
  uptime = Time.now.to_i - boot_time
380
- uptime_string = ChronicDuration.output(uptime, :format => :short, :keep_zero => true, :units => 2)
380
+ uptime_string = (ChronicDuration.output(uptime, :format => :short, :keep_zero => true, :units => 2) || '0s')
381
381
  event_counters = redis.hgetall("event_counters:#{instance_id}")
382
382
  event_rates = event_counters.inject({}) do |er, ec|
383
383
  er[ec[0]] = uptime && uptime > 0 ? (ec[1].to_f / uptime).round : nil
@@ -2,12 +2,7 @@
2
2
 
3
3
  require 'logger'
4
4
  require 'syslog'
5
-
6
- begin
7
- # Ruby 2.0+
8
- require 'syslog/logger'
9
- rescue LoadError
10
- end
5
+ require 'monitor'
11
6
 
12
7
  module Flapjack
13
8
 
@@ -34,21 +29,9 @@ module Flapjack
34
29
  "#{t} [#{severity}] :: #{name} :: #{msg}\n"
35
30
  end
36
31
 
37
- @syslog_formatter = proc do |severity, datetime, progname, msg|
38
- t = datetime.iso8601
39
- l = SEVERITY_LABELS[severity]
40
- "#{t} [#{l}] :: #{name} :: #{msg}\n"
41
- end
42
-
43
32
  @logger = ::Logger.new(STDOUT)
44
33
  @logger.formatter = @formatter
45
34
 
46
- if Syslog.const_defined?('Logger', false)
47
- # Ruby 2.0+
48
- @sys_logger = Syslog.const_get('Logger', false).new('flapjack')
49
- @sys_logger.formatter = @syslog_formatter
50
- end
51
-
52
35
  configure(config)
53
36
  end
54
37
 
@@ -75,53 +58,50 @@ module Flapjack
75
58
  @logger.error(err) if err
76
59
 
77
60
  @logger.level = @level
78
- if @sys_logger
79
- @sys_logger.level = @level
80
- end
61
+ @use_syslog = config.has_key?('syslog_errors') && config['syslog_errors']
81
62
  end
82
63
 
83
64
  def close
84
65
  raise "Already closed" if @logger.nil?
85
66
  @logger.close
86
67
  @logger = nil
87
- if @sys_logger
88
- @sys_logger.close
89
- @sys_logger = nil
90
- end
91
68
  end
92
69
 
93
- def add(severity, message = nil, progname = nil, &block)
94
- raise "Cannot log with a closed logger" if @logger.nil?
95
- @logger.add(severity, message, progname, &block)
96
- return if severity < @level
97
-
98
- progname ||= 'flapjack'
99
- if message.nil?
100
- if block_given?
101
- message = yield
102
- else
103
- message = progname
104
- progname = 'flapjack'
105
- end
106
- end
107
-
108
- if @sys_logger
109
- @sys_logger.add(severity, message, progname, &block)
110
- else
70
+ def self.syslog_add(severity, message, name)
71
+ @lock ||= Monitor.new
72
+ @lock.synchronize do
111
73
  level = SYSLOG_LEVELS[severity]
112
74
  t = Time.now.iso8601
113
75
  l = SEVERITY_LABELS[severity]
114
76
  begin
115
77
  Syslog.open('flapjack', (Syslog::Constants::LOG_PID | Syslog::Constants::LOG_CONS),
116
78
  Syslog::Constants::LOG_USER)
117
- Syslog.mask = Syslog::LOG_UPTO(level)
118
- Syslog.log(level, "#{t} [#{l}] :: #{@name} :: %s", message)
79
+ Syslog.mask = Syslog::LOG_UPTO(::Syslog::Constants::LOG_ERR)
80
+ Syslog.log(level, "#{t} [#{l}] :: #{name} :: %s", message)
119
81
  ensure
120
82
  Syslog.close
121
83
  end
122
84
  end
123
85
  end
124
86
 
87
+ def add(severity, message = nil, progname = nil, &block)
88
+ raise "Cannot log with a closed logger" if @logger.nil?
89
+ @logger.add(severity, message, progname, &block)
90
+ if severity >= @level
91
+ progname ||= 'flapjack'
92
+ if message.nil?
93
+ if block_given?
94
+ message = yield
95
+ else
96
+ message = progname
97
+ progname = 'flapjack'
98
+ end
99
+ end
100
+ end
101
+
102
+ Flapjack::Logger.syslog_add(severity, message, @name) if @use_syslog
103
+ end
104
+
125
105
  LEVELS.each do |level|
126
106
  define_method(level) {|progname, &block|
127
107
  add(::Logger.const_get(level.upcase), nil, progname, &block)
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  module Flapjack
4
- VERSION = "0.7.29"
4
+ VERSION = "0.7.30"
5
5
  end
@@ -17,7 +17,7 @@ describe Flapjack::Coordinator do
17
17
  cfg = {'processor' => {'enabled' => true}}
18
18
  EM.should_receive(:synchrony).and_yield
19
19
  config.should_receive(:for_redis).and_return({})
20
- config.should_receive(:all).and_return(cfg)
20
+ config.should_receive(:all).twice.and_return(cfg)
21
21
 
22
22
  processor = double('processor')
23
23
  processor.should_receive(:start)
@@ -51,7 +51,7 @@ describe Flapjack::Coordinator do
51
51
  cfg = {'processor' => {'enabled' => true}}
52
52
  EM.should_receive(:synchrony).and_yield
53
53
  config.should_receive(:for_redis).and_return({})
54
- config.should_receive(:all).and_return(cfg)
54
+ config.should_receive(:all).twice.and_return(cfg)
55
55
 
56
56
  processor = double('processor')
57
57
  processor.should_receive(:start).and_raise(RuntimeError)
@@ -82,7 +82,7 @@ describe Flapjack::Coordinator do
82
82
  cfg = {'executive' => {'enabled' => true}}
83
83
  EM.should_receive(:synchrony).and_yield
84
84
  config.should_receive(:for_redis).and_return({})
85
- config.should_receive(:all).and_return(cfg)
85
+ config.should_receive(:all).twice.and_return(cfg)
86
86
 
87
87
  processor = double('processor')
88
88
  processor.should_receive(:start)
@@ -125,7 +125,7 @@ describe Flapjack::Coordinator do
125
125
  }
126
126
  EM.should_receive(:synchrony).and_yield
127
127
  config.should_receive(:for_redis).and_return({})
128
- config.should_receive(:all).and_return(cfg)
128
+ config.should_receive(:all).twice.and_return(cfg)
129
129
 
130
130
  processor = double('processor')
131
131
  processor.should_receive(:start)
@@ -163,6 +163,7 @@ describe Flapjack::Coordinator do
163
163
  Kernel.should_receive(:trap).with('QUIT').and_yield
164
164
  Kernel.should_receive(:trap).with('HUP').and_yield
165
165
 
166
+ config.should_receive(:all).and_return({})
166
167
  config.should_receive(:for_redis).and_return({})
167
168
  fc = Flapjack::Coordinator.new(config)
168
169
  fc.should_receive(:stop).exactly(3).times
@@ -181,6 +182,7 @@ describe Flapjack::Coordinator do
181
182
  Kernel.should_not_receive(:trap).with('QUIT')
182
183
  Kernel.should_not_receive(:trap).with('HUP')
183
184
 
185
+ config.should_receive(:all).and_return({})
184
186
  config.should_receive(:for_redis).and_return({})
185
187
  fc = Flapjack::Coordinator.new(config)
186
188
  fc.should_receive(:stop).twice
@@ -197,7 +199,7 @@ describe Flapjack::Coordinator do
197
199
  new_config = double('new_config')
198
200
  filename = double('filename')
199
201
 
200
- config.should_receive(:all).and_return(old_cfg)
202
+ config.should_receive(:all).twice.and_return(old_cfg)
201
203
  config.should_receive(:filename).and_return(filename)
202
204
 
203
205
  Flapjack::Configuration.should_receive(:new).and_return(new_config)
@@ -240,7 +242,7 @@ describe Flapjack::Coordinator do
240
242
  new_config = double('new_config')
241
243
  filename = double('filename')
242
244
 
243
- config.should_receive(:all).and_return(old_cfg)
245
+ config.should_receive(:all).twice.and_return(old_cfg)
244
246
  config.should_receive(:filename).and_return(filename)
245
247
 
246
248
  Flapjack::Configuration.should_receive(:new).and_return(new_config)
@@ -270,7 +272,7 @@ describe Flapjack::Coordinator do
270
272
  new_config = double('new_config')
271
273
  filename = double('filename')
272
274
 
273
- config.should_receive(:all).and_return(old_cfg)
275
+ config.should_receive(:all).twice.and_return(old_cfg)
274
276
  config.should_receive(:filename).and_return(filename)
275
277
 
276
278
  Flapjack::Configuration.should_receive(:new).and_return(new_config)
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'flapjack/logger'
2
3
 
3
4
  describe Flapjack::Logger do
4
5
 
@@ -13,19 +14,24 @@ describe Flapjack::Logger do
13
14
  logger.should_receive(:add).with(2, nil, "Yowza!")
14
15
  ::Logger.should_receive(:new).with(STDOUT).and_return(logger)
15
16
 
16
- if Syslog.const_defined?('Logger', false)
17
- sys_logger.should_receive(:formatter=).with(an_instance_of(Proc))
18
- sys_logger.should_receive(:level=).with(Logger::DEBUG)
19
- sys_logger.should_receive(:add).with(Logger::WARN, 'Yowza!', 'flapjack')
20
- Syslog.const_get('Logger', false).should_receive(:new).with('flapjack').and_return(sys_logger)
21
- else
22
- Syslog.should_receive(:open).with('flapjack',
23
- (Syslog::Constants::LOG_PID | Syslog::Constants::LOG_CONS),
24
- Syslog::Constants::LOG_USER).and_return(syslog)
25
- Syslog.should_receive(:mask=).with(Syslog::LOG_UPTO(Syslog::Constants::LOG_WARNING))
26
- Syslog.should_receive(:log).with(Syslog::Constants::LOG_WARNING, /\[WARN\] :: spec :: %s/, "Yowza!")
27
- Syslog.should_receive(:close)
28
- end
17
+ Syslog.should_receive(:open).with('flapjack',
18
+ (Syslog::Constants::LOG_PID | Syslog::Constants::LOG_CONS),
19
+ Syslog::Constants::LOG_USER).and_return(syslog)
20
+ Syslog.should_receive(:mask=).with(Syslog::LOG_UPTO(Syslog::Constants::LOG_ERR))
21
+ Syslog.should_receive(:log).with(Syslog::Constants::LOG_WARNING, /\[WARN\] :: spec :: %s/, "Yowza!")
22
+ Syslog.should_receive(:close)
23
+
24
+ flogger = Flapjack::Logger.new('spec', 'level' => 'debug', 'syslog_errors' => 'true')
25
+ flogger.warn "Yowza!"
26
+ end
27
+
28
+ it 'defaults to not logging via syslog' do
29
+ logger.should_receive(:formatter=).with(an_instance_of(Proc))
30
+ logger.should_receive(:level=).and_return(Logger::DEBUG)
31
+ logger.should_receive(:add).with(2, nil, "Yowza!")
32
+ ::Logger.should_receive(:new).with(STDOUT).and_return(logger)
33
+
34
+ Syslog.should_not_receive(:open)
29
35
 
30
36
  flogger = Flapjack::Logger.new('spec', 'level' => 'debug')
31
37
  flogger.warn "Yowza!"
@@ -14,7 +14,7 @@ namespace :benchmarks do
14
14
  require 'flapjack/data/entity_check'
15
15
  require 'flapjack/version'
16
16
 
17
- FLAPJACK_ENV = ENV['FLAPJACK_ENV'] || 'test'
17
+ FLAPJACK_ENV = 'test'
18
18
  config_file = File.join('tasks', 'support', 'flapjack_config_benchmark.yaml')
19
19
 
20
20
  config = Flapjack::Configuration.new
@@ -27,32 +27,4 @@ test:
27
27
  default_contact_timezone: Australia/Broken_Hill
28
28
  logger:
29
29
  level: WARN
30
- development:
31
- pid_file: tmp/pids/flapjack_development.pid
32
- log_file: log/flapjack_development.log
33
- daemonize: no
34
- redis:
35
- host: 127.0.0.1
36
- port: 6379
37
- db: 13
38
- processor:
39
- enabled: yes
40
- queue: events
41
- notifier_queue: notifications
42
- archive_events: true
43
- events_archive_maxage: 10800
44
- new_check_scheduled_maintenance_duration: 1 month
45
- exit_on_queue_empty: true
46
- logger:
47
- level: INFO
48
- notifier:
49
- enabled: yes
50
- queue: notifications
51
- email_queue: email_notifications
52
- sms_queue: sms_notifications
53
- jabber_queue: jabber_notifications
54
- pagerduty_queue: pagerduty_notifications
55
- notification_log_file: log/notification_test.log
56
- default_contact_timezone: Australia/Broken_Hill
57
- logger:
58
- level: INFO
30
+