flapjack 0.9.6 → 1.0.0rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rspec +6 -0
  4. data/.travis.yml +20 -16
  5. data/CHANGELOG.md +11 -25
  6. data/Dockerfile +8 -0
  7. data/Gemfile +2 -5
  8. data/bin/flapjack +24 -213
  9. data/etc/flapjack_config.yaml.example +6 -30
  10. data/features/cli.feature +16 -14
  11. data/features/cli_flapjack-feed-events.feature +12 -13
  12. data/features/cli_flapjack-nagios-receiver.feature +14 -15
  13. data/features/cli_flapjack-populator.feature +16 -15
  14. data/features/cli_flapper.feature +12 -12
  15. data/features/cli_receive-events.feature +6 -5
  16. data/features/cli_simulate-failed-check.feature +7 -6
  17. data/features/steps/cli_steps.rb +2 -2
  18. data/features/support/env.rb +1 -0
  19. data/flapjack.gemspec +1 -0
  20. data/lib/flapjack/cli/flapper.rb +200 -0
  21. data/lib/flapjack/cli/import.rb +102 -0
  22. data/lib/flapjack/cli/receiver.rb +656 -0
  23. data/lib/flapjack/cli/server.rb +256 -0
  24. data/lib/flapjack/cli/simulate.rb +180 -0
  25. data/lib/flapjack/configuration.rb +2 -0
  26. data/lib/flapjack/data/entity_check.rb +5 -22
  27. data/lib/flapjack/data/event.rb +7 -12
  28. data/lib/flapjack/gateways/email.rb +4 -1
  29. data/lib/flapjack/gateways/jabber.rb +12 -36
  30. data/lib/flapjack/gateways/jsonapi/check_presenter.rb +6 -6
  31. data/lib/flapjack/gateways/jsonapi/report_methods.rb +5 -3
  32. data/lib/flapjack/gateways/pagerduty.rb +1 -1
  33. data/lib/flapjack/gateways/web/public/js/backbone.jsonapi.js +1 -1
  34. data/lib/flapjack/gateways/web/public/js/modules/contact.js +2 -2
  35. data/lib/flapjack/gateways/web/public/js/modules/entity.js +2 -2
  36. data/lib/flapjack/gateways/web/public/js/modules/medium.js +4 -4
  37. data/lib/flapjack/gateways/web/public/js/self_stats.js +1 -1
  38. data/lib/flapjack/gateways/web/views/check.html.erb +7 -7
  39. data/lib/flapjack/gateways/web/views/checks.html.erb +2 -3
  40. data/lib/flapjack/gateways/web/views/contact.html.erb +4 -4
  41. data/lib/flapjack/gateways/web/views/contacts.html.erb +2 -2
  42. data/lib/flapjack/gateways/web/views/edit_contacts.html.erb +1 -1
  43. data/lib/flapjack/gateways/web/views/entities.html.erb +1 -1
  44. data/lib/flapjack/gateways/web/views/entity.html.erb +1 -1
  45. data/lib/flapjack/gateways/web/views/index.html.erb +2 -2
  46. data/lib/flapjack/gateways/web/views/layout.erb +10 -10
  47. data/lib/flapjack/gateways/web/views/self_stats.html.erb +1 -1
  48. data/lib/flapjack/gateways/web.rb +36 -7
  49. data/lib/flapjack/pikelet.rb +0 -2
  50. data/lib/flapjack/processor.rb +3 -1
  51. data/lib/flapjack/redis_pool.rb +2 -6
  52. data/lib/flapjack/version.rb +1 -1
  53. data/spec/lib/flapjack/coordinator_spec.rb +3 -3
  54. data/spec/lib/flapjack/data/entity_check_spec.rb +2 -6
  55. data/spec/lib/flapjack/data/event_spec.rb +0 -31
  56. data/spec/lib/flapjack/gateways/email_spec.rb +109 -0
  57. data/spec/lib/flapjack/gateways/jabber_spec.rb +18 -16
  58. data/spec/lib/flapjack/gateways/jsonapi/check_presenter_spec.rb +12 -24
  59. data/spec/lib/flapjack/gateways/pagerduty_spec.rb +1 -1
  60. data/spec/lib/flapjack/gateways/web/views/check.html.erb_spec.rb +2 -0
  61. data/spec/lib/flapjack/gateways/web/views/contact.html.erb_spec.rb +2 -0
  62. data/spec/lib/flapjack/gateways/web/views/index.html.erb_spec.rb +2 -0
  63. data/spec/lib/flapjack/gateways/web_spec.rb +194 -145
  64. data/spec/lib/flapjack/redis_pool_spec.rb +0 -1
  65. data/spec/support/profile_all_formatter.rb +44 -0
  66. data/spec/support/uncolored_doc_formatter.rb +9 -0
  67. data/tasks/benchmarks.rake +0 -4
  68. metadata +28 -38
  69. data/.ruby-version +0 -1
  70. data/Gemfile-ruby1.9 +0 -28
  71. data/Gemfile-ruby1.9.lock +0 -227
  72. data/bin/flapjack-feed-events +0 -124
  73. data/bin/flapjack-nagios-receiver +0 -246
  74. data/bin/flapjack-nsca-receiver +0 -246
  75. data/bin/flapjack-populator +0 -132
  76. data/bin/flapper +0 -152
  77. data/bin/receive-events +0 -179
  78. data/bin/simulate-failed-check +0 -151
  79. data/lib/flapjack/data/migration.rb +0 -36
  80. data/lib/flapjack/gateways/api/contact_methods.rb +0 -369
  81. data/lib/flapjack/gateways/api/entity_check_presenter.rb +0 -218
  82. data/lib/flapjack/gateways/api/entity_methods.rb +0 -361
  83. data/lib/flapjack/gateways/api/entity_presenter.rb +0 -75
  84. data/lib/flapjack/gateways/api/rack/json_params_parser.rb +0 -26
  85. data/lib/flapjack/gateways/api.rb +0 -124
  86. data/spec/lib/flapjack/gateways/api/contact_methods_spec.rb +0 -772
  87. data/spec/lib/flapjack/gateways/api/entity_check_presenter_spec.rb +0 -211
  88. data/spec/lib/flapjack/gateways/api/entity_methods_spec.rb +0 -863
  89. data/spec/lib/flapjack/gateways/api/entity_presenter_spec.rb +0 -108
  90. data/spec/lib/flapjack/gateways/api_spec.rb +0 -30
