flapjack 0.4.12 → 0.5.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.
Files changed (55) hide show
  1. data/README.md +77 -50
  2. data/Rakefile +78 -26
  3. data/TODO.md +15 -32
  4. data/bin/flapjack-benchmark +50 -0
  5. data/bin/flapjack-notifier +11 -36
  6. data/bin/flapjack-notifier-manager +1 -3
  7. data/bin/flapjack-worker +5 -19
  8. data/doc/PACKAGING.md +25 -0
  9. data/etc/flapjack/flapjack-notifier.conf.example +34 -0
  10. data/etc/flapjack/recipients.conf.example +14 -0
  11. data/features/flapjack-notifier-manager.feature +19 -0
  12. data/features/flapjack-worker-manager.feature +25 -0
  13. data/features/packaging-lintian.feature +15 -0
  14. data/features/persistence/couch.feature +105 -0
  15. data/features/persistence/sqlite3.feature +105 -0
  16. data/features/persistence/steps/couch_steps.rb +25 -0
  17. data/features/persistence/steps/generic_steps.rb +102 -0
  18. data/features/persistence/steps/sqlite3_steps.rb +13 -0
  19. data/features/steps/flapjack-notifier-manager_steps.rb +24 -0
  20. data/features/steps/flapjack-worker-manager_steps.rb +50 -0
  21. data/features/steps/packaging-lintian_steps.rb +13 -0
  22. data/features/support/env.rb +22 -0
  23. data/features/support/silent_system.rb +4 -0
  24. data/flapjack.gemspec +7 -11
  25. data/lib/flapjack/applications/notifier.rb +222 -0
  26. data/lib/flapjack/applications/worker.rb +99 -0
  27. data/lib/flapjack/checks/ping +10 -0
  28. data/lib/flapjack/cli/notifier.rb +80 -218
  29. data/lib/flapjack/cli/worker.rb +1 -86
  30. data/lib/flapjack/filters/any_parents_failed.rb +14 -0
  31. data/lib/flapjack/filters/ok.rb +13 -0
  32. data/lib/flapjack/inifile.rb +44 -0
  33. data/lib/flapjack/{notifier.rb → notifier_engine.rb} +13 -9
  34. data/lib/flapjack/notifiers/mailer/mailer.rb +12 -13
  35. data/lib/flapjack/notifiers/xmpp/xmpp.rb +2 -2
  36. data/lib/flapjack/patches.rb +25 -0
  37. data/lib/flapjack/persistence/couch.rb +5 -0
  38. data/lib/flapjack/persistence/couch/connection.rb +66 -0
  39. data/lib/flapjack/persistence/couch/couch.rb +63 -0
  40. data/lib/flapjack/persistence/data_mapper.rb +3 -0
  41. data/lib/flapjack/persistence/data_mapper/data_mapper.rb +67 -0
  42. data/lib/flapjack/{models → persistence/data_mapper/models}/check.rb +3 -7
  43. data/lib/flapjack/{models → persistence/data_mapper/models}/check_template.rb +0 -0
  44. data/lib/flapjack/persistence/data_mapper/models/event.rb +17 -0
  45. data/lib/flapjack/{models → persistence/data_mapper/models}/node.rb +0 -0
  46. data/lib/flapjack/{models → persistence/data_mapper/models}/related_check.rb +0 -0
  47. data/lib/flapjack/persistence/sqlite3.rb +3 -0
  48. data/lib/flapjack/persistence/sqlite3/sqlite3.rb +166 -0
  49. data/lib/flapjack/transports/beanstalkd.rb +33 -0
  50. data/lib/flapjack/transports/result.rb +58 -0
  51. metadata +46 -56
  52. data/etc/flapjack/flapjack-notifier.yaml.example +0 -8
  53. data/etc/flapjack/recipients.yaml.example +0 -10
  54. data/lib/flapjack/database.rb +0 -10
  55. data/lib/flapjack/result.rb +0 -47
