fluent-plugin-out-http 0.3.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +0 -9
- data/README.md +2 -3
- data/fluent-plugin-out-http.gemspec +3 -3
- data/lib/fluent/plugin/out_http.rb +49 -33
- data/test/plugin/test_out_http.rb +132 -138
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3fd85f5885dad181862a83638f8bb88f67f896abb63f705f6e7c9c128318feac
|
4
|
+
data.tar.gz: d10e356dd5f510b085385ac52034d43ba3a92fc457549fc719a0305da298096f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f47578551ada94db75b72156cd0c1e96fbad70225e715eca3ed63ad1d34123b2e870fdfe47c11d6c5a7b0605a81c8e820ce78748fac6c6bb0a32f775ded3664e
|
7
|
+
data.tar.gz: 8ef5a6c31b36978efdef707c6064772c4d2151b87b576766698ae07e522ec645a7a683b455363658f2e36c43c2fce2ba4fd0bb624e236c389ec7e4d7fdc77a08
|
data/CHANGELOG.md
CHANGED
@@ -1,14 +1,5 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## 0.3.1
|
4
|
-
### Added
|
5
|
-
* Added plain text transport capability
|
6
|
-
* Added specify cacert file for ssl verify
|
7
|
-
|
8
|
-
## 0.3.0
|
9
|
-
### Added
|
10
|
-
* Support for jwt token authentication:
|
11
|
-
|
12
3
|
## 0.2.0
|
13
4
|
### Added
|
14
5
|
* SSL is now supported if `endpoint_url` uses the `https` scheme (uses ruby-2.1 syntax internally)
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
A generic [fluentd][1] output plugin for sending logs to an HTTP endpoint.
|
4
4
|
|
5
|
-
[![Build Status](https://travis-ci.org/
|
5
|
+
[![Build Status](https://travis-ci.org/fluent-plugins-nursery/fluent-plugin-out-http.svg?branch=master)](https://travis-ci.org/fluent-plugins-nursery/fluent-plugin-out-http)
|
6
6
|
|
7
7
|
## Configuration options
|
8
8
|
|
@@ -16,8 +16,7 @@ A generic [fluentd][1] output plugin for sending logs to an HTTP endpoint.
|
|
16
16
|
authentication basic # default: none
|
17
17
|
username alice # default: ''
|
18
18
|
password bobpop # default: '', secret: true
|
19
|
-
|
20
|
-
token tokent # default: ''
|
19
|
+
buffered true # default: false. Switch non-buffered/buffered mode
|
21
20
|
</match>
|
22
21
|
|
23
22
|
## Usage notes
|
@@ -2,12 +2,12 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |gem|
|
4
4
|
gem.name = "fluent-plugin-out-http"
|
5
|
-
gem.version = "0.
|
5
|
+
gem.version = "1.0.0"
|
6
6
|
gem.authors = ["Marica Odagaki"]
|
7
7
|
gem.email = ["ento.entotto@gmail.com"]
|
8
8
|
gem.summary = %q{A generic Fluentd output plugin to send logs to an HTTP endpoint}
|
9
9
|
gem.description = gem.summary
|
10
|
-
gem.homepage = "https://github.com/
|
10
|
+
gem.homepage = "https://github.com/fluent-plugins-nursery/fluent-plugin-out-http"
|
11
11
|
gem.licenses = ["Apache-2.0"]
|
12
12
|
|
13
13
|
gem.files = `git ls-files`.split($\)
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.required_ruby_version = '>= 2.1.0'
|
19
19
|
|
20
20
|
gem.add_runtime_dependency "yajl-ruby", "~> 1.0"
|
21
|
-
gem.add_runtime_dependency "fluentd", [">= 0.
|
21
|
+
gem.add_runtime_dependency "fluentd", [">= 0.14.15", "< 2"]
|
22
22
|
gem.add_development_dependency "bundler"
|
23
23
|
gem.add_development_dependency "rake"
|
24
24
|
gem.add_development_dependency "test-unit", ">= 3.1.0"
|
@@ -1,11 +1,17 @@
|
|
1
|
-
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'yajl'
|
4
|
+
require 'fluent/plugin/output'
|
5
|
+
|
6
|
+
class Fluent::Plugin::HTTPOutput < Fluent::Plugin::Output
|
2
7
|
Fluent::Plugin.register_output('http', self)
|
3
8
|
|
9
|
+
helpers :compat_parameters
|
10
|
+
|
11
|
+
DEFAULT_BUFFER_TYPE = "memory"
|
12
|
+
|
4
13
|
def initialize
|
5
14
|
super
|
6
|
-
require 'net/http'
|
7
|
-
require 'uri'
|
8
|
-
require 'yajl'
|
9
15
|
end
|
10
16
|
|
11
17
|
# Endpoint URL ex. http://localhost.local/api/
|
@@ -27,16 +33,20 @@ class Fluent::HTTPOutput < Fluent::Output
|
|
27
33
|
# Raise errors that were rescued during HTTP requests?
|
28
34
|
config_param :raise_on_error, :bool, :default => true
|
29
35
|
|
30
|
-
#
|
31
|
-
config_param :cacert_file, :string, :default => ''
|
32
|
-
|
33
|
-
# nil | 'none' | 'basic' | 'jwt' | 'bearer'
|
36
|
+
# nil | 'none' | 'basic'
|
34
37
|
config_param :authentication, :string, :default => nil
|
35
38
|
config_param :username, :string, :default => ''
|
36
39
|
config_param :password, :string, :default => '', :secret => true
|
37
|
-
|
40
|
+
# Switch non-buffered/buffered plugin
|
41
|
+
config_param :buffered, :bool, :default => false
|
42
|
+
|
43
|
+
config_section :buffer do
|
44
|
+
config_set_default :@type, DEFAULT_BUFFER_TYPE
|
45
|
+
config_set_default :chunk_keys, ['tag']
|
46
|
+
end
|
38
47
|
|
39
48
|
def configure(conf)
|
49
|
+
compat_parameters_convert(conf, :buffer)
|
40
50
|
super
|
41
51
|
|
42
52
|
@ssl_verify_mode = if @ssl_no_verify
|
@@ -45,9 +55,7 @@ class Fluent::HTTPOutput < Fluent::Output
|
|
45
55
|
OpenSSL::SSL::VERIFY_PEER
|
46
56
|
end
|
47
57
|
|
48
|
-
|
49
|
-
|
50
|
-
serializers = [:json, :form, :text]
|
58
|
+
serializers = [:json, :form]
|
51
59
|
@serializer = if serializers.include? @serializer.intern
|
52
60
|
@serializer.intern
|
53
61
|
else
|
@@ -63,13 +71,12 @@ class Fluent::HTTPOutput < Fluent::Output
|
|
63
71
|
|
64
72
|
@auth = case @authentication
|
65
73
|
when 'basic' then :basic
|
66
|
-
when 'bearer' then :bearer
|
67
|
-
when 'jwt' then :jwt
|
68
74
|
else
|
69
75
|
:none
|
70
76
|
end
|
71
77
|
|
72
78
|
@last_request_time = nil
|
79
|
+
raise Fluent::ConfigError, "'tag' in chunk_keys is required." if !@chunk_key_tag && @buffered
|
73
80
|
end
|
74
81
|
|
75
82
|
def start
|
@@ -79,7 +86,7 @@ class Fluent::HTTPOutput < Fluent::Output
|
|
79
86
|
def shutdown
|
80
87
|
super
|
81
88
|
end
|
82
|
-
|
89
|
+
|
83
90
|
def format_url(tag, time, record)
|
84
91
|
@endpoint_url
|
85
92
|
end
|
@@ -87,8 +94,6 @@ class Fluent::HTTPOutput < Fluent::Output
|
|
87
94
|
def set_body(req, tag, time, record)
|
88
95
|
if @serializer == :json
|
89
96
|
set_json_body(req, record)
|
90
|
-
elsif @serializer == :text
|
91
|
-
set_text_body(req, record)
|
92
97
|
else
|
93
98
|
req.set_form_data(record)
|
94
99
|
end
|
@@ -104,11 +109,6 @@ class Fluent::HTTPOutput < Fluent::Output
|
|
104
109
|
req['Content-Type'] = 'application/json'
|
105
110
|
end
|
106
111
|
|
107
|
-
def set_text_body(req, data)
|
108
|
-
req.body = data["message"]
|
109
|
-
req['Content-Type'] = 'text/plain'
|
110
|
-
end
|
111
|
-
|
112
112
|
def create_request(tag, time, record)
|
113
113
|
url = format_url(tag, time, record)
|
114
114
|
uri = URI.parse(url)
|
@@ -123,14 +123,13 @@ class Fluent::HTTPOutput < Fluent::Output
|
|
123
123
|
:use_ssl => uri.scheme == 'https'
|
124
124
|
}
|
125
125
|
opts[:verify_mode] = @ssl_verify_mode if opts[:use_ssl]
|
126
|
-
opts[:ca_file] = File.join(@ca_file) if File.file?(@ca_file)
|
127
126
|
opts
|
128
127
|
end
|
129
128
|
|
130
129
|
def send_request(req, uri)
|
131
130
|
is_rate_limited = (@rate_limit_msec != 0 and not @last_request_time.nil?)
|
132
131
|
if is_rate_limited and ((Time.now.to_f - @last_request_time) * 1000.0 < @rate_limit_msec)
|
133
|
-
|
132
|
+
log.info('Dropped request due to rate limiting')
|
134
133
|
return
|
135
134
|
end
|
136
135
|
|
@@ -139,16 +138,12 @@ class Fluent::HTTPOutput < Fluent::Output
|
|
139
138
|
begin
|
140
139
|
if @auth and @auth == :basic
|
141
140
|
req.basic_auth(@username, @password)
|
142
|
-
elsif @auth and @auth == :bearer
|
143
|
-
req['authorization'] = "bearer #{@token}"
|
144
|
-
elsif @auth and @auth == :jwt
|
145
|
-
req['authorization'] = "jwt #{@token}"
|
146
141
|
end
|
147
142
|
@last_request_time = Time.now.to_f
|
148
143
|
res = Net::HTTP.start(uri.host, uri.port, **http_opts(uri)) {|http| http.request(req) }
|
149
144
|
rescue => e # rescue all StandardErrors
|
150
145
|
# server didn't respond
|
151
|
-
|
146
|
+
log.warn "Net::HTTP.#{req.method.capitalize} raises exception: #{e.class}, '#{e.message}'"
|
152
147
|
raise e if @raise_on_error
|
153
148
|
else
|
154
149
|
unless res and res.is_a?(Net::HTTPSuccess)
|
@@ -157,7 +152,7 @@ class Fluent::HTTPOutput < Fluent::Output
|
|
157
152
|
else
|
158
153
|
"res=nil"
|
159
154
|
end
|
160
|
-
|
155
|
+
log.warn "failed to #{req.method} #{uri} (#{res_summary})"
|
161
156
|
end #end unless
|
162
157
|
end # end begin
|
163
158
|
end # end send_request
|
@@ -167,11 +162,32 @@ class Fluent::HTTPOutput < Fluent::Output
|
|
167
162
|
send_request(req, uri)
|
168
163
|
end
|
169
164
|
|
170
|
-
def
|
165
|
+
def prefer_buffered_processing
|
166
|
+
@buffered
|
167
|
+
end
|
168
|
+
|
169
|
+
def format(tag, time, record)
|
170
|
+
[time, record].to_msgpack
|
171
|
+
end
|
172
|
+
|
173
|
+
def formatted_to_msgpack_binary?
|
174
|
+
true
|
175
|
+
end
|
176
|
+
|
177
|
+
def multi_workers_ready?
|
178
|
+
true
|
179
|
+
end
|
180
|
+
|
181
|
+
def process(tag, es)
|
171
182
|
es.each do |time, record|
|
172
183
|
handle_record(tag, time, record)
|
173
184
|
end
|
174
|
-
chain.next
|
175
185
|
end
|
176
|
-
end
|
177
186
|
|
187
|
+
def write(chunk)
|
188
|
+
tag = chunk.metadata.tag
|
189
|
+
chunk.msgpack_each do |time, record|
|
190
|
+
handle_record(tag, time, record)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
@@ -4,27 +4,13 @@ require 'uri'
|
|
4
4
|
require 'yajl'
|
5
5
|
require 'fluent/test/http_output_test'
|
6
6
|
require 'fluent/plugin/out_http'
|
7
|
+
require 'fluent/test/driver/output'
|
8
|
+
require 'fluent/test/helpers'
|
7
9
|
|
8
|
-
module OS
|
9
|
-
# ref. http://stackoverflow.com/questions/170956/how-can-i-find-which-operating-system-my-ruby-program-is-running-on
|
10
|
-
def OS.windows?
|
11
|
-
(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
|
12
|
-
end
|
13
|
-
|
14
|
-
def OS.mac?
|
15
|
-
(/darwin/ =~ RUBY_PLATFORM) != nil
|
16
|
-
end
|
17
|
-
|
18
|
-
def OS.unix?
|
19
|
-
!OS.windows?
|
20
|
-
end
|
21
|
-
|
22
|
-
def OS.linux?
|
23
|
-
OS.unix? and not OS.mac?
|
24
|
-
end
|
25
|
-
end
|
26
10
|
|
27
11
|
class HTTPOutputTestBase < Test::Unit::TestCase
|
12
|
+
include Fluent::Test::Helpers
|
13
|
+
|
28
14
|
def self.port
|
29
15
|
5126
|
30
16
|
end
|
@@ -65,22 +51,6 @@ class HTTPOutputTestBase < Test::Unit::TestCase
|
|
65
51
|
end
|
66
52
|
if @auth and req.header['authorization'][0] == 'Basic YWxpY2U6c2VjcmV0IQ==' # pattern of user='alice' passwd='secret!'
|
67
53
|
# ok, authorized
|
68
|
-
# pattern of bear #{Base64.encode64('secret token!')}
|
69
|
-
elsif @auth and req.header['authorization'][0] == 'bearer c2VjcmV0IHRva2VuIQ=='
|
70
|
-
# pattern of jwt
|
71
|
-
# header: {
|
72
|
-
# "alg": "HS256",
|
73
|
-
# "typ": "JWT"
|
74
|
-
# }
|
75
|
-
# payload: {
|
76
|
-
# "iss": "Hoge Publisher",
|
77
|
-
# "sub": "Hoge User"
|
78
|
-
# }
|
79
|
-
# signature:
|
80
|
-
# HS256(base64UrlEncode(header) + "." +
|
81
|
-
# base64UrlEncode(payload) + "." +
|
82
|
-
# secret)
|
83
|
-
elsif @auth and req.header['authorization'][0] == 'jwt eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJIb2dlIFB1Ymxpc2hlciIsInN1YiI6IkhvZ2UgVXNlciJ9.V2NL7YgCWNt5d3vTXFrcRLpRImO2cU2JZ4mQglqw3rE'
|
84
54
|
elsif @auth
|
85
55
|
res.status = 403
|
86
56
|
@prohibited += 1
|
@@ -92,9 +62,6 @@ class HTTPOutputTestBase < Test::Unit::TestCase
|
|
92
62
|
record = {:auth => nil}
|
93
63
|
if req.content_type == 'application/json'
|
94
64
|
record[:json] = Yajl.load(req.body)
|
95
|
-
elsif req.content_type == 'text/plain'
|
96
|
-
puts req
|
97
|
-
record[:data] = req.body
|
98
65
|
else
|
99
66
|
record[:form] = Hash[*(req.body.split('&').map{|kv|kv.split('=')}.flatten)]
|
100
67
|
end
|
@@ -180,8 +147,8 @@ class HTTPOutputTestBase < Test::Unit::TestCase
|
|
180
147
|
@dummy_server_thread.join
|
181
148
|
end
|
182
149
|
|
183
|
-
def create_driver(conf
|
184
|
-
Fluent::Test::
|
150
|
+
def create_driver(conf)
|
151
|
+
Fluent::Test::Driver::Output.new(Fluent::Plugin::HTTPOutput).configure(conf)
|
185
152
|
end
|
186
153
|
end
|
187
154
|
|
@@ -195,11 +162,6 @@ class HTTPOutputTest < HTTPOutputTestBase
|
|
195
162
|
serializer json
|
196
163
|
]
|
197
164
|
|
198
|
-
CONFIG_TEXT = %[
|
199
|
-
endpoint_url http://127.0.0.1:#{port}/api/
|
200
|
-
serializer text
|
201
|
-
]
|
202
|
-
|
203
165
|
CONFIG_PUT = %[
|
204
166
|
endpoint_url http://127.0.0.1:#{port}/api/
|
205
167
|
http_method put
|
@@ -231,10 +193,27 @@ class HTTPOutputTest < HTTPOutputTestBase
|
|
231
193
|
assert_equal :json, d.instance.serializer
|
232
194
|
end
|
233
195
|
|
196
|
+
test 'lack of tag in chunk_keys' do
|
197
|
+
assert_raise_message(/'tag' in chunk_keys is required./) do
|
198
|
+
create_driver(Fluent::Config::Element.new(
|
199
|
+
'ROOT', '', {
|
200
|
+
'@type' => 'http',
|
201
|
+
'endpoint_url' => "http://127.0.0.1:#{self.class.port}/api/",
|
202
|
+
'buffered' => true,
|
203
|
+
}, [
|
204
|
+
Fluent::Config::Element.new('buffer', 'mykey', {
|
205
|
+
'chunk_keys' => 'mykey'
|
206
|
+
}, [])
|
207
|
+
]
|
208
|
+
))
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
234
212
|
def test_emit_form
|
235
213
|
d = create_driver CONFIG
|
236
|
-
d.
|
237
|
-
|
214
|
+
d.run(default_tag: 'test.metrics') do
|
215
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1, 'binary' => "\xe3\x81\x82".force_encoding("ascii-8bit") })
|
216
|
+
end
|
238
217
|
|
239
218
|
assert_equal 1, @posts.size
|
240
219
|
record = @posts[0]
|
@@ -246,16 +225,82 @@ class HTTPOutputTest < HTTPOutputTestBase
|
|
246
225
|
assert_equal URI.encode_www_form_component("あ").upcase, record[:form]['binary'].upcase
|
247
226
|
assert_nil record[:auth]
|
248
227
|
|
249
|
-
d.
|
250
|
-
|
228
|
+
d.run(default_tag: 'test.metrics') do
|
229
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
230
|
+
end
|
251
231
|
|
252
232
|
assert_equal 2, @posts.size
|
253
233
|
end
|
254
234
|
|
235
|
+
class BufferedEmitTest < self
|
236
|
+
def test_emit_form
|
237
|
+
d = create_driver CONFIG + %[buffered true]
|
238
|
+
d.run(default_tag: 'test.metrics', shutdown: false) do
|
239
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1, 'binary' => "\xe3\x81\x82".force_encoding("ascii-8bit") })
|
240
|
+
end
|
241
|
+
|
242
|
+
assert_equal 1, @posts.size
|
243
|
+
record = @posts[0]
|
244
|
+
|
245
|
+
assert_equal '50', record[:form]['field1']
|
246
|
+
assert_equal '20', record[:form]['field2']
|
247
|
+
assert_equal '10', record[:form]['field3']
|
248
|
+
assert_equal '1', record[:form]['otherfield']
|
249
|
+
assert_equal URI.encode_www_form_component("あ").upcase, record[:form]['binary'].upcase
|
250
|
+
assert_nil record[:auth]
|
251
|
+
|
252
|
+
d.run(default_tag: 'test.metrics', shutdown: false) do
|
253
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
254
|
+
end
|
255
|
+
|
256
|
+
assert_equal 2, @posts.size
|
257
|
+
end
|
258
|
+
|
259
|
+
def test_emit_form_put
|
260
|
+
d = create_driver CONFIG_PUT + %[buffered true]
|
261
|
+
d.run(default_tag: 'test.metrics', shutdown: false) do
|
262
|
+
d.feed({ 'field1' => 50 })
|
263
|
+
end
|
264
|
+
|
265
|
+
assert_equal 0, @posts.size
|
266
|
+
assert_equal 1, @puts.size
|
267
|
+
record = @puts[0]
|
268
|
+
|
269
|
+
assert_equal '50', record[:form]['field1']
|
270
|
+
assert_nil record[:auth]
|
271
|
+
|
272
|
+
d.run(default_tag: 'test.metrics', shutdown: false) do
|
273
|
+
d.feed({ 'field1' => 50 })
|
274
|
+
end
|
275
|
+
|
276
|
+
assert_equal 0, @posts.size
|
277
|
+
assert_equal 2, @puts.size
|
278
|
+
end
|
279
|
+
|
280
|
+
def test_emit_json
|
281
|
+
binary_string = "\xe3\x81\x82"
|
282
|
+
d = create_driver CONFIG_JSON + %[buffered true]
|
283
|
+
d.run(default_tag: 'test.metrics') do
|
284
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1, 'binary' => binary_string })
|
285
|
+
end
|
286
|
+
|
287
|
+
assert_equal 1, @posts.size
|
288
|
+
record = @posts[0]
|
289
|
+
|
290
|
+
assert_equal 50, record[:json]['field1']
|
291
|
+
assert_equal 20, record[:json]['field2']
|
292
|
+
assert_equal 10, record[:json]['field3']
|
293
|
+
assert_equal 1, record[:json]['otherfield']
|
294
|
+
assert_equal binary_string, record[:json]['binary']
|
295
|
+
assert_nil record[:auth]
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
255
299
|
def test_emit_form_put
|
256
300
|
d = create_driver CONFIG_PUT
|
257
|
-
d.
|
258
|
-
|
301
|
+
d.run(default_tag: 'test.metrics') do
|
302
|
+
d.feed({ 'field1' => 50 })
|
303
|
+
end
|
259
304
|
|
260
305
|
assert_equal 0, @posts.size
|
261
306
|
assert_equal 1, @puts.size
|
@@ -264,8 +309,9 @@ class HTTPOutputTest < HTTPOutputTestBase
|
|
264
309
|
assert_equal '50', record[:form]['field1']
|
265
310
|
assert_nil record[:auth]
|
266
311
|
|
267
|
-
d.
|
268
|
-
|
312
|
+
d.run(default_tag: 'test.metrics') do
|
313
|
+
d.feed({ 'field1' => 50 })
|
314
|
+
end
|
269
315
|
|
270
316
|
assert_equal 0, @posts.size
|
271
317
|
assert_equal 2, @puts.size
|
@@ -274,8 +320,9 @@ class HTTPOutputTest < HTTPOutputTestBase
|
|
274
320
|
def test_emit_json
|
275
321
|
binary_string = "\xe3\x81\x82"
|
276
322
|
d = create_driver CONFIG_JSON
|
277
|
-
d.
|
278
|
-
|
323
|
+
d.run(default_tag: 'test.metrics') do
|
324
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1, 'binary' => binary_string })
|
325
|
+
end
|
279
326
|
|
280
327
|
assert_equal 1, @posts.size
|
281
328
|
record = @posts[0]
|
@@ -286,30 +333,22 @@ class HTTPOutputTest < HTTPOutputTestBase
|
|
286
333
|
assert_equal 1, record[:json]['otherfield']
|
287
334
|
assert_equal binary_string, record[:json]['binary']
|
288
335
|
assert_nil record[:auth]
|
289
|
-
end
|
290
|
-
|
291
|
-
def test_emit_text
|
292
|
-
binary_string = "\xe3\x81\x82"
|
293
|
-
d = create_driver CONFIG_TEXT
|
294
|
-
d.emit({ "message" => "hello" })
|
295
|
-
d.run
|
296
|
-
assert_equal 1, @posts.size
|
297
|
-
record = @posts[0]
|
298
|
-
assert_equal 'hello', record[:data]
|
299
|
-
assert_nil record[:auth]
|
300
336
|
end
|
301
337
|
|
302
338
|
def test_http_error_is_raised
|
303
339
|
d = create_driver CONFIG_HTTP_ERROR
|
304
340
|
assert_raise Errno::ECONNREFUSED do
|
305
|
-
d.
|
341
|
+
d.run(default_tag: 'test.metrics') do
|
342
|
+
d.feed({ 'field1' => 50 })
|
343
|
+
end
|
306
344
|
end
|
307
345
|
end
|
308
346
|
|
309
347
|
def test_http_error_is_suppressed_with_raise_on_error_false
|
310
348
|
d = create_driver CONFIG_HTTP_ERROR_SUPPRESSED
|
311
|
-
d.
|
312
|
-
|
349
|
+
d.run(default_tag: 'test.metrics') do
|
350
|
+
d.feed({ 'field1' => 50 })
|
351
|
+
end
|
313
352
|
# drive asserts the next output chain is called;
|
314
353
|
# so no exception means our plugin handled the error
|
315
354
|
|
@@ -321,23 +360,25 @@ class HTTPOutputTest < HTTPOutputTestBase
|
|
321
360
|
record = { :k => 1 }
|
322
361
|
|
323
362
|
last_emit = _current_msec
|
324
|
-
d.
|
325
|
-
|
363
|
+
d.run(default_tag: 'test.metrics') do
|
364
|
+
d.feed(record)
|
365
|
+
end
|
326
366
|
|
327
367
|
assert_equal 1, @posts.size
|
328
368
|
|
329
|
-
d.
|
330
|
-
|
331
|
-
|
332
|
-
assert last_emit + RATE_LIMIT_MSEC > _current_msec, "Still under rate limiting interval"
|
369
|
+
d.run(default_tag: 'test.metrics') do
|
370
|
+
d.feed({})
|
371
|
+
end
|
372
|
+
assert last_emit + RATE_LIMIT_MSEC > _current_msec, "Still under rate limiting interval"
|
333
373
|
assert_equal 1, @posts.size
|
334
374
|
|
335
375
|
wait_msec = 500
|
336
376
|
sleep (last_emit + RATE_LIMIT_MSEC - _current_msec + wait_msec) * 0.001
|
337
377
|
|
338
378
|
assert last_emit + RATE_LIMIT_MSEC < _current_msec, "No longer under rate limiting interval"
|
339
|
-
d.
|
340
|
-
|
379
|
+
d.run(default_tag: 'test.metrics') do
|
380
|
+
d.feed(record)
|
381
|
+
end
|
341
382
|
assert_equal 2, @posts.size
|
342
383
|
end
|
343
384
|
|
@@ -348,9 +389,10 @@ class HTTPOutputTest < HTTPOutputTestBase
|
|
348
389
|
def test_auth
|
349
390
|
@auth = true # enable authentication of dummy server
|
350
391
|
|
351
|
-
d = create_driver(CONFIG
|
352
|
-
d.
|
353
|
-
|
392
|
+
d = create_driver(CONFIG)
|
393
|
+
d.run(default_tag: 'test.metrics') do
|
394
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
395
|
+
end # failed in background, and output warn log
|
354
396
|
|
355
397
|
assert_equal 0, @posts.size
|
356
398
|
assert_equal 1, @prohibited
|
@@ -359,9 +401,10 @@ class HTTPOutputTest < HTTPOutputTestBase
|
|
359
401
|
authentication basic
|
360
402
|
username alice
|
361
403
|
password wrong_password
|
362
|
-
]
|
363
|
-
d.
|
364
|
-
|
404
|
+
])
|
405
|
+
d.run(default_tag: 'test.metrics') do
|
406
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
407
|
+
end # failed in background, and output warn log
|
365
408
|
|
366
409
|
assert_equal 0, @posts.size
|
367
410
|
assert_equal 2, @prohibited
|
@@ -370,33 +413,13 @@ class HTTPOutputTest < HTTPOutputTestBase
|
|
370
413
|
authentication basic
|
371
414
|
username alice
|
372
415
|
password secret!
|
373
|
-
]
|
374
|
-
d.
|
375
|
-
|
416
|
+
])
|
417
|
+
d.run(default_tag: 'test.metrics') do
|
418
|
+
d.feed({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
419
|
+
end # failed in background, and output warn log
|
376
420
|
|
377
421
|
assert_equal 1, @posts.size
|
378
422
|
assert_equal 2, @prohibited
|
379
|
-
|
380
|
-
require 'base64'
|
381
|
-
d = create_driver(CONFIG + %[
|
382
|
-
authentication bearer
|
383
|
-
token #{Base64.encode64('secret token!')}
|
384
|
-
], 'test.metrics')
|
385
|
-
d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
386
|
-
d.run # failed in background, and output warn log
|
387
|
-
|
388
|
-
assert_equal 2, @posts.size
|
389
|
-
assert_equal 2, @prohibited
|
390
|
-
|
391
|
-
d = create_driver(CONFIG + %[
|
392
|
-
authentication jwt
|
393
|
-
token eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJIb2dlIFB1Ymxpc2hlciIsInN1YiI6IkhvZ2UgVXNlciJ9.V2NL7YgCWNt5d3vTXFrcRLpRImO2cU2JZ4mQglqw3rE
|
394
|
-
], 'test.metrics')
|
395
|
-
d.emit({ 'field1' => 50, 'field2' => 20, 'field3' => 10, 'otherfield' => 1 })
|
396
|
-
d.run # failed in background, and output warn log
|
397
|
-
|
398
|
-
assert_equal 3, @posts.size
|
399
|
-
assert_equal 2, @prohibited
|
400
423
|
end
|
401
424
|
|
402
425
|
end
|
@@ -441,20 +464,6 @@ class HTTPSOutputTest < HTTPOutputTestBase
|
|
441
464
|
http_opts = d.instance.http_opts(test_uri)
|
442
465
|
assert_equal true, http_opts[:use_ssl]
|
443
466
|
assert_equal OpenSSL::SSL::VERIFY_NONE, http_opts[:verify_mode]
|
444
|
-
|
445
|
-
cacert_file_config = %[
|
446
|
-
endpoint_url https://127.0.0.1:#{self.class.port}/api/
|
447
|
-
ssl_no_verify true
|
448
|
-
cacert_file /tmp/ssl.cert
|
449
|
-
]
|
450
|
-
d = create_driver cacert_file_config
|
451
|
-
FileUtils::touch '/tmp/ssl.cert'
|
452
|
-
http_opts = d.instance.http_opts(test_uri)
|
453
|
-
assert_equal true, http_opts[:use_ssl]
|
454
|
-
assert_equal OpenSSL::SSL::VERIFY_NONE, http_opts[:verify_mode]
|
455
|
-
assert_equal true, File.file?('/tmp/ssl.cert')
|
456
|
-
puts http_opts
|
457
|
-
assert_equal File.join('/tmp/ssl.cert'), http_opts[:ca_file]
|
458
467
|
end
|
459
468
|
|
460
469
|
def test_emit_form_ssl
|
@@ -463,24 +472,9 @@ class HTTPSOutputTest < HTTPOutputTestBase
|
|
463
472
|
ssl_no_verify true
|
464
473
|
]
|
465
474
|
d = create_driver config
|
466
|
-
d.
|
467
|
-
|
468
|
-
|
469
|
-
assert_equal 1, @posts.size
|
470
|
-
record = @posts[0]
|
471
|
-
|
472
|
-
assert_equal '50', record[:form]['field1']
|
473
|
-
end
|
474
|
-
|
475
|
-
def test_emit_form_ssl_ca
|
476
|
-
config = %[
|
477
|
-
endpoint_url https://127.0.0.1:#{self.class.port}/api/
|
478
|
-
ssl_no_verify true
|
479
|
-
cacert_file /tmp/ssl.cert
|
480
|
-
]
|
481
|
-
d = create_driver config
|
482
|
-
d.emit({ 'field1' => 50 })
|
483
|
-
d.run
|
475
|
+
d.run(default_tag: 'test.metrics') do
|
476
|
+
d.feed({ 'field1' => 50 })
|
477
|
+
end
|
484
478
|
|
485
479
|
assert_equal 1, @posts.size
|
486
480
|
record = @posts[0]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-out-http
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marica Odagaki
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-11-
|
11
|
+
date: 2018-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: yajl-ruby
|
@@ -30,7 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.14.15
|
34
34
|
- - "<"
|
35
35
|
- !ruby/object:Gem::Version
|
36
36
|
version: '2'
|
@@ -40,7 +40,7 @@ dependencies:
|
|
40
40
|
requirements:
|
41
41
|
- - ">="
|
42
42
|
- !ruby/object:Gem::Version
|
43
|
-
version: 0.
|
43
|
+
version: 0.14.15
|
44
44
|
- - "<"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '2'
|
@@ -104,7 +104,7 @@ files:
|
|
104
104
|
- lib/fluent/plugin/out_http.rb
|
105
105
|
- lib/fluent/test/http_output_test.rb
|
106
106
|
- test/plugin/test_out_http.rb
|
107
|
-
homepage: https://github.com/
|
107
|
+
homepage: https://github.com/fluent-plugins-nursery/fluent-plugin-out-http
|
108
108
|
licenses:
|
109
109
|
- Apache-2.0
|
110
110
|
metadata: {}
|