fluent-plugin-out-http 0.3.1 → 1.0.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.
- 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
|
-
[](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: {}
|