flapjack 0.4.12 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
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