fluq 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.travis.yml +6 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +39 -0
- data/MIT-LICENCE +19 -0
- data/README.md +10 -0
- data/Rakefile +11 -0
- data/benchmark/logging.rb +37 -0
- data/benchmark/socket.rb +52 -0
- data/bin/fluq-rb +8 -0
- data/examples/common.rb +3 -0
- data/examples/simple.rb +5 -0
- data/fluq.gemspec +33 -0
- data/lib/fluq.rb +50 -0
- data/lib/fluq/buffer.rb +6 -0
- data/lib/fluq/buffer/base.rb +51 -0
- data/lib/fluq/buffer/file.rb +68 -0
- data/lib/fluq/cli.rb +142 -0
- data/lib/fluq/dsl.rb +49 -0
- data/lib/fluq/dsl/options.rb +27 -0
- data/lib/fluq/error.rb +2 -0
- data/lib/fluq/event.rb +55 -0
- data/lib/fluq/feed.rb +6 -0
- data/lib/fluq/feed/base.rb +18 -0
- data/lib/fluq/feed/json.rb +28 -0
- data/lib/fluq/feed/msgpack.rb +27 -0
- data/lib/fluq/feed/tsv.rb +30 -0
- data/lib/fluq/handler.rb +6 -0
- data/lib/fluq/handler/base.rb +80 -0
- data/lib/fluq/handler/log.rb +67 -0
- data/lib/fluq/handler/null.rb +4 -0
- data/lib/fluq/input.rb +6 -0
- data/lib/fluq/input/base.rb +59 -0
- data/lib/fluq/input/socket.rb +50 -0
- data/lib/fluq/input/socket/connection.rb +41 -0
- data/lib/fluq/mixins.rb +6 -0
- data/lib/fluq/mixins/loggable.rb +7 -0
- data/lib/fluq/mixins/logger.rb +26 -0
- data/lib/fluq/reactor.rb +76 -0
- data/lib/fluq/testing.rb +26 -0
- data/lib/fluq/url.rb +16 -0
- data/lib/fluq/version.rb +3 -0
- data/spec/fluq/buffer/base_spec.rb +21 -0
- data/spec/fluq/buffer/file_spec.rb +47 -0
- data/spec/fluq/dsl/options_spec.rb +24 -0
- data/spec/fluq/dsl_spec.rb +43 -0
- data/spec/fluq/event_spec.rb +25 -0
- data/spec/fluq/feed/base_spec.rb +15 -0
- data/spec/fluq/feed/json_spec.rb +27 -0
- data/spec/fluq/feed/msgpack_spec.rb +27 -0
- data/spec/fluq/feed/tsv_spec.rb +27 -0
- data/spec/fluq/handler/base_spec.rb +70 -0
- data/spec/fluq/handler/log_spec.rb +68 -0
- data/spec/fluq/handler/null_spec.rb +11 -0
- data/spec/fluq/input/base_spec.rb +29 -0
- data/spec/fluq/input/socket/connection_spec.rb +35 -0
- data/spec/fluq/input/socket_spec.rb +45 -0
- data/spec/fluq/mixins/loggable_spec.rb +10 -0
- data/spec/fluq/mixins/logger_spec.rb +25 -0
- data/spec/fluq/reactor_spec.rb +58 -0
- data/spec/fluq/url_spec.rb +16 -0
- data/spec/fluq_spec.rb +11 -0
- data/spec/scenario/config/nested/common.rb +3 -0
- data/spec/scenario/config/test.rb +3 -0
- data/spec/scenario/lib/fluq/handler/custom/test_handler.rb +4 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/configuration.rb +25 -0
- metadata +242 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
fluq (0.7.0)
|
5
|
+
eventmachine-le
|
6
|
+
msgpack (~> 0.5.0)
|
7
|
+
oj (>= 2.0.10)
|
8
|
+
timed_lru
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
diff-lcs (1.2.4)
|
14
|
+
eventmachine-le (1.1.5)
|
15
|
+
msgpack (0.5.5)
|
16
|
+
oj (2.1.3)
|
17
|
+
rake (10.1.0)
|
18
|
+
rspec (2.13.0)
|
19
|
+
rspec-core (~> 2.13.0)
|
20
|
+
rspec-expectations (~> 2.13.0)
|
21
|
+
rspec-mocks (~> 2.13.0)
|
22
|
+
rspec-core (2.13.1)
|
23
|
+
rspec-expectations (2.13.0)
|
24
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
25
|
+
rspec-mocks (2.13.1)
|
26
|
+
timed_lru (0.3.1)
|
27
|
+
yard (0.8.6.2)
|
28
|
+
|
29
|
+
PLATFORMS
|
30
|
+
java
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
bundler
|
35
|
+
fluq!
|
36
|
+
oj
|
37
|
+
rake
|
38
|
+
rspec
|
39
|
+
yard
|
data/MIT-LICENCE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
2
|
+
a copy of this software and associated documentation files (the
|
3
|
+
"Software"), to deal in the Software without restriction, including
|
4
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
5
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
6
|
+
permit persons to whom the Software is furnished to do so, subject to
|
7
|
+
the following conditions:
|
8
|
+
|
9
|
+
The above copyright notice and this permission notice shall be
|
10
|
+
included in all copies or substantial portions of the Software.
|
11
|
+
|
12
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
13
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
14
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
15
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
16
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
17
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
18
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
19
|
+
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift(File.expand_path('../../lib', __FILE__))
|
4
|
+
|
5
|
+
require 'bundler/setup'
|
6
|
+
require 'fluq'
|
7
|
+
require 'benchmark'
|
8
|
+
|
9
|
+
ITER = 100_000
|
10
|
+
|
11
|
+
MultiJson.use :oj
|
12
|
+
FileUtils.rm_rf FluQ.root.join("log/benchmark")
|
13
|
+
|
14
|
+
events = (1..ITER).map do
|
15
|
+
FluQ::Event.new "a.b#{rand(4)}.c#{rand(100)}.d#{rand(100)}", Time.now.to_i, "k1" => "value", "k2" => "value", "k3" => "value"
|
16
|
+
end
|
17
|
+
|
18
|
+
handler = FluQ::Handler::Log.new \
|
19
|
+
path: "log/benchmark/%Y%m/%d/%H/%t.log",
|
20
|
+
rewrite: lambda {|t| t.split(".")[1] }
|
21
|
+
|
22
|
+
puts "--> Started benchmark"
|
23
|
+
processed = Benchmark.realtime do
|
24
|
+
num = 0
|
25
|
+
events.each_slice(1_000) do |slice|
|
26
|
+
handler.on_events(slice)
|
27
|
+
num += slice.size
|
28
|
+
if (num % 10_000).zero?
|
29
|
+
puts "--> Processed : #{num}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
puts "--> Processed : #{events.size} in #{processed.round(1)}s"
|
35
|
+
files = Dir[FluQ.root.join("log/benchmark/**/*.log").to_s]
|
36
|
+
lines = `cat #{files.join(' ')} | wc -l`.strip
|
37
|
+
puts "--> Written : #{lines} lines"
|
data/benchmark/socket.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$:.unshift(File.expand_path('../../lib', __FILE__))
|
4
|
+
|
5
|
+
require 'bundler/setup'
|
6
|
+
require 'fluq'
|
7
|
+
|
8
|
+
BATCH_SIZE = 100_000
|
9
|
+
BATCHES = 50
|
10
|
+
ROOT = FluQ.root.join("log/benchmark")
|
11
|
+
EVENT = FluQ::Event.new("a.b.c.d", Time.now.to_i, "k1" => "value", "k2" => "value", "k3" => "value").to_msgpack
|
12
|
+
|
13
|
+
FileUtils.rm_rf ROOT.to_s
|
14
|
+
FileUtils.mkdir_p ROOT.to_s
|
15
|
+
|
16
|
+
class FluQ::Handler::Counter < FluQ::Handler::Base
|
17
|
+
attr_reader :count
|
18
|
+
def initialize(*)
|
19
|
+
super
|
20
|
+
@count = 0
|
21
|
+
end
|
22
|
+
def on_events(events)
|
23
|
+
@count += events.size
|
24
|
+
EM.stop if @count >= BATCHES * BATCH_SIZE
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
puts "--> Preparing"
|
29
|
+
BATCHES.times do |i|
|
30
|
+
ROOT.join("batch.#{i}").open("wb:ASCII-8BIT") do |file|
|
31
|
+
BATCH_SIZE.times { file.write(EVENT) }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
processed = 0
|
36
|
+
handler = nil
|
37
|
+
start = Time.now
|
38
|
+
FluQ::Reactor.run do |reactor|
|
39
|
+
reactor.listen FluQ::Input::Socket, bind: "tcp://127.0.0.1:8765"
|
40
|
+
handler = reactor.register FluQ::Handler::Counter
|
41
|
+
|
42
|
+
sleep(0.1)
|
43
|
+
start = Time.now
|
44
|
+
puts "--> Started benchmark"
|
45
|
+
BATCHES.times do |i|
|
46
|
+
file = ROOT.join("batch.#{i}")
|
47
|
+
spawn("nc 127.0.0.1 8765 < #{file}")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
puts "--> Accepted : #{BATCHES * BATCH_SIZE} in #{(Time.now - start).round(1)}s"
|
52
|
+
puts "--> Processed : #{handler.count} events"
|
data/bin/fluq-rb
ADDED
data/examples/common.rb
ADDED
data/examples/simple.rb
ADDED
data/fluq.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
$:.push File.expand_path("../lib", __FILE__)
|
4
|
+
require "fluq/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.required_ruby_version = '>= 1.9.1'
|
8
|
+
s.required_rubygems_version = ">= 1.8.0"
|
9
|
+
|
10
|
+
s.name = File.basename(__FILE__, '.gemspec')
|
11
|
+
s.summary = "FluQ"
|
12
|
+
s.description = "The minimalistic stream processor"
|
13
|
+
s.version = FluQ::VERSION.dup
|
14
|
+
|
15
|
+
s.authors = ["Black Square Media"]
|
16
|
+
s.email = "info@blacksquaremedia.com"
|
17
|
+
s.homepage = "https://github.com/bsm/fluq"
|
18
|
+
|
19
|
+
s.require_path = 'lib'
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
|
24
|
+
s.add_dependency "msgpack", "~> 0.5.0"
|
25
|
+
s.add_dependency "eventmachine-le"
|
26
|
+
s.add_dependency "oj", ">= 2.0.10"
|
27
|
+
s.add_dependency "timed_lru"
|
28
|
+
|
29
|
+
s.add_development_dependency "rake"
|
30
|
+
s.add_development_dependency "bundler"
|
31
|
+
s.add_development_dependency "rspec"
|
32
|
+
s.add_development_dependency "yard"
|
33
|
+
end
|
data/lib/fluq.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'uri'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'securerandom'
|
5
|
+
require 'forwardable'
|
6
|
+
require 'logger'
|
7
|
+
require 'eventmachine'
|
8
|
+
require 'msgpack'
|
9
|
+
require 'oj'
|
10
|
+
require 'timed_lru'
|
11
|
+
|
12
|
+
module FluQ
|
13
|
+
%w'version error mixins'.each do |name|
|
14
|
+
require "fluq/#{name}"
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
|
19
|
+
# @attr_reader [String] env runtime environemnt
|
20
|
+
# @attr_reader [Pathname] root project root
|
21
|
+
# @attr_reader [Logger] logger the main logger
|
22
|
+
attr_reader :env, :root, :logger
|
23
|
+
|
24
|
+
# @param [Logger] instance the thread-safe logger instance
|
25
|
+
def logger=(instance)
|
26
|
+
instance.extend(FluQ::Mixins::Logger)
|
27
|
+
@logger = instance
|
28
|
+
end
|
29
|
+
|
30
|
+
def init!
|
31
|
+
# Detect environment
|
32
|
+
@env = ENV['FLUQ_ENV'] || "development"
|
33
|
+
|
34
|
+
# Set root path
|
35
|
+
@root = Pathname.new(ENV['FLUQ_ROOT'] || ".")
|
36
|
+
|
37
|
+
# Setup logger
|
38
|
+
self.logger = ::Logger.new(STDOUT)
|
39
|
+
logger.level = ::Logger::INFO if env == "production"
|
40
|
+
end
|
41
|
+
protected :init!
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
init!
|
46
|
+
end
|
47
|
+
|
48
|
+
%w'url event reactor handler input buffer feed dsl'.each do |name|
|
49
|
+
require "fluq/#{name}"
|
50
|
+
end
|
data/lib/fluq/buffer.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
class FluQ::Buffer::Base
|
2
|
+
MAX_SIZE = 256 * 1024 * 1024 # 256M
|
3
|
+
|
4
|
+
# @attr_reader [Hash] config
|
5
|
+
attr_reader :config
|
6
|
+
|
7
|
+
# @param [Hash] options various configuration options
|
8
|
+
def initialize(options = {})
|
9
|
+
super()
|
10
|
+
@config = defaults.merge(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [String] name identifier
|
14
|
+
def name
|
15
|
+
@name ||= self.class.name.split("::").last.downcase
|
16
|
+
end
|
17
|
+
|
18
|
+
# @abstract
|
19
|
+
# @yield over io object
|
20
|
+
# @yieldparam [IO] io
|
21
|
+
def drain
|
22
|
+
yield StringIO.new
|
23
|
+
end
|
24
|
+
|
25
|
+
# @abstract
|
26
|
+
# @return [Integer] the size
|
27
|
+
def size
|
28
|
+
0
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Boolean] true if size exceeds limit
|
32
|
+
def full?
|
33
|
+
size >= config[:max_size]
|
34
|
+
end
|
35
|
+
|
36
|
+
# @abstract data writer
|
37
|
+
# @param [String] data binary string
|
38
|
+
def write(data)
|
39
|
+
end
|
40
|
+
|
41
|
+
# @abstract callback, close buffer
|
42
|
+
def close
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
def defaults
|
48
|
+
{ max_size: MAX_SIZE }
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
class FluQ::Buffer::File < FluQ::Buffer::Base
|
2
|
+
|
3
|
+
# @attr_reader [File] file instance
|
4
|
+
attr_reader :file
|
5
|
+
|
6
|
+
# @see FluQ::Buffer::Base#initialize
|
7
|
+
def initialize(*)
|
8
|
+
super
|
9
|
+
@file = new_file
|
10
|
+
@size = 0
|
11
|
+
end
|
12
|
+
|
13
|
+
# @see FluQ::Buffer::Base#name
|
14
|
+
def name
|
15
|
+
@name ||= [super, File.basename(file.path)].join("-")
|
16
|
+
end
|
17
|
+
|
18
|
+
# @see FluQ::Buffer::Base#write
|
19
|
+
def write(data)
|
20
|
+
file.write(data)
|
21
|
+
end
|
22
|
+
|
23
|
+
# @see FluQ::Buffer::Base#size
|
24
|
+
def size
|
25
|
+
file.size
|
26
|
+
end
|
27
|
+
|
28
|
+
# @see FluQ::Buffer::Base#close
|
29
|
+
def close
|
30
|
+
file.close unless file.closed?
|
31
|
+
File.unlink(file.path) if File.exists?(file.path)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @see FluQ::Buffer::Base#drain
|
35
|
+
def drain
|
36
|
+
file.close unless file.closed?
|
37
|
+
io = File.open(file.path, 'rb', encoding: Encoding::BINARY)
|
38
|
+
yield(io)
|
39
|
+
ensure
|
40
|
+
io.close if io
|
41
|
+
end
|
42
|
+
|
43
|
+
protected
|
44
|
+
|
45
|
+
def defaults
|
46
|
+
super.merge(path: "tmp/buffers")
|
47
|
+
end
|
48
|
+
|
49
|
+
def new_file
|
50
|
+
path = nil
|
51
|
+
incr = 0
|
52
|
+
path = root.join(generate_name(incr+=1)) until path && !path.exist?
|
53
|
+
file = path.open("wb", encoding: Encoding::BINARY)
|
54
|
+
file.sync = true
|
55
|
+
file
|
56
|
+
end
|
57
|
+
|
58
|
+
def root
|
59
|
+
@root ||= FluQ.root.join(config[:path]).tap do |full_path|
|
60
|
+
FileUtils.mkdir_p full_path.to_s
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def generate_name(index)
|
65
|
+
"fb-#{(Time.now.utc.to_f * 1000).round}.#{index}"
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/lib/fluq/cli.rb
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
require "optparse"
|
2
|
+
require "fileutils"
|
3
|
+
require "socket"
|
4
|
+
|
5
|
+
module FluQ
|
6
|
+
class CLI
|
7
|
+
SIGNALS = [ :QUIT, :INT, :TERM, :HUP ]
|
8
|
+
|
9
|
+
# attr_reader [Hash] options
|
10
|
+
attr_reader :options
|
11
|
+
|
12
|
+
# Runs the CLI
|
13
|
+
def self.run
|
14
|
+
if BasicSocket.respond_to?(:do_not_reverse_lookup=)
|
15
|
+
BasicSocket.do_not_reverse_lookup = true
|
16
|
+
end
|
17
|
+
new.run
|
18
|
+
end
|
19
|
+
|
20
|
+
# Constructor
|
21
|
+
def initialize
|
22
|
+
super
|
23
|
+
|
24
|
+
# Parse options
|
25
|
+
@options = {}
|
26
|
+
parser.parse!(ARGV)
|
27
|
+
end
|
28
|
+
|
29
|
+
def run
|
30
|
+
# Exit if not configured correctly
|
31
|
+
unless configured?
|
32
|
+
puts parser
|
33
|
+
exit
|
34
|
+
end
|
35
|
+
|
36
|
+
# Set the environment
|
37
|
+
if options[:env]
|
38
|
+
ENV["FLUQ_ENV"] = options[:env]
|
39
|
+
end
|
40
|
+
|
41
|
+
# Boot and add project's lib/ dir to load path
|
42
|
+
require 'fluq'
|
43
|
+
$LOAD_PATH.unshift FluQ.root.join('lib')
|
44
|
+
procline "(starting)"
|
45
|
+
|
46
|
+
# Setup logger
|
47
|
+
if options[:log]
|
48
|
+
FileUtils.mkdir_p(File.dirname(options[:log]))
|
49
|
+
FluQ.logger = ::Logger.new(options[:log])
|
50
|
+
end
|
51
|
+
if options[:verbose]
|
52
|
+
FluQ.logger.level = ::Logger::DEBUG
|
53
|
+
end
|
54
|
+
|
55
|
+
# Write PID file
|
56
|
+
@pidfile = options[:pidfile] || FluQ.root.join("tmp", "pids", "fluq.pid")
|
57
|
+
FileUtils.mkdir_p(File.dirname(@pidfile))
|
58
|
+
File.open(@pidfile, "w") {|f| f.write Process.pid }
|
59
|
+
|
60
|
+
# Trap signals
|
61
|
+
SIGNALS.each do |signal|
|
62
|
+
trap(signal) {|*| shutdown! }
|
63
|
+
end
|
64
|
+
|
65
|
+
# Start
|
66
|
+
log "Starting FluQ #{FluQ::VERSION} (#{FluQ.env})"
|
67
|
+
FluQ::Reactor.run do |reactor|
|
68
|
+
FluQ::DSL.new(reactor, options[:config]).run
|
69
|
+
procline
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# @return [Boolean] true if configured
|
74
|
+
def configured?
|
75
|
+
options[:config] && File.file?(options[:config])
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
# Shut down
|
81
|
+
def shutdown!
|
82
|
+
FluQ.logger.info "Shutting down FluQ" if defined?(FluQ)
|
83
|
+
FileUtils.rm_f(@pidfile) if @pidfile
|
84
|
+
exit
|
85
|
+
end
|
86
|
+
|
87
|
+
def log(message)
|
88
|
+
FluQ.logger.info(message)
|
89
|
+
end
|
90
|
+
|
91
|
+
def procline(message = nil)
|
92
|
+
$0 = ["fluq-rb", FluQ::VERSION, message].compact.join(" ")
|
93
|
+
end
|
94
|
+
|
95
|
+
def parser
|
96
|
+
@parser ||= OptionParser.new do |o|
|
97
|
+
o.banner = "Usage: #{File.basename($0)} [OPTIONS]"
|
98
|
+
|
99
|
+
o.separator ""
|
100
|
+
o.separator "Required:"
|
101
|
+
|
102
|
+
o.on "-C", "--config FILE", "Use this config file" do |val|
|
103
|
+
@options[:config] = val
|
104
|
+
end
|
105
|
+
|
106
|
+
o.separator ""
|
107
|
+
o.separator "Optional:"
|
108
|
+
|
109
|
+
o.on("-e", "--environment ENV", "Runtime environment (default: development)") do |val|
|
110
|
+
@options[:env] = val
|
111
|
+
end
|
112
|
+
|
113
|
+
o.on("-l", "--log FILE", "File to log to (default: STDOUT)") do |val|
|
114
|
+
@options[:log] = val
|
115
|
+
end
|
116
|
+
|
117
|
+
o.on("-v", "--verbose", "Use verbose output") do |val|
|
118
|
+
@options[:verbose] = true
|
119
|
+
end
|
120
|
+
|
121
|
+
o.separator ""
|
122
|
+
|
123
|
+
o.on "--pidfile FILE", "Path to pidfile (default: tmp/pids/fluq.pid)" do |val|
|
124
|
+
@options[:pidfile] = val
|
125
|
+
end
|
126
|
+
|
127
|
+
o.separator ""
|
128
|
+
|
129
|
+
o.on("-h", "--help", "Show this message") do
|
130
|
+
puts o
|
131
|
+
exit
|
132
|
+
end
|
133
|
+
|
134
|
+
o.on("-V", "--version", "Show version") do
|
135
|
+
puts FluQ::VERSION
|
136
|
+
exit
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
end
|