fluent-plugin-hoop 0.1.0
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/.document +5 -0
- data/.gitignore +31 -0
- data/.gitmodules +3 -0
- data/AUTHORS +1 -0
- data/Gemfile +16 -0
- data/LICENSE.txt +13 -0
- data/README.rdoc +79 -0
- data/Rakefile +64 -0
- data/VERSION +1 -0
- data/fluent-plugin-hoop.gemspec +75 -0
- data/lib/fluent/plugin/out_hoop.rb +339 -0
- data/test/helper.rb +53 -0
- data/test/plugin/test_out_hoop.rb +441 -0
- data/test/plugin/test_out_hoop_realserver.rb +145 -0
- data/test/plugin/test_out_hoop_reconnect.rb +185 -0
- metadata +156 -0
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class HoopOutputRealServerTest < Test::Unit::TestCase
|
4
|
+
# setup/teardown and tests of dummy hoop server defined at the end of this class...
|
5
|
+
|
6
|
+
@@start_dummy_server = (not ENV['HOOP_SERVER'])
|
7
|
+
|
8
|
+
def create_driver()
|
9
|
+
server = ENV['HOOP_SERVER'] || 'localhost:14000'
|
10
|
+
path_prefix = ENV['HOOP_PATH_PREFIX'] || '/test/realhoop'
|
11
|
+
path = path_prefix + '/%Y%m%d/test-%H.log'
|
12
|
+
username = ENV['HOOP_USERNAME'] || 'hoopuser'
|
13
|
+
Fluent::Test::TimeSlicedOutputTestDriver.new(Fluent::HoopOutput).configure(<<"EOC")
|
14
|
+
hoop_server #{server}
|
15
|
+
path #{path}
|
16
|
+
username #{username}
|
17
|
+
EOC
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_output
|
21
|
+
d = create_driver
|
22
|
+
|
23
|
+
time = Time.now.to_i
|
24
|
+
d.emit({"data"=>'test_out_hoop_realserver: test_output: 1'}, time)
|
25
|
+
d.emit({"data"=>'test_out_hoop_realserver: test_output: 2'}, time)
|
26
|
+
paths = d.run
|
27
|
+
assert true
|
28
|
+
end
|
29
|
+
|
30
|
+
VALID_COOKIE_STRING = 'alfredo.auth="u=hoopuser&p=hoopuser&t=simple&e=1322203001386&s=SErpv88rOAVEItSOIoCtIV/DSpE="'
|
31
|
+
RES_COOKIE_AUTH_FAILURE = WEBrick::Cookie.parse_set_cookie('alfredo.auth=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/')
|
32
|
+
RES_COOKIE_AUTH_SUCCESS = WEBrick::Cookie.parse_set_cookie(VALID_COOKIE_STRING + '; Version=1; Path=/')
|
33
|
+
RES_BODY_STATUS_ROOT = '{"path":"http:\/\/localhost:14000\/","isDir":true,"len":0,"owner":"hoopuser","group":"supergroup","permission":"-rwxr-xr-x","accessTime":0,"modificationTime":1320055230010,"blockSize":0,"replication":0}'
|
34
|
+
RES_FORMAT_ALREADY_EXISTS = "{\"statusCode\":500,\"reason\":\"Internal Server Error\",\"message\":\"java.io.IOException: failed to create file %s on client 127.0.0.1 either because the filename is invalid or the file exists\",\"exception\":\"org.apache.hadoop.ipc.RemoteException\"}"
|
35
|
+
RES_FORMAT_NOT_FOUND = "{\"statusCode\":404,\"reason\":\"Not Found\",\"message\":\"java.io.FileNotFoundException: failed to append to non-existent file %s on client 127.0.0.1\",\"exception\":\"java.io.FileNotFoundException\"}"
|
36
|
+
RES_FORMAT_NOT_FOUND_GET = "{\"statusCode\":404,\"reason\":\"Not Found\",\"message\":\"File does not exist: %s\",\"exception\":\"java.io.FileNotFoundException\"}"
|
37
|
+
|
38
|
+
CONTENT_TYPE_JSON = 'application/json'
|
39
|
+
|
40
|
+
def setup
|
41
|
+
Fluent::Test.setup
|
42
|
+
|
43
|
+
return unless @@start_dummy_server
|
44
|
+
|
45
|
+
@dummy_server_thread = Thread.new do
|
46
|
+
srv = if ENV['FLUENT_TEST_DEBUG']
|
47
|
+
logger = WEBrick::Log.new('/dev/null', WEBrick::BasicLog::DEBUG)
|
48
|
+
WEBrick::HTTPServer.new({:BindAddress => '127.0.0.1', :Port => 14000, :Logger => logger, :AccessLog => []})
|
49
|
+
else
|
50
|
+
WEBrick::HTTPServer.new({:BindAddress => '127.0.0.1', :Port => 14000})
|
51
|
+
end
|
52
|
+
@fsdata = {}
|
53
|
+
begin
|
54
|
+
srv.mount_proc('/'){|req,res|
|
55
|
+
# status only...
|
56
|
+
if req.query['user.name'] or req.cookies.index{|item| item.name == 'alfredo.auth' and item.value}
|
57
|
+
res.status = 200
|
58
|
+
res.content_type = CONTENT_TYPE_JSON
|
59
|
+
res.cookies << RES_COOKIE_AUTH_SUCCESS
|
60
|
+
res.body = RES_BODY_STATUS_ROOT
|
61
|
+
else
|
62
|
+
res.cookies << RES_COOKIE_AUTH_FAILURE
|
63
|
+
res.status = 401
|
64
|
+
end
|
65
|
+
}
|
66
|
+
srv.mount_proc('/logs/from/fluentd') {|req, res|
|
67
|
+
if req.request_method == 'POST' or req.request_method == 'PUT' or req.request_method == 'DELETE'
|
68
|
+
# WEBrick's default handler ignores query parameter of URI without method GET
|
69
|
+
req.query.update(Hash[*(req.request_line.split(' ')[1].split('?')[1].split('&').map{|kv|kv.split('=')}.flatten)])
|
70
|
+
end
|
71
|
+
case
|
72
|
+
when (not req.query['user.name'] and req.cookies.index{|item| item.name == 'alfredo.auth' and item.value} < 0)
|
73
|
+
res.cookies << RES_COOKIE_AUTH_FAILURE
|
74
|
+
res.status = 401
|
75
|
+
when (req.query['op'] == 'create' and @fsdata[req.path] and req.query['overwrite'] and req.query['overwrite'] == 'false')
|
76
|
+
res.status = 500
|
77
|
+
res.content_type = CONTENT_TYPE_JSON
|
78
|
+
res.cookies << RES_COOKIE_AUTH_SUCCESS
|
79
|
+
res.body = sprintf RES_FORMAT_ALREADY_EXISTS, req.path
|
80
|
+
when req.query['op'] == 'create'
|
81
|
+
@fsdata[req.path] = req.body
|
82
|
+
res.status = 201
|
83
|
+
res['Location'] = 'http://localhost:14000' + req.path
|
84
|
+
res.content_type = CONTENT_TYPE_JSON
|
85
|
+
res.cookies << RES_COOKIE_AUTH_SUCCESS
|
86
|
+
when (req.query['op'] == 'append' and @fsdata[req.path])
|
87
|
+
@fsdata[req.path] += req.body
|
88
|
+
res.status = 200
|
89
|
+
res['Location'] = 'http://localhost:14000' + req.path
|
90
|
+
res.content_type = CONTENT_TYPE_JSON
|
91
|
+
res.cookies << RES_COOKIE_AUTH_SUCCESS
|
92
|
+
when req.query['op'] == 'append'
|
93
|
+
res.status = 404
|
94
|
+
res.content_type = CONTENT_TYPE_JSON
|
95
|
+
res.cookies << RES_COOKIE_AUTH_SUCCESS
|
96
|
+
res.body = sprintf RES_FORMAT_NOT_FOUND, req.path
|
97
|
+
when (req.request_method == 'GET' and @fsdata[req.path]) # maybe GET
|
98
|
+
res.status = 200
|
99
|
+
res.content_type = 'application/octet-stream'
|
100
|
+
res.cookies << RES_COOKIE_AUTH_SUCCESS
|
101
|
+
res.body = @fsdata[req.path]
|
102
|
+
else
|
103
|
+
res.status = 404
|
104
|
+
res.content_type = CONTENT_TYPE_JSON
|
105
|
+
res.cookies << RES_COOKIE_AUTH_SUCCESS
|
106
|
+
res.body = sprintf RES_FORMAT_NOT_FOUND_GET, req.path
|
107
|
+
end
|
108
|
+
}
|
109
|
+
srv.start
|
110
|
+
ensure
|
111
|
+
srv.shutdown
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# to wait completion of dummy server.start()
|
116
|
+
require 'thread'
|
117
|
+
cv = ConditionVariable.new
|
118
|
+
watcher = Thread.new {
|
119
|
+
connected = false
|
120
|
+
while not connected
|
121
|
+
begin
|
122
|
+
get_content('localhost', 14000, '/', {'Cookie' => VALID_COOKIE_STRING})
|
123
|
+
connected = true
|
124
|
+
rescue Errno::ECONNREFUSED
|
125
|
+
sleep 0.1
|
126
|
+
rescue StandardError => e
|
127
|
+
p e
|
128
|
+
sleep 0.1
|
129
|
+
end
|
130
|
+
end
|
131
|
+
cv.signal
|
132
|
+
}
|
133
|
+
mutex = Mutex.new
|
134
|
+
mutex.synchronize {
|
135
|
+
cv.wait(mutex)
|
136
|
+
}
|
137
|
+
end
|
138
|
+
|
139
|
+
def teardown
|
140
|
+
return unless @@start_dummy_server
|
141
|
+
|
142
|
+
@dummy_server_thread.kill
|
143
|
+
@dummy_server_thread.join
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class HoopOutputReconnectTest < Test::Unit::TestCase
|
4
|
+
# setup/teardown and tests of dummy hoop server defined at the end of this class...
|
5
|
+
|
6
|
+
CONFIG = %[
|
7
|
+
hoop_server localhost:14000
|
8
|
+
path /logs/from/fluentd/foo-%Y%m%d
|
9
|
+
username hoopuser
|
10
|
+
]
|
11
|
+
|
12
|
+
def create_driver(conf = CONFIG)
|
13
|
+
Fluent::Test::TimeSlicedOutputTestDriver.new(Fluent::HoopOutput).configure(conf)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_write
|
17
|
+
d = create_driver CONFIG
|
18
|
+
|
19
|
+
assert_equal '404', get_code('localhost', 14000, '/logs/from/fluentd/foo-20111124', {'Cookie' => VALID_COOKIE_STRING})
|
20
|
+
|
21
|
+
time = Time.parse("2011-10-01 00:14:15 UTC").to_i
|
22
|
+
d.emit({"a"=>1}, time)
|
23
|
+
d.emit({"a"=>2}, time)
|
24
|
+
paths = d.run
|
25
|
+
assert_equal ['/logs/from/fluentd/foo-20111001'], paths
|
26
|
+
assert_equal %[2011-10-01T00:14:15Z\ttest\t{"a":1}\n2011-10-01T00:14:15Z\ttest\t{"a":2}\n], get_content('localhost', 14000, paths.first, {'Cookie' => VALID_COOKIE_STRING})
|
27
|
+
|
28
|
+
# d = create_driver CONFIG
|
29
|
+
restart_dummy_server
|
30
|
+
|
31
|
+
time = Time.parse("2011-10-02 00:14:15 UTC").to_i
|
32
|
+
d.emit({"a"=>3}, time)
|
33
|
+
d.emit({"a"=>4}, time)
|
34
|
+
paths = d.run
|
35
|
+
|
36
|
+
assert_equal ['/logs/from/fluentd/foo-20111001', '/logs/from/fluentd/foo-20111002'], paths.sort
|
37
|
+
assert_equal %[2011-10-02T00:14:15Z\ttest\t{"a":3}\n2011-10-02T00:14:15Z\ttest\t{"a":4}\n], get_content('localhost', 14000, paths.sort.last, {'Cookie' => VALID_COOKIE_STRING})
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
VALID_COOKIE_STRING = 'alfredo.auth="u=hoopuser&p=hoopuser&t=simple&e=1322203001386&s=SErpv88rOAVEItSOIoCtIV/DSpE="'
|
42
|
+
RES_COOKIE_AUTH_FAILURE = WEBrick::Cookie.parse_set_cookie('alfredo.auth=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/')
|
43
|
+
RES_COOKIE_AUTH_SUCCESS = WEBrick::Cookie.parse_set_cookie(VALID_COOKIE_STRING + '; Version=1; Path=/')
|
44
|
+
RES_BODY_STATUS_ROOT = '{"path":"http:\/\/localhost:14000\/","isDir":true,"len":0,"owner":"hoopuser","group":"supergroup","permission":"-rwxr-xr-x","accessTime":0,"modificationTime":1320055230010,"blockSize":0,"replication":0}'
|
45
|
+
RES_FORMAT_ALREADY_EXISTS = "{\"statusCode\":500,\"reason\":\"Internal Server Error\",\"message\":\"java.io.IOException: failed to create file %s on client 127.0.0.1 either because the filename is invalid or the file exists\",\"exception\":\"org.apache.hadoop.ipc.RemoteException\"}"
|
46
|
+
RES_FORMAT_NOT_FOUND = "{\"statusCode\":404,\"reason\":\"Not Found\",\"message\":\"java.io.FileNotFoundException: failed to append to non-existent file %s on client 127.0.0.1\",\"exception\":\"java.io.FileNotFoundException\"}"
|
47
|
+
RES_FORMAT_NOT_FOUND_GET = "{\"statusCode\":404,\"reason\":\"Not Found\",\"message\":\"File does not exist: %s\",\"exception\":\"java.io.FileNotFoundException\"}"
|
48
|
+
|
49
|
+
CONTENT_TYPE_JSON = 'application/json'
|
50
|
+
|
51
|
+
def start_server
|
52
|
+
@dummy_server_thread = Thread.new do
|
53
|
+
srv = if ENV['FLUENT_TEST_DEBUG']
|
54
|
+
logger = WEBrick::Log.new('/dev/null', WEBrick::BasicLog::DEBUG)
|
55
|
+
WEBrick::HTTPServer.new({:BindAddress => '127.0.0.1', :Port => 14000, :Logger => logger, :AccessLog => []})
|
56
|
+
else
|
57
|
+
WEBrick::HTTPServer.new({:BindAddress => '127.0.0.1', :Port => 14000})
|
58
|
+
end
|
59
|
+
@fsdata = {}
|
60
|
+
begin
|
61
|
+
srv.mount_proc('/'){|req,res|
|
62
|
+
# status only...
|
63
|
+
if req.query['user.name'] or req.cookies.index{|item| item.name == 'alfredo.auth' and item.value}
|
64
|
+
res.status = 200
|
65
|
+
res.content_type = CONTENT_TYPE_JSON
|
66
|
+
res.cookies << RES_COOKIE_AUTH_SUCCESS
|
67
|
+
res.body = RES_BODY_STATUS_ROOT
|
68
|
+
else
|
69
|
+
res.cookies << RES_COOKIE_AUTH_FAILURE
|
70
|
+
res.status = 401
|
71
|
+
end
|
72
|
+
}
|
73
|
+
srv.mount_proc('/logs/from/fluentd') {|req, res|
|
74
|
+
if req.request_method == 'POST' or req.request_method == 'PUT' or req.request_method == 'DELETE'
|
75
|
+
# WEBrick's default handler ignores query parameter of URI without method GET
|
76
|
+
req.query.update(Hash[*(req.request_line.split(' ')[1].split('?')[1].split('&').map{|kv|kv.split('=')}.flatten)])
|
77
|
+
end
|
78
|
+
case
|
79
|
+
when (not req.query['user.name'] and req.cookies.index{|item| item.name == 'alfredo.auth' and item.value} < 0)
|
80
|
+
res.cookies << RES_COOKIE_AUTH_FAILURE
|
81
|
+
res.status = 401
|
82
|
+
when (req.query['op'] == 'create' and @fsdata[req.path] and req.query['overwrite'] and req.query['overwrite'] == 'false')
|
83
|
+
res.status = 500
|
84
|
+
res.content_type = CONTENT_TYPE_JSON
|
85
|
+
res.body = sprintf RES_FORMAT_ALREADY_EXISTS, req.path
|
86
|
+
when req.query['op'] == 'create'
|
87
|
+
@fsdata[req.path] = req.body
|
88
|
+
res.status = 201
|
89
|
+
res['Location'] = 'http://localhost:14000' + req.path
|
90
|
+
res.content_type = CONTENT_TYPE_JSON
|
91
|
+
when (req.query['op'] == 'append' and @fsdata[req.path])
|
92
|
+
@fsdata[req.path] += req.body
|
93
|
+
res.status = 200
|
94
|
+
res['Location'] = 'http://localhost:14000' + req.path
|
95
|
+
res.content_type = CONTENT_TYPE_JSON
|
96
|
+
when req.query['op'] == 'append'
|
97
|
+
res.status = 404
|
98
|
+
res.content_type = CONTENT_TYPE_JSON
|
99
|
+
res.body = sprintf RES_FORMAT_NOT_FOUND, req.path
|
100
|
+
when (req.request_method == 'GET' and @fsdata[req.path]) # maybe GET
|
101
|
+
res.status = 200
|
102
|
+
res.content_type = 'application/octet-stream'
|
103
|
+
res.body = @fsdata[req.path]
|
104
|
+
else
|
105
|
+
res.status = 404
|
106
|
+
res.content_type = CONTENT_TYPE_JSON
|
107
|
+
res.body = sprintf RES_FORMAT_NOT_FOUND_GET, req.path
|
108
|
+
end
|
109
|
+
}
|
110
|
+
srv.start
|
111
|
+
ensure
|
112
|
+
srv.shutdown
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# to wait completion of dummy server.start()
|
117
|
+
require 'thread'
|
118
|
+
cv = ConditionVariable.new
|
119
|
+
watcher = Thread.new {
|
120
|
+
connected = false
|
121
|
+
while not connected
|
122
|
+
begin
|
123
|
+
get_content('localhost', 14000, '/', {'Cookie' => VALID_COOKIE_STRING})
|
124
|
+
connected = true
|
125
|
+
rescue Errno::ECONNREFUSED
|
126
|
+
sleep 0.1
|
127
|
+
rescue StandardError => e
|
128
|
+
p e
|
129
|
+
sleep 0.1
|
130
|
+
end
|
131
|
+
end
|
132
|
+
cv.signal
|
133
|
+
}
|
134
|
+
mutex = Mutex.new
|
135
|
+
mutex.synchronize {
|
136
|
+
cv.wait(mutex)
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
def setup
|
141
|
+
Fluent::Test.setup
|
142
|
+
start_server
|
143
|
+
end
|
144
|
+
|
145
|
+
def restart_dummy_server
|
146
|
+
@dummy_server_thread.kill
|
147
|
+
@dummy_server_thread.join
|
148
|
+
start_server
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_dummy_server
|
152
|
+
d = create_driver
|
153
|
+
authheader = {'Cookie' => VALID_COOKIE_STRING}
|
154
|
+
client = Net::HTTP.start(d.instance.hoop_server.split(':')[0], d.instance.hoop_server.split(':')[1])
|
155
|
+
assert_equal '401', client.request_get('/').code
|
156
|
+
assert_equal '200', client.request_get('/?user.name=hoopuser').code
|
157
|
+
assert_equal '200', client.request_get('/', authheader).code
|
158
|
+
|
159
|
+
# /logs/from/fluentd
|
160
|
+
path1 = '/logs/from/fluentd/hoge001/moge-access-log'
|
161
|
+
path1_line1 = "1111111111111111111111111111111\n"
|
162
|
+
path1_line2 = "2222222222222222222222222222222222222222222222222\n"
|
163
|
+
assert_equal '404', client.request_put(path1 + '?op=append', path1_line1, authheader).code
|
164
|
+
assert_equal '201', client.request_post(path1 + '?op=create&overwrite=false', path1_line1, authheader).code
|
165
|
+
assert_equal path1_line1, client.request_get(path1, authheader).body
|
166
|
+
assert_equal '200', client.request_put(path1 + '?op=append', path1_line2, authheader).code
|
167
|
+
assert_equal path1_line1 + path1_line2, client.request_get(path1, authheader).body
|
168
|
+
|
169
|
+
path2 = '/logs/from/fluentd/hoge002/moge-access-log'
|
170
|
+
path2_line1 = "XXXXX___1111111111111111111111111111111\n"
|
171
|
+
path2_line2 = "YYYYY___2222222222222222222222222222222222222222222222222\n"
|
172
|
+
assert_equal '404', client.request_put(path2 + '?op=append', path2_line1, authheader).code
|
173
|
+
assert_equal '201', client.request_post(path2 + '?op=create&overwrite=false', path2_line1, authheader).code
|
174
|
+
assert_equal '500', client.request_post(path2 + '?op=create&overwrite=false', path2_line1, authheader).code
|
175
|
+
assert_equal path2_line1, client.request_get(path2, authheader).body
|
176
|
+
assert_equal '200', client.request_put(path2 + '?op=append', path2_line2, authheader).code
|
177
|
+
assert_equal path2_line1 + path2_line2, client.request_get(path2, authheader).body
|
178
|
+
assert_equal path2_line1 + path2_line2, get_content('localhost', 14000, path2, authheader)
|
179
|
+
end
|
180
|
+
|
181
|
+
def teardown
|
182
|
+
@dummy_server_thread.kill
|
183
|
+
@dummy_server_thread.join
|
184
|
+
end
|
185
|
+
end
|
metadata
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-hoop
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- TAGOMORI Satoshi
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-12-26 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rdoc
|
16
|
+
requirement: &2157501280 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2157501280
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: shoulda
|
27
|
+
requirement: &2157500800 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2157500800
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: bundler
|
38
|
+
requirement: &2157500320 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.0.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2157500320
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: jeweler
|
49
|
+
requirement: &2157499840 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.6.4
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2157499840
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rcov
|
60
|
+
requirement: &2157499360 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *2157499360
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: fluentd
|
71
|
+
requirement: &2157498880 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.10.8
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *2157498880
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: rake
|
82
|
+
requirement: &2157498400 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 0.9.2
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *2157498400
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: simplecov
|
93
|
+
requirement: &2157497920 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 0.5.4
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *2157497920
|
102
|
+
description: Hoop (HDFS http-fs) plugin for Fluent event collector
|
103
|
+
email: tagomoris@gmail.com
|
104
|
+
executables: []
|
105
|
+
extensions: []
|
106
|
+
extra_rdoc_files:
|
107
|
+
- LICENSE.txt
|
108
|
+
- README.rdoc
|
109
|
+
files:
|
110
|
+
- .document
|
111
|
+
- .gitignore
|
112
|
+
- .gitmodules
|
113
|
+
- AUTHORS
|
114
|
+
- Gemfile
|
115
|
+
- LICENSE.txt
|
116
|
+
- README.rdoc
|
117
|
+
- Rakefile
|
118
|
+
- VERSION
|
119
|
+
- fluent-plugin-hoop.gemspec
|
120
|
+
- lib/fluent/plugin/out_hoop.rb
|
121
|
+
- test/helper.rb
|
122
|
+
- test/plugin/test_out_hoop.rb
|
123
|
+
- test/plugin/test_out_hoop_realserver.rb
|
124
|
+
- test/plugin/test_out_hoop_reconnect.rb
|
125
|
+
homepage: http://github.com/tagomoris/fluent-plugin-hoop
|
126
|
+
licenses: []
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
133
|
+
requirements:
|
134
|
+
- - ! '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
segments:
|
138
|
+
- 0
|
139
|
+
hash: -3094368316846613574
|
140
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ! '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
requirements: []
|
147
|
+
rubyforge_project:
|
148
|
+
rubygems_version: 1.8.6
|
149
|
+
signing_key:
|
150
|
+
specification_version: 3
|
151
|
+
summary: Hoop (HDFS http-fs) plugin for Fluent event collector
|
152
|
+
test_files:
|
153
|
+
- test/helper.rb
|
154
|
+
- test/plugin/test_out_hoop.rb
|
155
|
+
- test/plugin/test_out_hoop_realserver.rb
|
156
|
+
- test/plugin/test_out_hoop_reconnect.rb
|