@@ -1,246 +0,0 @@
1
- #!/usr/bin/env ruby
2
- #
3
- # Nagios.cfg should be enabled with a command_file:
4
- #
5
- # command_file=/var/lib/nagios3/rw/nagios.cmd
6
- #
7
- # The format this script expects looks like:
8
- # [$TIMET] PROCESS_SERVICE_CHECK_RESULT;$HOSTNAME$;$SERVICEDESC$;$SERVICESTATE$;$SERVICEOUTPUT$;$SERVICEPERFDATA$
9
- #
10
-
11
- unless $:.include?(File.dirname(__FILE__) + '/../lib/')
12
- $: << File.dirname(__FILE__) + '/../lib'
13
- end
14
-
15
- require 'optparse'
16
- require 'ostruct'
17
- require 'redis'
18
-
19
- require 'oj'
20
- Oj.default_options = { :indent => 0, :mode => :strict }
21
-
22
- require 'dante'
23
-
24
- require 'flapjack/configuration'
25
- require 'flapjack/data/event'
26
-
27
- # Nsca example line for a storage-device check:
28
- #[1393410685] PROCESS_SERVICE_CHECK_RESULT;db1.dev;STORAGE;0;Raid Set # 000 (800.0GB) is Normal.
29
-
30
- def process_input(opts)
31
- redis = opts[:redis]
32
- fifo = File.new(opts[:fifo])
33
- begin
34
- while line = fifo.gets
35
- skip unless line
36
- split_line = line.split(" ")
37
-
38
- timestamp, passivecheck = split_line
39
- split_passive = passivecheck.split(";")
40
- timestamp = timestamp.delete('[]')
41
-
42
- check_long_output = ''
43
- object_type, entity, check, state, check_output = split_passive
44
-
45
- case
46
- when (split_line.length < 2 || split_passive.length < 5)
47
- puts "ERROR - rejecting this line; illegal format: [#{line}]"
48
- next
49
- when (timestamp !~ /^\d+$/)
50
- puts "ERROR - rejecting this line; timestamp look like a timestamp: [#{line}]"
51
- next
52
- when (object_type != 'PROCESS_SERVICE_CHECK_RESULT')
53
- puts "ERROR - rejecting this line; identifier 'PROCESS_SERVICE_CHECK_RESULT' is missing: [#{line}]"
54
- next
55
- end
56
-
57
- puts "#{object_type}, #{timestamp}, #{entity}, #{check}, #{state}, #{check_output}"
58
-
59
- state = {'0' => 'ok', '1' => 'warning', '2' => 'critical'}[state.downcase] || 'unknown'
60
- event = {
61
- 'entity' => entity,
62
- 'check' => check,
63
- 'type' => 'service',
64
- 'state' => state,
65
- 'summary' => check_output,
66
- 'details' => nil,
67
- 'time' => timestamp,
68
- }
69
- Flapjack::Data::Event.add(event, :redis => redis)
70
- end
71
- rescue Redis::CannotConnectError
72
- puts "Error, unable to to connect to the redis server (#{$!})"
73
- end
74
- end
75
-
76
- def main(opts)
77
- fifo = opts[:fifo]
78
- redis = Redis.new(opts[:redis_options])
79
- while true
80
- process_input(:redis => redis, :fifo => fifo)
81
- puts "Whoops with the fifo, restarting main loop in 10 seconds"
82
- sleep 10
83
- end
84
- end
85
-
86
- options = OpenStruct.new
87
- options.config = Flapjack::Configuration::DEFAULT_CONFIG_PATH
88
- options.daemonize = nil
89
-
90
- exe = File.basename(__FILE__)
91
-
92
- optparse = OptionParser.new do |opts|
93
- opts.banner = "Usage: #{exe} COMMAND [OPTIONS]"
94
-
95
- opts.separator ""
96
- opts.separator "Commands"
97
- opts.separator " start #{" " * 25} start #{exe}"
98
- opts.separator " stop #{" " * 26} stop #{exe}"
99
- opts.separator " restart #{" " * 23} (re)start #{exe}"
100
- opts.separator " status #{" " * 24} see if #{exe} is running"
101
- opts.separator ""
102
- opts.separator "Options"
103
-
104
- opts.on("-c", "--config [PATH]", String, "PATH to the config file to use") do |c|
105
- options.config = c
106
- end
107
-
108
- opts.on("-f", "--fifo FIFO", String, "Path to the nagios perfdata named pipe") do |f|
109
- options.fifo = f
110
- end
111
-
112
- opts.on("-d", "--[no-]daemonize", "Daemonize?") do |d|
113
- options.daemonize = d
114
- end
115
-
116
- opts.on("-p", "--pidfile [PATH]", String, "PATH to the pidfile to write to") do |pid|
117
- options.pidfile = pid
118
- end
119
-
120
- opts.on("-l", "--logfile [PATH]", String, "PATH to the logfile to write to") do |l|
121
- options.logfile = l
122
- end
123
-
124
- opts.on_tail("-h", "--help", "Show this usage message") do
125
- puts opts
126
- puts '
127
- Required Nagios Configuration Changes
128
- -------------------------------------
129
-
130
- flapjack-nsca-receiver reads events from the nagios "command file" read from by Nagios, written to by the Nsca-daemon.
131
-
132
- The named pipe is automatically created by _nagios_ if it is enabled
133
- in the configfile:
134
-
135
- # modified lines:
136
- command_file=/var/lib/nagios3/rw/nagios.cmd
137
-
138
- The Nsca daemon is optionally writing to a tempfile if the named pipe does
139
- not exist.
140
-
141
- Details on the wiki: https://github.com/flapjack/flapjack/wiki/USING#XXX
142
- '
143
-
144
- exit
145
- end
146
-
147
- end
148
- optparse.parse!(ARGV)
149
-
150
- FLAPJACK_ENV = ENV['FLAPJACK_ENV'] || 'production'
151
-
152
- config = Flapjack::Configuration.new
153
- config.load(options.config)
154
- config_env = config.all
155
- redis_options = config.for_redis
156
-
157
- if config_env.nil? || config_env.empty?
158
- puts "No config data for environment '#{FLAPJACK_ENV}' found in '#{options.config}'"
159
- puts optparse
160
- exit 1
161
- end
162
-
163
- config_nr = config_env['nsca-receiver'] || {}
164
-
165
- pidfile = options.pidfile.nil? ?
166
- (config_nr['pid_file'] || "/var/run/flapjack/#{exe}.pid") :
167
- options.pidfile
168
-
169
- logfile = options.logfile.nil? ?
170
- (config_nr['log_file'] || "/var/log/flapjack/#{exe}.log") :
171
- options.logfile
172
-
173
- fifo = options.fifo.nil? ?
174
- (config_nr['fifo'] || '/var/lib/nagios3/rw/nagios.cmd') :
175
- options.fifo
176
-
177
- daemonize = options.daemonize.nil? ?
178
- !!config_nr['daemonize'] :
179
- options.daemonize
180
-
181
-
182
- runner = Dante::Runner.new(exe, :pid_path => pidfile, :log_path => logfile)
183
- case ARGV[0]
184
- when "start", "restart"
185
- unless File.exist?(fifo)
186
- raise "No fifo (named pipe) file found at #{fifo}"
187
- end
188
- unless File.pipe?(fifo)
189
- raise "The file at #{fifo} is not a named pipe, try using mkfifo to make one"
190
- end
191
- unless File.readable?(fifo)
192
- raise "The fifo (named pipe) at #{fifo} is unreadable"
193
- end
194
- end
195
-
196
- case ARGV[0]
197
- when "start"
198
- if runner.daemon_running?
199
- puts "#{exe} is already running."
200
- exit 1
201
- else
202
- print "#{exe} starting..."
203
- runner.execute(:daemonize => daemonize) {
204
- main(:redis_options => redis_options, :fifo => fifo)
205
- }
206
- puts " done."
207
- end
208
-
209
- when "stop"
210
- if runner.daemon_running?
211
- print "#{exe} stopping..."
212
- runner.execute(:kill => true)
213
- puts " done."
214
- else
215
- puts "#{exe} is not running."
216
- exit 1
217
- end
218
-
219
- when "restart"
220
- print "#{exe} restarting..."
221
- runner.execute(:daemonize => true, :restart => true) {
222
- main(:redis_options => redis_options, :fifo => fifo)
223
- }
224
- puts " done."
225
-
226
- when "status"
227
- uptime = (runner.daemon_running?) ? Time.now - File.stat(pidfile).ctime : 0
228
- if runner.daemon_running?
229
- puts "#{exe} is running: #{uptime}"
230
- else
231
- puts "#{exe} is not running"
232
- exit 3
233
- end
234
-
235
- else
236
- if ARGV.nil? || ARGV.empty?
237
- puts "No command provided"
238
- else
239
- puts "Unknown command provided: '#{ARGV[0]}'"
240
- end
241
- puts "\n#{optparse}"
242
- exit 1
243
-
244
- end
245
-
246
-
@@ -1,132 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'optparse'
4
- require 'ostruct'
5
-
6
- require 'oj'
7
- Oj.default_options = { :indent => 0, :mode => :strict }
8
-
9
- require 'redis'
10
-
11
- # add lib to the default include path
12
- unless $:.include?(File.dirname(__FILE__) + '/../lib/')
13
- $: << File.dirname(__FILE__) + '/../lib'
14
- end
15
-
16
- require 'flapjack/configuration'
17
- require 'flapjack/data/contact'
18
- require 'flapjack/data/entity'
19
- require 'flapjack/data/event'
20
-
21
- options = OpenStruct.new
22
- options.config = Flapjack::Configuration::DEFAULT_CONFIG_PATH
23
-
24
- exe = File.basename(__FILE__)
25
-
26
- optparse = OptionParser.new do |opts|
27
- opts.banner = "Usage: #{exe} COMMAND [OPTIONS]"
28
-
29
- opts.separator ""
30
- opts.separator "Commands:"
31
- opts.separator " import-entities"
32
- opts.separator " import-contacts"
33
- opts.separator " purge-events purge queued monitoring events"
34
- opts.separator ""
35
- opts.separator "Options"
36
-
37
- opts.on("-c", "--config [PATH]", String, "PATH to the config file to use") do |c|
38
- options.config = c
39
- end
40
-
41
- opts.on("-f", "--from [FILE]", String, "path to the FILE to import") do |f|
42
- options.from = f
43
- end
44
-
45
- end
46
- optparse.parse!(ARGV)
47
-
48
- bail_with_usage = proc do |message|
49
- puts message
50
- puts "\n#{optparse}"
51
- exit(false)
52
- end
53
-
54
- if options.help
55
- puts optparse
56
- exit
57
- elsif options.version
58
- puts Flapjack::VERSION
59
- exit
60
- elsif !["import-contacts", "import-entities", "purge-events"].include?(ARGV[0])
61
- message = if ARGV.nil? || ARGV.empty?
62
- "No command provided"
63
- else
64
- "Unknown command provided: '#{ARGV[0]}'"
65
- end
66
- bail_with_usage.call message
67
- end
68
-
69
- FLAPJACK_ENV = ENV['FLAPJACK_ENV'] || 'production'
70
-
71
- config = Flapjack::Configuration.new
72
- config.load(options.config)
73
- config_env = config.all
74
- redis_options = config.for_redis
75
-
76
- if config_env.nil? || config_env.empty?
77
- puts "No config data for environment '#{FLAPJACK_ENV}' found in '#{options.config}'"
78
- exit(false)
79
- end
80
-
81
- case ARGV[0]
82
- when "import-contacts"
83
- unless options.from
84
- bail_with_usage.call "No import file provided with --from, eg. --from contacts.json"
85
- end
86
- contacts = Oj.load(File.new(options.from))
87
-
88
- if contacts && contacts.is_a?(Enumerable) && contacts.any? {|e| !e['id'].nil?}
89
- @persistence = Redis.new(redis_options)
90
- contacts.each do |contact|
91
- unless contact['id']
92
- puts "Contact not imported as it has no id: " + contact.inspect
93
- next
94
- end
95
- Flapjack::Data::Contact.add(contact, :redis => @persistence)
96
- end
97
- @persistence.quit
98
- end
99
-
100
- when "import-entities"
101
- unless options.from
102
- bail_with_usage.call "No import file provided with --from, eg. --from contacts.json"
103
- end
104
- entities = Oj.load(File.new(options.from))
105
-
106
- if entities && entities.is_a?(Enumerable) && entities.any? {|e| !e['id'].nil?}
107
- @persistence = Redis.new(redis_options)
108
- entities.each do |entity|
109
- unless entity['id']
110
- puts "Entity not imported as it has no id: " + entity.inspect
111
- next
112
- end
113
- Flapjack::Data::Entity.add(entity, :redis => @persistence)
114
- end
115
- @persistence.quit
116
- end
117
-
118
- when "purge-events"
119
- @persistence = Redis.new(redis_options)
120
- events_size = @persistence.llen('events')
121
- puts "purging #{events_size} events..."
122
- etq = "events.#{Time.now.to_i}"
123
- puts "renaming 'events' to '#{etq}'"
124
- @persistence.rename('events', etq)
125
- puts "setting expiry of '#{etq}' to 8 hours"
126
- @persistence.expire(etq, (60 * 60 * 8))
127
- @persistence.quit
128
-
129
- else
130
- bail_with_usage.call "You need to give me something to do, eg. a command like 'import-entities', 'import-clients', etc."
131
- end
132
-
data/bin/flapper DELETED
@@ -1,152 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'optparse'
4
- require 'ostruct'
5
- require 'eventmachine'
6
- require 'socket'
7
- require 'dante'
8
-
9
- module Flapper
10
- def receive_data data
11
- send_data ">>>you sent: #{data}"
12
- close_connection if data =~ /quit/i
13
- end
14
- end
15
-
16
- def local_ip
17
- # turn off reverse DNS resolution temporarily
18
- orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true
19
-
20
- UDPSocket.open do |s|
21
- s.connect '64.233.187.99', 1
22
- s.addr.last
23
- end
24
- ensure
25
- Socket.do_not_reverse_lookup = orig
26
- end
27
-
28
- def main(bind_ip, bind_port, frequency)
29
- raise "bind_port must be an integer" unless bind_port.is_a?(Integer)
30
- start_every = frequency
31
- stop_after = frequency.to_f / 2
32
-
33
- EM.run {
34
-
35
- puts "#{Time.now}: starting server on #{bind_ip}:#{bind_port}"
36
- server_init = EM.start_server bind_ip, bind_port, Flapper
37
- EM.add_timer(stop_after) do
38
- puts "#{Time.now}: stopping server"
39
- EM.stop_server(server_init)
40
- end
41
-
42
- EM.add_periodic_timer(start_every) do
43
- puts "#{Time.now}: starting server on #{bind_ip}:#{bind_port}"
44
- server = EM.start_server bind_ip, bind_port, Flapper
45
- EM.add_timer(stop_after) do
46
- puts "#{Time.now}: stopping server"
47
- EM.stop_server(server)
48
- end
49
- end
50
- }
51
- end
52
-
53
- options = OpenStruct.new
54
- options.daemonize = nil
55
-
56
- exe = File.basename(__FILE__)
57
-
58
- OptionParser.new do |opts|
59
- opts.banner = "Usage: #{exe} COMMAND [OPTIONS]"
60
-
61
- opts.separator ""
62
- opts.separator "Commands"
63
- opts.separator " start #{" " * 25} start #{exe}"
64
- opts.separator " stop #{" " * 26} stop #{exe}"
65
- opts.separator " restart #{" " * 23} (re)start #{exe}"
66
- opts.separator " status #{" " * 24} see if #{exe} is running"
67
- opts.separator ""
68
- opts.separator "Options"
69
-
70
- opts.on("-d", "--[no-]daemonize", "Daemonize?") do |d|
71
- options.daemonize = d
72
- end
73
-
74
- opts.on("-p", "--pidfile [PATH]", String, "PATH to the pidfile to write to") do |pid|
75
- options.pidfile = pid
76
- end
77
-
78
- opts.on("-l", "--logfile [PATH]", String, "PATH to the logfile to write to") do |l|
79
- options.log_path = l
80
- end
81
-
82
- opts.on("-b", "--bind-ip [ADDRESS]", String, "ADDRESS (IPv4 or IPv6) for flapper to bind to") do |b|
83
- options.bind_ip = b
84
- end
85
-
86
- opts.on("-P", "--bind-port [PORT]", String, "PORT for flapper to bind to (default: 12345)") do |p|
87
- options.bind_port = p.to_i
88
- end
89
-
90
- opts.on("-f", "--frequency [SECONDS]", String, "oscillate with a frequency of SECONDS [120]") do |f|
91
- options.frequency = f.to_f
92
- end
93
-
94
- end.parse!(ARGV)
95
-
96
- daemonize = options.daemonize.nil? ? true : options.daemonize
97
- pidfile = options.pidfile || "/var/run/flapjack/#{exe}.pid"
98
- logfile = options.log_path || "/var/log/flapjack/#{exe}.log"
99
- bind_ip = options.bind_ip || local_ip
100
- bind_port = options.bind_port || 12345
101
- frequency = options.frequency || 120.0
102
-
103
- runner = Dante::Runner.new(exe, :pid_path => pidfile, :log_path => logfile)
104
-
105
- case ARGV[0]
106
- when "start"
107
- if runner.daemon_running?
108
- puts "#{exe} is already running."
109
- exit 1
110
- else
111
- print "#{exe} starting..."
112
- runner.execute(:daemonize => daemonize) {
113
- main(bind_ip, bind_port, frequency)
114
- }
115
- puts " done."
116
- end
117
-
118
- when "stop"
119
- if runner.daemon_running?
120
- print "#{exe} stopping..."
121
- runner.execute(:kill => true)
122
- puts " done."
123
- else
124
- puts "#{exe} is not running."
125
- exit 1
126
- end
127
-
128
- when "restart"
129
- print "#{exe} restarting..."
130
- runner.execute(:daemonize => true, :restart => true) {
131
- main(bind_ip, bind_port, frequency)
132
- }
133
- puts " done."
134
-
135
- when "status"
136
- uptime = (runner.daemon_running?) ? (Time.now - File.stat(pidfile).ctime) : 0
137
- if runner.daemon_running?
138
- puts "#{exe} is running: #{uptime}"
139
- else
140
- puts "#{exe} is not running"
141
- exit 3
142
- end
143
-
144
- else
145
- if ARGV.nil? || ARGV.empty?
146
- puts "No command provided"
147
- else
148
- puts "Unknown command provided: '#{ARGV[0]}'"
149
- end
150
- exit 1
151
-
152
- end
data/bin/receive-events DELETED
@@ -1,179 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- unless $:.include?(File.dirname(__FILE__) + '/../lib/')
4
- $: << File.dirname(__FILE__) + '/../lib'
5
- end
6
-
7
- require 'optparse'
8
- require 'ostruct'
9
- require 'redis'
10
-
11
- require 'oj'
12
- Oj.default_options = { :indent => 0, :mode => :strict }
13
-
14
- require 'flapjack/configuration'
15
- require 'flapjack/data/event'
16
-
17
- def pike(message)
18
- puts "piking out: #{message}"
19
- exit 1
20
- end
21
-
22
- def send_event(event, opts)
23
- Flapjack::Data::Event.add(event, :redis => opts[:redis])
24
- end
25
-
26
- def receive(opts)
27
- redis = Redis.new(opts[:redis_options])
28
- source_redis = Redis.new(:url => opts[:source])
29
-
30
- archives = get_archive_keys_stats(source_redis)
31
- raise "found no archives!" unless archives && archives.length > 0
32
-
33
- puts "found archives: #{archives.inspect}"
34
-
35
- # each archive bucket is a redis list that is written
36
- # with brpoplpush, that is newest items are added to the left (head)
37
- # of the list, so oldest events are to be found at the tail of the list.
38
- #
39
- # the index of these archives, in the 'archives' array, also stores the
40
- # redis key names for each bucket in oldest to newest
41
- events_sent = 0
42
- case
43
- when opts[:all]
44
- archive_key = archives[0][:name]
45
- cursor = -1
46
- when opts[:last], opts[:time]
47
- raise "Sorry, unimplemented"
48
- else
49
- # wait for the next event to be archived, so point the cursor at a non-existant
50
- # slot in the list, the one before the 0'th
51
- archive_key = archives[-1][:name]
52
- cursor = -1 - archives[-1][:size]
53
- end
54
-
55
- puts archive_key
56
-
57
- loop do
58
- new_archive_key = false
59
- # something to read at cursor?
60
- event = source_redis.lindex(archive_key, cursor)
61
- if event
62
- send_event(event, :redis => redis)
63
- events_sent += 1
64
- print "#{events_sent} " if events_sent % 1000 == 0
65
- cursor -= 1
66
- else
67
- puts "\narchive key: #{archive_key}, cursor: #{cursor}"
68
- # do we need to look at the next archive bucket?
69
- archives = get_archive_keys_stats(source_redis)
70
- i = archives.index {|a| a[:name] == archive_key }
71
- if archives[i][:size] = (cursor.abs + 1)
72
- if archives[i + 1]
73
- archive_key = archives[i + 1][:name]
74
- puts archive_key
75
- cursor = -1
76
- new_archive_key = true
77
- else
78
- return unless opts[:follow]
79
- end
80
- end
81
- sleep 1 unless new_archive_key
82
- end
83
- end
84
- end
85
-
86
- def get_archive_keys_stats(source_redis)
87
- source_redis.keys("events_archive:*").sort.map {|a|
88
- { :name => a,
89
- :size => source_redis.llen(a) }
90
- }
91
- end
92
-
93
- options = OpenStruct.new
94
- options.config = Flapjack::Configuration::DEFAULT_CONFIG_PATH
95
- options.daemonize = nil
96
-
97
- exe = File.basename(__FILE__)
98
-
99
- optparse = OptionParser.new do |opts|
100
- opts.banner = "Usage: #{exe} COMMAND [OPTIONS]"
101
-
102
- opts.separator ""
103
- opts.separator "Commands"
104
- opts.separator " help"
105
- opts.separator ""
106
- opts.separator "Options"
107
-
108
- opts.on("-c", "--config [PATH]", String, "PATH to the config file to use") do |c|
109
- options.config = c
110
- end
111
-
112
- opts.on("-s", "--source URL", String, "URL of source redis database, eg redis://localhost:6379/0") do |s|
113
- options.source = s
114
- end
115
-
116
- opts.on("-f", "--follow", String, "keep reading events as they are archived on the source") do |f|
117
- options.follow = true
118
- end
119
-
120
- opts.on("-a", "--all", String, "replay all archived events from the source") do |a|
121
- options.all = true
122
- end
123
-
124
- opts.on("-l", "--last COUNT", String, "replay the last COUNT events from the source") do |l|
125
- options.count = l
126
- end
127
-
128
- opts.on("-t", "--time TIME", String, "replay all events archived on the source since TIME") do |t|
129
- options.since = t
130
- end
131
-
132
- end
133
- optparse.parse!(ARGV)
134
-
135
- FLAPJACK_ENV = ENV['FLAPJACK_ENV'] || 'production'
136
-
137
- config = Flapjack::Configuration.new
138
- config.load(options.config)
139
- config_env = config.all
140
- redis_options = config.for_redis
141
-
142
- if config_env.nil? || config_env.empty?
143
- puts "No config data for environment '#{FLAPJACK_ENV}' found in '#{options.config}'"
144
- puts "\n#{optparse}"
145
- exit 1
146
- end
147
-
148
- case ARGV[0]
149
- when "help"
150
- puts optparse
151
- exit
152
- else
153
- unless ARGV.nil? || ARGV.empty?
154
- puts "Unknown command provided: '#{ARGV[0]}'"
155
- puts "\n#{optparse}"
156
- exit 1
157
- end
158
- end
159
-
160
- unless options.source
161
- puts "--source URL is required"
162
- puts "\n#{optparse}"
163
- exit 1
164
- end
165
-
166
- unless options.follow || options.all
167
- puts "one or both of --follow or --all is required"
168
- puts "\n#{optparse}"
169
- exit 1
170
- end
171
-
172
- receive(:follow => options.follow,
173
- :all => options.all,
174
- :source => options.source,
175
- :last => options.last,
176
- :time => options.time,
177
- :redis_options => redis_options)
178
-
179
-