data/README.md CHANGED
@@ -6,7 +6,11 @@ Flapjack is highly scalable and distributed monitoring system.
6
6
  It understands the Nagios plugin format, and can easily be scaled
7
7
  from 1 server to 1000.
8
8
 
9
+ WARNING
10
+ =======
9
11
 
12
+ **These install instructions are probably wrong. Follow them best you can, and
13
+ please report bugs as you find them!**
10
14
 
11
15
  Setup dependencies (Ubuntu Hardy)
12
16
  ---------------------------------
@@ -51,13 +55,14 @@ Install the following software through your package manager or from source:
51
55
  Installation
52
56
  ------------
53
57
 
54
- Add GitHub's RubyGems server to your Gem sources:
55
58
 
56
- sudo gem sources -a http://gems.github.com
59
+ Add the Gemcutter RubyGems server to your Gem sources:
60
+
61
+ sudo gem sources -a http://gemcutter.org
57
62
 
58
63
  Install the Flapjack gem:
59
64
 
60
- sudo gem install auxesis-flapjack
65
+ sudo gem install flapjack
61
66
 
62
67
  Then run the magic configuration script to set up init scripts:
63
68
 
@@ -71,26 +76,51 @@ Running
71
76
 
72
77
  Make sure beanstalkd is running.
73
78
 
74
- You'll want to set up `/etc/flapjack/recipients.yaml` so notifications can be sent via
79
+ You'll want to set up `/etc/flapjack/recipients.conf` so notifications can be sent via
75
80
  `flapjack-notifier`:
76
81
 
77
- ---
78
- - :name: Jane Doe
79
- :email: "jane@doe.com"
80
- :phone: "+61 444 222 111"
81
- :pager: "61444222111"
82
- :jid: "jane@doe.com"
83
-
84
- You also need to set up `/etc/flapjack/flapjack-notifier.yaml`:
82
+ [John Doe]
83
+ email = johndoe@example.org
84
+ jid = john@example.org
85
+ phone = +61 400 111 222
86
+ pager = 61400111222
87
+
88
+ [Jane Doe]
89
+ email = janedoe@example.org
90
+ jid = jane@example.org
91
+ phone = +61 222 333 111
92
+ pager = 61222333111
93
+
94
+ You also need to set up `/etc/flapjack/notifier.conf`:
95
+
96
+ # top level
97
+ [notifier]
98
+ notifier-directories = /usr/lib/flapjack/notifiers/ /path/to/my/notifiers
99
+ notifiers = mailer, xmpp
100
+
101
+ # persistence layers
102
+ [persistence]
103
+ backend = data_mapper
104
+ uri = sqlite3:///tmp/flapjack.db
105
+
106
+ # message transports
107
+ [transport]
108
+ backend = beanstalkd
109
+ host = localhost
110
+ port = 11300
111
+
112
+ # notifiers
113
+ [mailer-notifier]
114
+ from_address = foo@bar.com
115
+
116
+ [xmpp-notifier]
117
+ jid = foo@bar.com
118
+ password = barfoo
119
+
120
+ # filters
121
+ [filters]
122
+ chain = ok, downtime, any_parents_failed
85
123
 
86
- ---
87
- :notifiers:
88
- :mailer:
89
- :from_address: notifications@my-domain.com
90
- :xmpp:
91
- :jid: notifications@my-domain.com
92
- :password: foo
93
- :database_uri: "sqlite3:///var/lib/flapjack/flapjack.db"
94
124
 
95
125
  Start up a cluster of workers:
96
126
 
