flumify 0.0.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.
- data/.bundle/config +2 -0
- data/.rvmrc +2 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +29 -0
- data/README +0 -0
- data/config/config.yaml +0 -0
- data/example/decommission.rb +10 -0
- data/example/example.rb +19 -0
- data/flumify.gemspec +23 -0
- data/lib/flume_master.rb +41 -0
- data/lib/flumify/version.rb +3 -0
- data/lib/flumify.rb +35 -0
- data/lib/ssh_connection.rb +15 -0
- data/rakefile +12 -0
- data/spec/flumify_spec.rb +68 -0
- metadata +98 -0
data/.bundle/config
ADDED
data/.rvmrc
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
flumify (0.0.1)
|
5
|
+
net-ssh (~> 2.1.4)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
remote: http://gems.trafficbroker.co.uk/
|
10
|
+
specs:
|
11
|
+
diff-lcs (1.1.2)
|
12
|
+
fwd (0.2.0)
|
13
|
+
net-ssh (2.1.4)
|
14
|
+
rspec (2.5.0)
|
15
|
+
rspec-core (~> 2.5.0)
|
16
|
+
rspec-expectations (~> 2.5.0)
|
17
|
+
rspec-mocks (~> 2.5.0)
|
18
|
+
rspec-core (2.5.2)
|
19
|
+
rspec-expectations (2.5.0)
|
20
|
+
diff-lcs (~> 1.1.2)
|
21
|
+
rspec-mocks (2.5.0)
|
22
|
+
|
23
|
+
PLATFORMS
|
24
|
+
ruby
|
25
|
+
|
26
|
+
DEPENDENCIES
|
27
|
+
flumify!
|
28
|
+
fwd (= 0.2.0)
|
29
|
+
rspec (= 2.5.0)
|
data/README
ADDED
File without changes
|
data/config/config.yaml
ADDED
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require File.join(File.dirname(__FILE__), %w[.. lib flume_master])
|
3
|
+
|
4
|
+
logical_nodes = ["a","b","c","d", "e","f"]
|
5
|
+
logical_nodes = logical_nodes.map {|node| "#{node}.my.machine.ip"}
|
6
|
+
|
7
|
+
master = FlumeMaster.new(:host => "flume.master", :username => "user", :password => "password")
|
8
|
+
|
9
|
+
|
10
|
+
master.decommission(logical_nodes)
|
data/example/example.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require File.join(File.dirname(__FILE__), %w[.. lib flume_master])
|
3
|
+
require File.join(File.dirname(__FILE__), %w[.. lib flumify])
|
4
|
+
|
5
|
+
|
6
|
+
config = Flumify.new("machine-to-configure") do
|
7
|
+
internal_collector :host => "internal-collector", :port => 35853
|
8
|
+
external_collector :host => "external-collector", :port => 35853
|
9
|
+
|
10
|
+
logical_node "access-logs", {:tail => "/mnt/logs/*.log", :bucket => "logs"}
|
11
|
+
logical_node "advert-clicks", {:tail => "/mnt/logs/clicks.log", :bucket => "clicks"}
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
master = FlumeMaster.new(:host => "flume.master", :username => "user", :password => "password")
|
16
|
+
master.apply(config)
|
17
|
+
|
18
|
+
|
19
|
+
|
data/flumify.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "flumify/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "flumify"
|
7
|
+
s.version = Flumify::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Ryan Greenhall", "Tom Hall"]
|
10
|
+
s.email = ["ryan.greenhall@gmail.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Simple flume configuration}
|
13
|
+
s.description = %q{}
|
14
|
+
|
15
|
+
s.rubyforge_project = "flumify"
|
16
|
+
|
17
|
+
s.add_dependency("net-ssh", ["~> 2.1.4"])
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
end
|
data/lib/flume_master.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require 'net/ssh'
|
3
|
+
require File.join(File.dirname(__FILE__), "ssh_connection")
|
4
|
+
|
5
|
+
class FlumeMaster
|
6
|
+
def initialize(opts)
|
7
|
+
@connection = SSHConnection.new({ :host => opts[:host],
|
8
|
+
:username => opts[:username],
|
9
|
+
:password => opts[:password]})
|
10
|
+
@connection.debug = true if opts[:debug] == true
|
11
|
+
end
|
12
|
+
|
13
|
+
def apply(config)
|
14
|
+
config.logical_nodes.each do |logical_node_command|
|
15
|
+
execute logical_node_command
|
16
|
+
end
|
17
|
+
|
18
|
+
config.node_configurations.each do |config|
|
19
|
+
config = config.gsub("\"", "\\\"")
|
20
|
+
execute "flume shell -c localhost -e \"exec multiconfig '#{config}'\""
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def decommission(nodes)
|
25
|
+
nodes.each do |node|
|
26
|
+
execute "flume shell -c localhost -e 'exec decommission #{node}'"
|
27
|
+
execute "flume shell -c localhost -e 'exec purge #{node}'"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def execute(command)
|
34
|
+
3.times do
|
35
|
+
response = @connection.send_command command
|
36
|
+
puts response
|
37
|
+
break if response.include? "Command succeeded"
|
38
|
+
sleep 3
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/flumify.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "ssh_connection")
|
2
|
+
require File.join(File.dirname(__FILE__), "flume_master")
|
3
|
+
|
4
|
+
class Flumify
|
5
|
+
|
6
|
+
attr_accessor :the_internal_collector, :the_external_collector, :logical_nodes, :node_configurations
|
7
|
+
|
8
|
+
def initialize(server, &blk)
|
9
|
+
@server = server
|
10
|
+
@logical_nodes = []
|
11
|
+
@node_configurations = []
|
12
|
+
instance_eval(&blk) if blk
|
13
|
+
end
|
14
|
+
|
15
|
+
def internal_collector(collector)
|
16
|
+
@the_internal_collector = collector
|
17
|
+
end
|
18
|
+
|
19
|
+
def external_collector(collector)
|
20
|
+
@the_external_collector = collector
|
21
|
+
end
|
22
|
+
|
23
|
+
def logical_node(name, opts)
|
24
|
+
@logical_nodes << "flume shell -c localhost -e 'exec spawn #{@server} #{name}.#{@server}'"
|
25
|
+
|
26
|
+
if opts[:tail].include? "*"
|
27
|
+
split = opts[:tail].split("*")
|
28
|
+
directory = split[0]
|
29
|
+
glob_pattern = ".*" + split[1]
|
30
|
+
@node_configurations << "#{name}.#{@server} : tailDir( \"#{directory}\", \"#{glob_pattern}\" ) | { value(\"bucket\", \"#{opts[:bucket]}\") => agentBEChain(\"#{@the_internal_collector[:host]}:#{@the_internal_collector[:port]}\",\"#{@the_external_collector[:host]}:#{@the_external_collector[:port]}\") };"
|
31
|
+
else
|
32
|
+
@node_configurations << "#{name}.#{@server} : tail( \"#{opts[:tail]}\", true ) | { value(\"bucket\", \"#{opts[:bucket]}\") => agentBEChain(\"#{@the_internal_collector[:host]}:#{@the_internal_collector[:port]}\",\"#{@the_external_collector[:host]}:#{@the_external_collector[:port]}\") };"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class SSHConnection
|
2
|
+
attr_accessor :debug
|
3
|
+
|
4
|
+
def initialize(config)
|
5
|
+
@connection = Net::SSH.start(config[:host], config[:username], :password => config[:password])
|
6
|
+
end
|
7
|
+
|
8
|
+
def send_command(commandstr)
|
9
|
+
if !@debug
|
10
|
+
@connection.exec! commandstr
|
11
|
+
else
|
12
|
+
puts "command: #{commandstr}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/rakefile
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "../lib/flumify")
|
2
|
+
|
3
|
+
describe "Flumify" do
|
4
|
+
|
5
|
+
it "allows collectors to be specified" do
|
6
|
+
config = Flumify.new("ec2.us-west-1a") do
|
7
|
+
internal_collector "ec2-foo"
|
8
|
+
external_collector "ec2-bar"
|
9
|
+
|
10
|
+
logical_node "query", {:tail => "/my/file", :bucket => "ask-query"}
|
11
|
+
logical_node "adclick", {:tail => "/my/file", :bucket => "ask-query"}
|
12
|
+
logical_node "redirect", {:tail => "/my/file", :bucket => "ask-query"}
|
13
|
+
logical_node "query", {:tail => "/my/file", :bucket => "ask-query"}
|
14
|
+
end
|
15
|
+
|
16
|
+
config.the_internal_collector.should == "ec2-foo"
|
17
|
+
config.the_external_collector.should == "ec2-bar"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "allows logical nodes to be specified" do
|
21
|
+
config = Flumify.new("ec2.us-west-1a") do
|
22
|
+
internal_collector "ec2-foo"
|
23
|
+
external_collector "ec2-bar"
|
24
|
+
|
25
|
+
logical_node "query", {:tail => "/my/file", :bucket => "ask-query"}
|
26
|
+
end
|
27
|
+
|
28
|
+
config.logical_nodes.should include "flume shell -c localhost -e 'exec spawn ec2.us-west-1a query.ec2.us-west-1a'"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "creates node configuration" do
|
32
|
+
config = Flumify.new("ec2.us-west-1a") do
|
33
|
+
internal_collector :host => "ec2-foo", :port => 35853
|
34
|
+
external_collector :host => "ec2-bar", :port => 35853
|
35
|
+
|
36
|
+
logical_node "query", {:tail => "/path/to/query.log", :bucket => "ask-query"}
|
37
|
+
end
|
38
|
+
|
39
|
+
config.node_configurations.should include "query.ec2.us-west-1a : tail( \"/path/to/query.log\", true ) | { value(\"bucket\", \"ask-query\") => agentBEChain(\"ec2-foo:35853\",\"ec2-bar:35853\") };"
|
40
|
+
config.node_configurations.length.should == 1
|
41
|
+
end
|
42
|
+
|
43
|
+
it "can create multiple node configurations" do
|
44
|
+
config = Flumify.new("ec2.us-west-1a") do
|
45
|
+
internal_collector :host => "ec2-foo", :port => 35853
|
46
|
+
external_collector :host => "ec2-bar", :port => 35853
|
47
|
+
|
48
|
+
logical_node "query", {:tail => "/path/to/query.log", :bucket => "ask-query"}
|
49
|
+
logical_node "click", {:tail => "/path/to/click.log", :bucket => "ask-click"}
|
50
|
+
end
|
51
|
+
|
52
|
+
config.node_configurations.should include "query.ec2.us-west-1a : tail( \"/path/to/query.log\", true ) | { value(\"bucket\", \"ask-query\") => agentBEChain(\"ec2-foo:35853\",\"ec2-bar:35853\") };"
|
53
|
+
config.node_configurations.should include "click.ec2.us-west-1a : tail( \"/path/to/click.log\", true ) | { value(\"bucket\", \"ask-click\") => agentBEChain(\"ec2-foo:35853\",\"ec2-bar:35853\") };"
|
54
|
+
config.node_configurations.length.should == 2
|
55
|
+
end
|
56
|
+
|
57
|
+
it "allows multiple log files to be specified" do
|
58
|
+
config = Flumify.new("ec2.us-west-1a") do
|
59
|
+
internal_collector :host => "ec2-foo", :port => 35853
|
60
|
+
external_collector :host => "ec2-bar", :port => 35853
|
61
|
+
|
62
|
+
logical_node "query", {:tail => "/path/to/*.log", :bucket => "ask-query"}
|
63
|
+
end
|
64
|
+
|
65
|
+
config.node_configurations.should include "query.ec2.us-west-1a : tailDir( \"/path/to/\", \".*.log\" ) | { value(\"bucket\", \"ask-query\") => agentBEChain(\"ec2-foo:35853\",\"ec2-bar:35853\") };"
|
66
|
+
config.node_configurations.length.should == 1
|
67
|
+
end
|
68
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: flumify
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Ryan Greenhall
|
14
|
+
- Tom Hall
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2011-05-26 00:00:00 +01:00
|
20
|
+
default_executable:
|
21
|
+
dependencies:
|
22
|
+
- !ruby/object:Gem::Dependency
|
23
|
+
name: net-ssh
|
24
|
+
prerelease: false
|
25
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 3
|
31
|
+
segments:
|
32
|
+
- 2
|
33
|
+
- 1
|
34
|
+
- 4
|
35
|
+
version: 2.1.4
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id001
|
38
|
+
description: ""
|
39
|
+
email:
|
40
|
+
- ryan.greenhall@gmail.com
|
41
|
+
executables: []
|
42
|
+
|
43
|
+
extensions: []
|
44
|
+
|
45
|
+
extra_rdoc_files: []
|
46
|
+
|
47
|
+
files:
|
48
|
+
- .bundle/config
|
49
|
+
- .rvmrc
|
50
|
+
- Gemfile
|
51
|
+
- Gemfile.lock
|
52
|
+
- README
|
53
|
+
- config/config.yaml
|
54
|
+
- example/decommission.rb
|
55
|
+
- example/example.rb
|
56
|
+
- flumify.gemspec
|
57
|
+
- lib/flume_master.rb
|
58
|
+
- lib/flumify.rb
|
59
|
+
- lib/flumify/version.rb
|
60
|
+
- lib/ssh_connection.rb
|
61
|
+
- rakefile
|
62
|
+
- spec/flumify_spec.rb
|
63
|
+
has_rdoc: true
|
64
|
+
homepage: ""
|
65
|
+
licenses: []
|
66
|
+
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 3
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
requirements: []
|
91
|
+
|
92
|
+
rubyforge_project: flumify
|
93
|
+
rubygems_version: 1.3.7
|
94
|
+
signing_key:
|
95
|
+
specification_version: 3
|
96
|
+
summary: Simple flume configuration
|
97
|
+
test_files:
|
98
|
+
- spec/flumify_spec.rb
|