fluent-plugin-out-falcon 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 93262b579cc60c929f865d81171a46b4d610738d
4
+ data.tar.gz: 6d0e4885faaebce8db8a1ca12488f9f0fd426a3c
5
+ SHA512:
6
+ metadata.gz: 00d5bc6bb7e9ed15148858bc792a3aed8290cea197e7f66c8d22cfe2579667583df53e79edcbd8a3b2c7ff3b7e2e026b184ddc48f063703c8d8e51c2b1764aef
7
+ data.tar.gz: 6d8d6d3b27bc2cdbca11cd8238d127a90ecc5b14337bad1360d479e0e5bb5abb8d7bd62549b3b3a0610ce1fed8a8ec217193de2cd39bbfdc2bb811c52f664d27
@@ -0,0 +1,8 @@
1
+ *~
2
+ \#*
3
+ .\#*
4
+ *.gem
5
+ .bundle
6
+ .ruby-version
7
+ Gemfile.lock
8
+ vendor
@@ -0,0 +1,21 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.0.0
4
+ - 2.1
5
+ - 2.2
6
+ - ruby-head
7
+ - rbx-2
8
+
9
+ os:
10
+ - linux
11
+ - osx
12
+
13
+ gemfile:
14
+ - Gemfile
15
+
16
+ script: bundle exec rake test
17
+
18
+ matrix:
19
+ allow_failures:
20
+ - rvm: ruby-head
21
+ - rvm: rbx-2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-out-falcon.gemspec
4
+ gemspec
@@ -0,0 +1,11 @@
1
+ Licensed under the Apache License, Version 2.0 (the "License");
2
+ you may not use this file except in compliance with the License.
3
+ You may obtain a copy of the License at
4
+
5
+ http://www.apache.org/licenses/LICENSE-2.0
6
+
7
+ Unless required by applicable law or agreed to in writing, software
8
+ distributed under the License is distributed on an "AS IS" BASIS,
9
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ See the License for the specific language governing permissions and
11
+ limitations under the License.
@@ -0,0 +1,24 @@
1
+ # fluent-plugin-out-falcon, a plugin for [Fluentd](http://fluentd.org)
2
+
3
+ A [fluentd][1] output plugin for sending logs to [falcon][2]'s push api.
4
+
5
+ ## Configuration options
6
+
7
+ <match *>
8
+ type falcon
9
+ endpoint_url http://localhost.local/api/
10
+ rate_limit_msec 100 # default: 0 = no rate limiting
11
+ raise_on_error false # default: true
12
+ authentication basic # default: none
13
+ username alice # default: ''
14
+ password bobpop # default: '', secret: true
15
+ </match>
16
+
17
+
18
+ ----
19
+
20
+ Heavily based on [fluent-plugin-out-http][3]
21
+
22
+ [1]: http://fluentd.org/
23
+ [2]: http://open-falcon.org/
24
+ [3]: https://github.com/https://github.com/ento/fluent-plugin-out-http
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'lib' << 'test'
7
+ test.pattern = 'test/**/test_*.rb'
8
+ test.verbose = true
9
+ end
10
+
11
+ task :default => :test
@@ -0,0 +1,147 @@
1
+ class Fluent::FalconOutput < Fluent::Output
2
+ Fluent::Plugin.register_output('falcon', self)
3
+
4
+ def initialize
5
+ super
6
+ require 'net/http'
7
+ require 'uri'
8
+ require 'yajl'
9
+ end
10
+
11
+ # Map which record field to falcon's value filed
12
+ #config_param :value_mapping, :string
13
+
14
+ # Endpoint URL ex. localhost.local/api/
15
+ config_param :endpoint_url, :string
16
+
17
+ # HTTP method
18
+ config_param :http_method, :string, :default => :post
19
+
20
+ # form | json
21
+ config_param :serializer, :string, :default => :json
22
+
23
+ # Simple rate limiting: ignore any records within `rate_limit_msec`
24
+ # since the last one.
25
+ config_param :rate_limit_msec, :integer, :default => 0
26
+
27
+ # Raise errors that were rescued during HTTP requests?
28
+ config_param :raise_on_error, :bool, :default => true
29
+
30
+ # nil | 'none' | 'basic'
31
+ config_param :authentication, :string, :default => nil
32
+ config_param :username, :string, :default => ''
33
+ config_param :password, :string, :default => '', :secret => true
34
+
35
+ def configure(conf)
36
+ super
37
+
38
+ serializers = [:json, :form]
39
+ @serializer = if serializers.include? @serializer.intern
40
+ @serializer.intern
41
+ else
42
+ :form
43
+ end
44
+
45
+ http_methods = [:get, :put, :post, :delete]
46
+ @http_method = if http_methods.include? @http_method.intern
47
+ @http_method.intern
48
+ else
49
+ :post
50
+ end
51
+
52
+ @auth = case @authentication
53
+ when 'basic' then :basic
54
+ else
55
+ :none
56
+ end
57
+ end
58
+
59
+ def start
60
+ super
61
+ end
62
+
63
+ def shutdown
64
+ super
65
+ end
66
+
67
+ def format_url(tag, time, record)
68
+ @endpoint_url
69
+ end
70
+
71
+ def set_body(req, tag, time, record)
72
+ if @serializer == :json
73
+ set_json_body(req, record)
74
+ else
75
+ req.set_form_data(record)
76
+ end
77
+ req
78
+ end
79
+
80
+ def set_header(req, tag, time, record)
81
+ req
82
+ end
83
+
84
+ def set_json_body(req, data)
85
+ # TODO remove record_modifier
86
+ #req.body = Yajl.dump([data].map do |record|
87
+ # temp = record[@value_mapping]
88
+ # data.clear
89
+ # data['value'] = temp
90
+ # data['time'] = Time.now.to_i
91
+ #end)
92
+ req.body = Yajl.dump([data])
93
+ req['Content-Type'] = 'application/json'
94
+ end
95
+
96
+ def create_request(tag, time, record)
97
+ url = format_url(tag, time, record)
98
+ uri = URI.parse(url)
99
+ req = Net::HTTP.const_get(@http_method.to_s.capitalize).new(uri.path)
100
+ set_body(req, tag, time, record)
101
+ set_header(req, tag, time, record)
102
+ return req, uri
103
+ end
104
+
105
+ def send_request(req, uri)
106
+ is_rate_limited = (@rate_limit_msec != 0 and not @last_request_time.nil?)
107
+ if is_rate_limited and ((Time.now.to_f - @last_request_time) * 1000.0 < @rate_limit_msec)
108
+ $log.info('Dropped request due to rate limiting')
109
+ return
110
+ end
111
+
112
+ res = nil
113
+
114
+ begin
115
+ if @auth and @auth == :basic
116
+ req.basic_auth(@username, @password)
117
+ end
118
+ @last_request_time = Time.now.to_f
119
+ res = Net::HTTP.new(uri.host, uri.port).start {|http| http.request(req) }
120
+ rescue => e # rescue all StandardErrors
121
+ # server didn't respond
122
+ $log.warn "Net::HTTP.#{req.method.capitalize} raises exception: #{e.class}, '#{e.message}'"
123
+ raise e if @raise_on_error
124
+ else
125
+ unless res and res.is_a?(Net::HTTPSuccess)
126
+ res_summary = if res
127
+ "#{res.code} #{res.message} #{res.body}"
128
+ else
129
+ "res=nil"
130
+ end
131
+ $log.warn "failed to #{req.method} #{uri} (#{res_summary})"
132
+ end #end unless
133
+ end # end begin
134
+ end # end send_request
135
+
136
+ def handle_record(tag, time, record)
137
+ req, uri = create_request(tag, time, record)
138
+ send_request(req, uri)
139
+ end
140
+
141
+ def emit(tag, es, chain)
142
+ es.each do |time, record|
143
+ handle_record(tag, time, record)
144
+ end
145
+ chain.next
146
+ end
147
+ end
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+
4
+ begin
5
+ Bundler.setup(:default, :development)
6
+ rescue Bundler::BundlerError => e
7
+ $stderr.puts e.message
8
+ $stderr.puts "Run `bundle install` to install missing gems"
9
+ exit e.status_code
10
+ end
11
+
12
+ require 'test/unit'
13
+
14
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
15
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
16
+
17
+ require 'fluent/test'
18
+
19
+ unless ENV.has_key?('VERBOSE')
20
+ nulllogger = Object.new
21
+ nulllogger.instance_eval {|obj|
22
+ def method_missing(method, *args)
23
+ # pass
24
+ end
25
+ }
26
+ $log = nulllogger
27
+ end
28
+
29
+ class Test::Unit::TestCase
30
+ end
31
+
32
+ require 'webrick'
33
+
34
+ # to handle POST/PUT/DELETE ...
35
+ module WEBrick::HTTPServlet
36
+ class ProcHandler < AbstractServlet
37
+ alias do_POST do_GET
38
+ alias do_PUT do_GET
39
+ alias do_DELETE do_GET
40
+ end
41
+ end
42
+
43
+ def get_code(server, port, path, headers={})
44
+ require 'net/http'
45
+ Net::HTTP.start(server, port){|http|
46
+ http.get(path, headers).code
47
+ }
48
+ end
49
+ def get_content(server, port, path, headers={})
50
+ require 'net/http'
51
+ Net::HTTP.start(server, port){|http|
52
+ http.get(path, headers).body
53
+ }
54
+ end
@@ -0,0 +1,320 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'uri'
3
+ require 'yajl'
4
+ require 'fluent/test/falcon_output_test'
5
+ require 'fluent/plugin/out_falcon'
6
+
7
+
8
+ TEST_LISTEN_PORT = 5126
9
+
10
+
11
+ class FalconOutputTestBase < Test::Unit::TestCase
12
+ # setup / teardown for servers
13
+ def setup
14
+ Fluent::Test.setup
15
+ @posts = []
16
+ @puts = []
17
+ @prohibited = 0
18
+ @requests = 0
19
+ @auth = false
20
+ @dummy_server_thread = Thread.new do
21
+ srv = if ENV['VERBOSE']
22
+ WEBrick::HTTPServer.new({:BindAddress => '127.0.0.1', :Port => TEST_LISTEN_PORT})
23
+ else
24
+ logger = WEBrick::Log.new('/dev/null', WEBrick::BasicLog::DEBUG)
25
+ WEBrick::HTTPServer.new({:BindAddress => '127.0.0.1', :Port => TEST_LISTEN_PORT, :Logger => logger, :AccessLog => []})
26
+ end
27
+ begin
28
+ allowed_methods = %w(POST PUT)
29
+ srv.mount_proc('/api/') { |req,res|
30
+ @requests += 1
31
+ unless allowed_methods.include? req.request_method
32
+ res.status = 405
33
+ res.body = 'request method mismatch'
34
+ next
35
+ end
36
+ if @auth and req.header['authorization'][0] == 'Basic YWxpY2U6c2VjcmV0IQ==' # pattern of user='alice' passwd='secret!'
37
+ # ok, authorized
38
+ elsif @auth
39
+ res.status = 403
40
+ @prohibited += 1
41
+ next
42
+ else
43
+ # ok, authorization not required
44
+ end
45
+
46
+ record = {:auth => nil}
47
+ if req.content_type == 'application/json'
48
+ record[:json] = Yajl.load(req.body)
49
+ else
50
+ record[:form] = Hash[*(req.body.split('&').map{|kv|kv.split('=')}.flatten)]
51
+ end
52
+
53
+ instance_variable_get("@#{req.request_method.downcase}s").push(record)
54
+
55
+ res.status = 200
56
+ }
57
+ srv.mount_proc('/') { |req,res|
58
+ res.status = 200
59
+ res.body = 'running'
60
+ }
61
+ srv.start
62
+ ensure
63
+ srv.shutdown
64
+ end
65
+ end
66
+
67
+ # to wait completion of dummy server.start()
68
+ require 'thread'
69
+ cv = ConditionVariable.new
70
+ watcher = Thread.new {
71
+ connected = false
72
+ while not connected
73
+ begin
74
+ get_content('localhost', TEST_LISTEN_PORT, '/')
75
+ connected = true
76
+ rescue Errno::ECONNREFUSED
77
+ sleep 0.1
78
+ rescue StandardError => e
79
+ p e
80
+ sleep 0.1
81
+ end
82
+ end
83
+ cv.signal
84
+ }
85
+ mutex = Mutex.new
86
+ mutex.synchronize {
87
+ cv.wait(mutex)
88
+ }
89
+ end
90
+
91
+ def test_dummy_server
92
+ host = '127.0.0.1'
93
+ port = TEST_LISTEN_PORT
94
+ client = Net::HTTP.start(host, port)
95
+
96
+ assert_equal '200', client.request_get('/').code
97
+ assert_equal '200', client.request_post('/api/service/metrics/hoge', 'number=1&mode=gauge').code
98
+
99
+ assert_equal 1, @posts.size
100
+
101
+ assert_equal '1', @posts[0][:form]['number']
102
+ assert_equal 'gauge', @posts[0][:form]['mode']
103
+ assert_nil @posts[0][:auth]
104
+
105
+ @auth = true
106
+
107
+ assert_equal '403', client.request_post('/api/service/metrics/pos', 'number=30&mode=gauge').code
108
+
109
+ req_with_auth = lambda do |number, mode, user, pass|
110
+ url = URI.parse("http://#{host}:#{port}/api/service/metrics/pos")
111
+ req = Net::HTTP::Post.new(url.path)
112
+ req.basic_auth user, pass
113
+ req.set_form_data({'number'=>number, 'mode'=>mode})
114
+ req
115
+ end
116
+
117
+ assert_equal '403', client.request(req_with_auth.call(500, 'count', 'alice', 'wrong password!')).code
118
+
119
+ assert_equal '403', client.request(req_with_auth.call(500, 'count', 'alice', 'wrong password!')).code
120
+
121
+ assert_equal 1, @posts.size
122
+
123
+ assert_equal '200', client.request(req_with_auth.call(500, 'count', 'alice', 'secret!')).code
124
+
125
+ assert_equal 2, @posts.size
126
+
127
+ end
128
+
129
+ def teardown
130
+ @dummy_server_thread.kill
131
+ @dummy_server_thread.join
132
+ end
133
+ end
134
+
135
+ class FalconOutputTest < FalconOutputTestBase
136
+ CONFIG_FORM = %[
137
+ endpoint_url http://127.0.0.1:#{TEST_LISTEN_PORT}/api/
138
+ serializer form
139
+ ]
140
+
141
+ CONFIG_JSON = %[
142
+ endpoint_url http://127.0.0.1:#{TEST_LISTEN_PORT}/api/
143
+ serializer json
144
+ ]
145
+
146
+ CONFIG_PUT = %[
147
+ endpoint_url http://127.0.0.1:#{TEST_LISTEN_PORT}/api/
148
+ serializer form
149
+ http_method put
150
+ ]
151
+
152
+ CONFIG_HTTP_ERROR = %[
153
+ endpoint_url https://127.0.0.1:#{TEST_LISTEN_PORT + 1}/api/
154
+ serializer form
155
+ ]
156
+
157
+ CONFIG_HTTP_ERROR_SUPPRESSED = %[
158
+ endpoint_url https://127.0.0.1:#{TEST_LISTEN_PORT + 1}/api/
159
+ serializer form
160
+ raise_on_error false
161
+ ]
162
+
163
+ RATE_LIMIT_MSEC = 1200
164
+
165
+ CONFIG_RATE_LIMIT = %[
166
+ endpoint_url http://127.0.0.1:#{TEST_LISTEN_PORT}/api/
167
+ serializer form
168
+ rate_limit_msec #{RATE_LIMIT_MSEC}
169
+ ]
170
+
171
+ def create_driver(conf=CONFIG_FORM, tag='test.metrics')
172
+ Fluent::Test::OutputTestDriver.new(Fluent::FalconOutput, tag).configure(conf)
173
+ end
174
+
175
+ def test_configure
176
+ d = create_driver
177
+ assert_equal "http://127.0.0.1:#{TEST_LISTEN_PORT}/api/", d.instance.endpoint_url
178
+ assert_equal :form, d.instance.serializer
179
+
180
+ d = create_driver CONFIG_JSON
181
+ assert_equal "http://127.0.0.1:#{TEST_LISTEN_PORT}/api/", d.instance.endpoint_url
182
+ assert_equal :json, d.instance.serializer
183
+ end
184
+
185
+ def test_emit_form
186
+ d = create_driver
187
+ d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1, 'binary' => "\xe3\x81\x82".force_encoding("ascii-8bit") })
188
+ d.run
189
+
190
+ assert_equal 1, @posts.size
191
+ record = @posts[0]
192
+
193
+ assert_equal '50', record[:form]['field1']
194
+ assert_equal '20', record[:form]['field2']
195
+ assert_equal '10', record[:form]['field3']
196
+ assert_equal '1', record[:form]['otherfield']
197
+ assert_equal URI.encode_www_form_component("あ").upcase, record[:form]['binary'].upcase
198
+ assert_nil record[:auth]
199
+
200
+ d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
201
+ d.run
202
+
203
+ assert_equal 2, @posts.size
204
+ end
205
+
206
+ def test_emit_form_put
207
+ d = create_driver CONFIG_PUT
208
+ d.emit({ 'field1' => 50 })
209
+ d.run
210
+
211
+ assert_equal 0, @posts.size
212
+ assert_equal 1, @puts.size
213
+ record = @puts[0]
214
+
215
+ assert_equal '50', record[:form]['field1']
216
+ assert_nil record[:auth]
217
+
218
+ d.emit({ 'field1' => 50 })
219
+ d.run
220
+
221
+ assert_equal 0, @posts.size
222
+ assert_equal 2, @puts.size
223
+ end
224
+
225
+ def test_emit_json
226
+ binary_string = "\xe3\x81\x82".force_encoding("ascii-8bit")
227
+ d = create_driver CONFIG_JSON
228
+ d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1, 'binary' => binary_string })
229
+ d.run
230
+
231
+ assert_equal 1, @posts.size
232
+ record = @posts[0]
233
+
234
+ assert_equal 50, record[:json][0]['field1']
235
+ assert_equal 20, record[:json][0]['field2']
236
+ assert_equal 10, record[:json][0]['field3']
237
+ assert_equal 1, record[:json][0]['otherfield']
238
+ assert_equal binary_string, record[:json][0]['binary'].force_encoding("ascii-8bit")
239
+ assert_nil record[:auth]
240
+ end
241
+
242
+ def test_http_error_is_raised
243
+ d = create_driver CONFIG_HTTP_ERROR
244
+ assert_raise Errno::ECONNREFUSED do
245
+ d.emit({ 'field1' => 50 })
246
+ end
247
+ end
248
+
249
+ def test_http_error_is_suppressed_with_raise_on_error_false
250
+ d = create_driver CONFIG_HTTP_ERROR_SUPPRESSED
251
+ d.emit({ 'field1' => 50 })
252
+ d.run
253
+ # drive asserts the next output chain is called;
254
+ # so no exception means our plugin handled the error
255
+
256
+ assert_equal 0, @requests
257
+ end
258
+
259
+ def test_rate_limiting
260
+ d = create_driver CONFIG_RATE_LIMIT
261
+ record = { :k => 1 }
262
+
263
+ last_emit = _current_msec
264
+ d.emit(record)
265
+ d.run
266
+
267
+ assert_equal 1, @posts.size
268
+
269
+ d.emit({})
270
+ d.run
271
+ assert last_emit + RATE_LIMIT_MSEC > _current_msec, "Still under rate limiting interval"
272
+ assert_equal 1, @posts.size
273
+
274
+ wait_msec = 500
275
+ sleep (last_emit + RATE_LIMIT_MSEC - _current_msec + wait_msec) * 0.001
276
+
277
+ assert last_emit + RATE_LIMIT_MSEC < _current_msec, "No longer under rate limiting interval"
278
+ d.emit(record)
279
+ d.run
280
+ assert_equal 2, @posts.size
281
+ end
282
+
283
+ def _current_msec
284
+ Time.now.to_f * 1000
285
+ end
286
+
287
+ def test_auth
288
+ @auth = true # enable authentication of dummy server
289
+
290
+ d = create_driver(CONFIG_FORM, 'test.metrics')
291
+ d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
292
+ d.run # failed in background, and output warn log
293
+
294
+ assert_equal 0, @posts.size
295
+ assert_equal 1, @prohibited
296
+
297
+ d = create_driver(CONFIG_FORM + %[
298
+ authentication basic
299
+ username alice
300
+ password wrong_password
301
+ ], 'test.metrics')
302
+ d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
303
+ d.run # failed in background, and output warn log
304
+
305
+ assert_equal 0, @posts.size
306
+ assert_equal 2, @prohibited
307
+
308
+ d = create_driver(CONFIG_FORM + %[
309
+ authentication basic
310
+ username alice
311
+ password secret!
312
+ ], 'test.metrics')
313
+ d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
314
+ d.run # failed in background, and output warn log
315
+
316
+ assert_equal 1, @posts.size
317
+ assert_equal 2, @prohibited
318
+ end
319
+
320
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-out-falcon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.5
5
+ platform: ruby
6
+ authors:
7
+ - Marica Odagaki
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: yajl-ruby
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: fluentd
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.10.0
34
+ - - "<"
35
+ - !ruby/object:Gem::Version
36
+ version: '2'
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 0.10.0
44
+ - - "<"
45
+ - !ruby/object:Gem::Version
46
+ version: '2'
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: test-unit
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: 3.1.0
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 3.1.0
89
+ description: A Fluentd output plugin to send logs to falcon's push api
90
+ email:
91
+ - ento.entotto@gmail.com
92
+ executables: []
93
+ extensions: []
94
+ extra_rdoc_files: []
95
+ files:
96
+ - ".gitignore"
97
+ - ".travis.yml"
98
+ - Gemfile
99
+ - LICENSE.txt
100
+ - README.md
101
+ - Rakefile
102
+ - lib/fluent/plugin/out_falcon.rb
103
+ - lib/fluent/test/falcon_output_test.rb
104
+ - test/plugin/test_out_falcon.rb
105
+ homepage: https://github.com/tsingakbar/fluent-plugin-out-falcon
106
+ licenses:
107
+ - Apache-2.0
108
+ metadata: {}
109
+ post_install_message:
110
+ rdoc_options: []
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ requirements: []
124
+ rubyforge_project:
125
+ rubygems_version: 2.5.1
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: A Fluentd output plugin to send logs to falcon's push api
129
+ test_files:
130
+ - test/plugin/test_out_falcon.rb