@@ -105,12 +135,12 @@ Each of the `flapjack-worker`s will output to syslog (check in /var/log/messages
105
135
 
106
136
  Start up the notifier:
107
137
 
108
- flapjack-notifier-manager start --recipients /etc/flapjack/recipients.yaml
138
+ flapjack-notifier-manager start --recipients /etc/flapjack/recipients.conf
109
139
 
110
140
  Currently there are email and XMPP notifiers.
111
141
 
112
142
  You'll want to get a copy of (http://github.com/auxesis/flapjack-admin/)[flapjack-admin]
113
- to set up some checks, then run its' populator to get them into Flapjack.
143
+ to set up some checks, then run its populator to get them into Flapjack.
114
144
 
115
145
  What things do
116
146
  --------------
@@ -119,6 +149,7 @@ What things do
119
149
  * `flapjack-worker-manager` => starts/stops a cluster of `flapjack-worker`
120
150
  * `flapjack-notifier` => gets results, notifies people if necessary
121
151
  * `flapjack-stats` => gets stats from beanstalkd tubes (useful for benchmarks + performance analysis)
152
+ * `flapjack-benchmark` => benchmarks various persistence/transport backend combinations
122
153
 
123
154
 
124
155
  init scripts
@@ -140,46 +171,35 @@ Config for the init scripts can be found in `/etc/defaults`.
140
171
 
141
172
 
142
173
 
143
- Developing
144
- ----------
145
-
146
- You can write your own notifiers and place them in `lib/flapjack/notifiers/`.
147
-
148
- Your notifier just needs to implement the `notify` method, and take in a hash:
149
-
150
- class Sms
151
- def initialize(opts={})
152
- # you may want to set from address here
153
- end
154
-
155
- def notify(opts={})
156
- who = opts[:who]
157
- result = opts[:result]
158
- # sms to your hearts content
159
- end
160
- end
161
-
162
-
163
174
  Testing
164
175
  -------
165
176
 
166
- Tests are in `spec/`.
177
+ Tests are in `spec/` and `features/`.
167
178
 
168
179
  To run tests:
169
180
 
170
181
  $ rake spec
182
+ $ rake cucumber
171
183
 
172
184
 
173
185
  Architecture
174
186
  ------------
175
187
 
176
- -------------------
177
- | web interface / |
178
- | dsl / flat file |
179
- -------------------
180
- /
181
- |
182
- |
188
+ ------------------- -------------------
189
+ | web interface / | | visualisation / |
190
+ | dsl / flat file | | reporting |
191
+ ------------------- -------------------
192
+ | |
193
+ \ /
194
+ \ /
195
+ ---------------
196
+ | persistence |
197
+ ---------------
198
+ |
199
+ -------------------------------
200
+ | |
201
+ | |
202
+ | |
183
203
  ------------- ------------
184
204
  | populator |--- -----| notifier |
185
205
  ------------- | | ------------
@@ -202,4 +222,11 @@ Architecture
202
222
  re-add check to `jobs` tube with a delay.
203
223
  - notifier pops results off `results` tube, notifies as necessary
204
224
 
225
+ Releasing
226
+ ---------
205
227
 
228
+ 1. bump version number + release date in gemspec
229
+ 1. create a new tag with `git tag -a -m "releasing 0.9" 0.9`
230
+ 1. push to github with `git push --tags`
231
+ 1. create a new gem with `rake build`
232
+ 1. push gem to Gemcutter with `rake push`
data/Rakefile CHANGED
@@ -19,23 +19,6 @@ Spec::Rake::SpecTask.new do |t|
19
19
  end
20
20
 
21
21
 
22
- desc "freeze deps"
23
- task :deps do
24
-
25
- deps = {'beanstalk-client' => ">= 1.0.2",
26
- 'log4r' => ">= 1.0.5",
27
- 'xmpp4r-simple' => ">= 0.8.8",
28
- 'mailfactory' => ">= 1.4.0"}
29
-
30
- puts "\ninstalling dependencies. this will take a few minutes."
31
-
32
- deps.each_pair do |dep, version|
33
- puts "\ninstalling #{dep} (#{version})"
34
- system("gem install #{dep} --version '#{version}' -i gems --no-rdoc --no-ri")
35
- end
36
-
37
- end
38
-
39
22
  desc "generate list of files for gemspec"
40
23
  task "gengemfiles" do
41
24
  executables = `git ls-files bin/*`.split.map {|bin| bin.gsub(/^bin\//, '')}
@@ -64,15 +47,6 @@ task :build do
64
47
  end
65
48
 
66
49
 
67
- if require 'yard'
68
-
69
- YARD::Rake::YardocTask.new do |t|
70
- t.files = ['lib/**/*.rb']
71
- t.options = ['--output-dir=doc/', '--readme=README.md']
72
- end
73
-
74
- end
75
-
76
50
  desc "display FIXMEs in the codebase"
77
51
  task :fixmes do
78
52
  output = `grep -nR FIXME lib/* spec/* bin/`
@@ -82,3 +56,81 @@ task :fixmes do
82
56
  puts " - #{parts[3].strip}"
83
57
  end
84
58
  end
59
+
60
+ desc "build a tarball suitable for building packages from"
61
+ task :tarball do
62
+ require 'open-uri'
63
+ require 'tmpdir'
64
+ tmpdir = Dir.mktmpdir
65
+
66
+ current_commit = `git log`.first.split[1][0..5]
67
+ release_tarball = "/tmp/flapjack-#{current_commit}.tar.gz"
68
+ flapjack_path = File.join(tmpdir, "flapjack-#{current_commit}")
69
+ repo_path = File.expand_path(File.dirname(__FILE__))
70
+ ignores = %w(.gitignore .git)
71
+
72
+ # create new staging directory
73
+ command = "git clone #{repo_path} #{flapjack_path}"
74
+ `#{command}`
75
+
76
+ # remove files we don't want to publish
77
+ ignores.each do |filename|
78
+ path = File.join(flapjack_path, filename)
79
+ FileUtils.rm_rf(path)
80
+ end
81
+
82
+ deps = { :daemons => {
83
+ :source => "http://rubyforge.org/frs/download.php/34223/daemons-1.0.10.tgz",
84
+ :filename => "daemons-1.0.10.tar.gz"
85
+ },
86
+ :beanstalkd_client => {
87
+ :source => "http://github.com/kr/beanstalk-client-ruby/tarball/v1.0.2",
88
+ :filename => "beanstalkd-client-1.0.2.tar.gz"
89
+ },
90
+ :yajl_ruby => {
91
+ :source => "http://github.com/brianmario/yajl-ruby/tarball/0.6.4",
92
+ :filename => "yajl-ruby-0.6.4.tar.gz"
93
+ },
94
+ :tmail => {
95
+ :source => "http://rubyforge.org/frs/download.php/35297/tmail-1.2.3.1.tgz",
96
+ :filename => "tmail-1.2.3.1.tar.gz"
97
+ },
98
+ :xmpp4r => {
99
+ :source => "http://download.gna.org/xmpp4r/xmpp4r-0.4.tgz",
100
+ :filename => "xmpp4r-0.4.tar.gz"
101
+ },
102
+ :log4r => {
103
+ :source => "http://qa.debian.org/watch/sf.php/log4r/log4r-1.0.5.tgz",
104
+ :filename => "log4r-1.0.5.tar.gz"
105
+ }
106
+ }
107
+ deps.each_pair do |name, details|
108
+ puts "Pulling in #{name} dependency..."
109
+ # save file
110
+ saved_file = "/tmp/#{details[:filename]}"
111
+ File.open(saved_file, 'w') do |f|
112
+ f << open(details[:source]).read
113
+ end
114
+
115
+ `tar zxf #{saved_file} -C #{tmpdir}`
116
+ end
117
+
118
+ # build tarball
119
+ under = File.dirname(tmpdir)
120
+ staging = File.join("/tmp", "flapjack-#{current_commit}")
121
+ FileUtils.mv(tmpdir, staging)
122
+ actual = File.basename(staging)
123
+ command = "cd #{under} ; tar czf #{release_tarball} #{actual}"
124
+ system(command)
125
+
126
+ puts "Release tarball with deps at #{release_tarball}"
127
+ end
128
+
129
+ desc "dump out statements to create sqlite3 schema"
130
+ task :dm_debug do
131
+ require 'lib/flapjack/persistence/data_mapper'
132
+
133
+ DataMapper.logger.set_log(STDOUT, :debug)
134
+ DataMapper.setup(:default, "sqlite3:///tmp/sqlite3.db")
135
+ DataMapper.auto_migrate!
136
+ end
data/TODO.md CHANGED
@@ -1,53 +1,36 @@
1
- * create events for failed checks
1
+ * refactor couchdb backend to be less bongtastic
2
+ * write "action" hooks API on notifications
2
3
 
3
- * rethink Notifier/NotifierCLI split
4
- Notifier + NotifierCLI are tightly coupled, which makes it difficult to refactor
5
- follow Puppet's lead with Puppet::Application (NotifierCLI translates to Flapjack::Notifier::Application)
6
- implement simple interface application interface => Flapjack::Notifier::Application.run(options)
4
+ * write migration tool for sqlite3 => couchdb
7
5
 
6
+ * write persistence backend setup tool (create couchdb/sqlite3 database)
8
7
 
9
- * reduce notifier dependencies (e.g. xmpp4r over xmpp4r-simple)
10
- * make notification/escalation logic pluggable (to reduce packaging dependencies)
11
-
12
- * release Flapjack as a distribution-consumable tarball
13
- * automate building of release tarball that optionally pulls in dependencies
14
8
  * add lintian-like checks for verifying packagability (see http://pkg-ruby-extras.alioth.debian.org/upstream-devs.html)
15
-
16
- * build benchmarks for flapjack-{worker,notifier}
17
-
18
- * setup wiki.flapjack-project.com
19
- * documentation!
20
- * user
21
- * developer
22
- * step-by-step install guide
23
- * scaling guide
24
- * integrating with collectd guide
25
- * writing custom populators guide
26
- * write puppet manifests
27
-
28
- * build option to specify notifier(s) directory
29
9
  * sandbox flapjack-worker
30
- * provide config option for specifying sandbox dir
10
+ * write beanstalkd.yreserve to simplify code
11
+ * write beanstalkd.jput, beanstalkd.jreserve for native json api
12
+
13
+ * build config file/cli options proxy
14
+ * build easily runnable benchmarks for flapjack-{worker,notifier}
15
+
16
+ * update installation guide
17
+ * clean up persistence API to be more user friendly
31
18
 
19
+ * write puppet manifests
32
20
  * provide common interface for loading checks into beanstalk (extract from populator)
33
- * make message queueing interface more abstract (support for AMQP/RabbitMQ)
34
21
 
35
22
  * write zeroconf/avahi notifier
36
23
  * write growl notifier
37
24
  * write sms notifier
38
- * write way to customise notifier messages (email body, xmpp format)
25
+ * allow customisation of notifier messages (body, header)
39
26
 
40
27
  * http://www.kitchensoap.com/2009/10/05/meanwhile-more-meta-metrics/
41
28
 
42
- * write beanstalkd.yreserve to simplify code
43
- * write beanstalkd.jput, beanstalkd.jreserve for native json api
44
-
45
29
  * add support to worker and notifier for multiple beanstalkds
30
+ * patch beanstalk-client to recognise DRAINING status
46
31
 
47
32
  * write check generator
48
33
  * include a collection of common functions
49
34
  (logging to rrd, retreiving values, executing check)
50
- * patch beanstalk-client to recognise DRAINING status
51
-
52
35
 
53
36
 
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.dirname(__FILE__) + '/../lib' unless $:.include?(File.dirname(__FILE__) + '/../lib/')
4
+
5
+ require 'flapjack/cli/notifier'
6
+ require 'flapjack/applications/notifier'
7
+ require 'daemons'
8
+ require 'flapjack/patches'
9
+
10
+ # setup
11
+ @options = Flapjack::Notifier::Options.parse(ARGV)
12
+
13
+ log = Log4r::Logger.new("notifier")
14
+ log.add(Log4r::SyslogOutputter.new("notifier"))
15
+
16
+ app = Flapjack::Notifier::Application.run(:log => log,
17
+ :notifiers => {},
18
+ :filters => [],
19
+ :queue_backend => {:type => :beanstalkd},
20
+ :persistence => {:type => :data_mapper,
21
+ :uri => "sqlite3:///tmp/flapjack.db"})
22
+
23
+ mockapp = Flapjack::Notifier::Application.run(:log => log,
24
+ :notifiers => {},
25
+ :queue_backend => {:type => :mockbackend,
26
+ :basedir => File.join(File.dirname(__FILE__), '..', 'spec', 'transports')},
27
+ :persistence => {:type => :mockbackend,
28
+ :basedir => File.join(File.dirname(__FILE__), '..', 'spec', 'persistence')})
29
+
30
+ # populate
31
+ require 'beanstalk-client'
32
+ beanstalk = Beanstalk::Pool.new(["localhost:11300"], 'results')
33
+
34
+ puts "Writing 1000 passing checks onto work queue."
35
+ 2000.times do
36
+ result = {:output => "some output", :check_id => 1, :retval => 0}
37
+ beanstalk.yput(result)
38
+ end
39
+
40
+ # benchmark
41
+ require 'benchmark'
42
+
43
+ Benchmark.bm(30) do |b|
44
+ b.report("beanstalkd + datamapper:") do
45
+ 1000.times {app.process_result}
46
+ end
47
+ b.report("mock + mock:") do
48
+ 1000.times {mockapp.process_result}
49
+ end
50
+ end
@@ -2,45 +2,20 @@
2
2
 
3
3
  $: << File.dirname(__FILE__) + '/../lib' unless $:.include?(File.dirname(__FILE__) + '/../lib/')
4
4
 
5
- require 'rubygems'
6
- require 'beanstalk-client'
7
- require 'ostruct'
8
- require 'optparse'
9
- require 'log4r'
10
- require 'log4r/outputter/syslogoutputter'
11
- require 'flapjack/result'
12
- require 'flapjack/notifier'
5
+ require 'flapjack/cli/notifier'
6
+ require 'flapjack/applications/notifier'
13
7
  require 'daemons'
14
8
  require 'flapjack/patches'
15
9
 
16
- # command line options are in here
17
- require 'flapjack/cli/notifier'
18
-
19
- # boot up the notifier
20
- @options = Flapjack::NotifierOptions.parse(ARGV)
21
-
22
- ncli = Flapjack::NotifierCLI.new
23
- ncli.setup_loggers
24
- ncli.setup_recipients(:filename => @options.recipients)
25
- ncli.setup_config(:filename => @options.config_filename)
26
- ncli.setup_notifier
27
- ncli.setup_database(:database_uri => @options.database_uri)
28
-
29
- begin
30
-
31
- ncli.results_queue = Beanstalk::Pool.new(["#{@options.host}:#{@options.port}"], 'results')
32
- ncli.log.info("established connection to beanstalkd on #{@options.host}...")
33
-
34
- # process results
35
- ncli.process_loop
10
+ @options = Flapjack::Notifier::Options.parse(ARGV)
36
11
 
37
- rescue Beanstalk::NotConnected
38
- ncli.log.error("Couldn't connect to the Beanstalk!")
12
+ log = Log4r::Logger.new("notifier")
13
+ log.add(Log4r::StdoutOutputter.new("notifier"))
14
+ log.add(Log4r::SyslogOutputter.new("notifier"))
39
15
 
40
- timeout = 5
41
- ncli.log.error("Retrying in #{timeout} seconds.")
42
- sleep timeout
16
+ app = Flapjack::Notifier::Application.run(:log => log,
17
+ :notifiers => @options.notifiers,
18
+ :transport => @options.transport,
19
+ :persistence => @options.persistence)
20
+ app.main()
43
21
 
44
- ncli.log.error("Retrying...")
45
- retry
46
- end