fluentd 1.2.2 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/fluentd.gemspec +1 -1
- data/lib/fluent/config/configure_proxy.rb +1 -1
- data/lib/fluent/config/dsl.rb +8 -5
- data/lib/fluent/plugin/compressable.rb +1 -1
- data/lib/fluent/plugin/in_http.rb +37 -5
- data/lib/fluent/plugin/in_monitor_agent.rb +6 -0
- data/lib/fluent/plugin/in_tail.rb +15 -11
- data/lib/fluent/plugin/parser_syslog.rb +2 -2
- data/lib/fluent/version.rb +1 -1
- data/templates/new_gem/lib/fluent/plugin/parser.rb.erb +3 -3
- data/test/config/test_dsl.rb +8 -8
- data/test/counter/test_client.rb +10 -4
- data/test/counter/test_server.rb +9 -3
- data/test/counter/test_store.rb +10 -4
- data/test/plugin/test_in_http.rb +110 -0
- data/test/plugin/test_out_file.rb +6 -2
- data/test/plugin_helper/test_retry_state.rb +2 -2
- data/test/test_configdsl.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 592df476adfeb30ef3a08865d03af3eeb7f60e1d27684f22dc3505b8dc7bcab4
|
4
|
+
data.tar.gz: acc575bbf086686addf560a7a65e084221a609ce5eff6385b88a9aea65c4aca4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1f5ebc8c426c80c7b6501afba2ac9534aeceafe21945e58fd0530dbde099d8cdbd0a6c9533c7500d838db09f66dfbefd4fbed5cb6304ab71fe473ab0a63cd5c
|
7
|
+
data.tar.gz: 6eef15e5140fc4547c59215ae01cd9eb661429bb7eb36067e6834f877c916bf78507345091002116129435e548525654e289db36c3a786f7aebc5780835458ef
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,31 @@
|
|
1
1
|
# v1.2
|
2
2
|
|
3
|
+
## Release v1.2.3 - 2018/07/10
|
4
|
+
|
5
|
+
### Enhancements
|
6
|
+
|
7
|
+
* in_http: Consider `<parse>` parameters in batch mode
|
8
|
+
https://github.com/fluent/fluentd/pull/2055
|
9
|
+
* in_http: Support gzip payload
|
10
|
+
https://github.com/fluent/fluentd/pull/2060
|
11
|
+
* output: Improve compress performance
|
12
|
+
https://github.com/fluent/fluentd/pull/2031
|
13
|
+
* in_monitor_agent: Add missing descriptions for configurable options
|
14
|
+
https://github.com/fluent/fluentd/pull/2037
|
15
|
+
* parser_syslog: update regex of pid field for conformance to RFC5424 spec
|
16
|
+
https://github.com/fluent/fluentd/pull/2051
|
17
|
+
|
18
|
+
### Bug fixes
|
19
|
+
|
20
|
+
* in_tail: Fix to rescue Errno::ENOENT for File.mtime()
|
21
|
+
https://github.com/fluent/fluentd/pull/2063
|
22
|
+
* fluent-plugin-generate: Fix Parser plugin template
|
23
|
+
https://github.com/fluent/fluentd/pull/2026
|
24
|
+
* fluent-plugin-config-format: Fix NoMethodError for some plugins
|
25
|
+
https://github.com/fluent/fluentd/pull/2023
|
26
|
+
* config: Don't warn message for reserved parameters in DSL
|
27
|
+
https://github.com/fluent/fluentd/pull/2034
|
28
|
+
|
3
29
|
## Release v1.2.2 - 2018/06/12
|
4
30
|
|
5
31
|
### Enhancements
|
data/fluentd.gemspec
CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.email = ["frsyuki@gmail.com"]
|
9
9
|
gem.description = %q{Fluentd is an open source data collector designed to scale and simplify log management. It can collect, process and ship many kinds of data in near real-time.}
|
10
10
|
gem.summary = %q{Fluentd event collector}
|
11
|
-
gem.homepage = "https://fluentd.org/"
|
11
|
+
gem.homepage = "https://www.fluentd.org/"
|
12
12
|
|
13
13
|
gem.files = `git ls-files`.split($\)
|
14
14
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
@@ -384,7 +384,7 @@ module Fluent
|
|
384
384
|
end
|
385
385
|
# Overwrite by config_set_default
|
386
386
|
@defaults.each do |name, value|
|
387
|
-
if @params.key?(name) || @argument.first == name
|
387
|
+
if @params.key?(name) || (@argument && @argument.first == name)
|
388
388
|
dumped_config[name][:default] = value
|
389
389
|
else
|
390
390
|
dumped_config[name] = { default: value }
|
data/lib/fluent/config/dsl.rb
CHANGED
@@ -22,6 +22,8 @@ require 'fluent/config/element'
|
|
22
22
|
module Fluent
|
23
23
|
module Config
|
24
24
|
module DSL
|
25
|
+
RESERVED_PARAMETERS = [:type, :id, :log_level, :label] # Need '@' prefix for reserved parameters
|
26
|
+
|
25
27
|
module Parser
|
26
28
|
def self.read(path)
|
27
29
|
path = File.expand_path(path)
|
@@ -95,11 +97,12 @@ module Fluent
|
|
95
97
|
proxy.element.instance_exec(&block)
|
96
98
|
@elements.push(proxy.to_config_element)
|
97
99
|
else
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
100
|
+
param_name = RESERVED_PARAMETERS.include?(name) ? "@#{name}" : name.to_s
|
101
|
+
@attrs[param_name] = if value.is_a?(Array) || value.is_a?(Hash)
|
102
|
+
JSON.dump(value)
|
103
|
+
else
|
104
|
+
value.to_s
|
105
|
+
end
|
103
106
|
end
|
104
107
|
|
105
108
|
self
|
@@ -78,10 +78,16 @@ module Fluent::Plugin
|
|
78
78
|
@parser_json = parser_create(usage: 'parser_in_http_json', type: 'json')
|
79
79
|
@parser_json.estimate_current_event = false
|
80
80
|
@format_name = 'default'
|
81
|
+
@parser_time_key = if parser_config = conf.elements('parse').first
|
82
|
+
parser_config['time_key'] || 'time'
|
83
|
+
else
|
84
|
+
'time'
|
85
|
+
end
|
81
86
|
method(:parse_params_default)
|
82
87
|
else
|
83
88
|
@parser = parser_create
|
84
89
|
@format_name = @parser_configs.first['@type']
|
90
|
+
@parser_time_key = @parser.time_key
|
85
91
|
method(:parse_params_with_parser)
|
86
92
|
end
|
87
93
|
self.singleton_class.module_eval do
|
@@ -202,11 +208,18 @@ module Fluent::Plugin
|
|
202
208
|
if @add_remote_addr
|
203
209
|
single_record['REMOTE_ADDR'] = params['REMOTE_ADDR']
|
204
210
|
end
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
211
|
+
|
212
|
+
if defined? @parser
|
213
|
+
single_time = @parser.parse_time(single_record)
|
214
|
+
single_time, single_record = @parser.convert_values(single_time, single_record)
|
215
|
+
else
|
216
|
+
single_time = if t = single_record.delete(@parser_time_key)
|
217
|
+
Fluent::EventTime.from_time(Time.at(t))
|
218
|
+
else
|
219
|
+
time
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
210
223
|
mes.add(single_time, single_record)
|
211
224
|
end
|
212
225
|
router.emit_stream(tag, mes)
|
@@ -305,6 +318,7 @@ module Fluent::Plugin
|
|
305
318
|
end
|
306
319
|
@env = {}
|
307
320
|
@content_type = ""
|
321
|
+
@content_encoding = ""
|
308
322
|
headers.each_pair {|k,v|
|
309
323
|
@env["HTTP_#{k.gsub('-','_').upcase}"] = v
|
310
324
|
case k
|
@@ -314,6 +328,8 @@ module Fluent::Plugin
|
|
314
328
|
size = v.to_i
|
315
329
|
when /Content-Type/i
|
316
330
|
@content_type = v
|
331
|
+
when /Content-Encoding/i
|
332
|
+
@content_encoding = v
|
317
333
|
when /Connection/i
|
318
334
|
if v =~ /close/i
|
319
335
|
@keep_alive = false
|
@@ -365,6 +381,22 @@ module Fluent::Plugin
|
|
365
381
|
end
|
366
382
|
end
|
367
383
|
|
384
|
+
# Content Encoding
|
385
|
+
# =================
|
386
|
+
# Decode payload according to the "Content-Encoding" header.
|
387
|
+
# For now, we only support 'gzip' and 'deflate'.
|
388
|
+
begin
|
389
|
+
if @content_encoding == 'gzip'
|
390
|
+
@body = Zlib::GzipReader.new(StringIO.new(@body)).read
|
391
|
+
elsif @content_encoding == 'deflate'
|
392
|
+
@body = Zlib::Inflate.inflate(@body)
|
393
|
+
end
|
394
|
+
rescue
|
395
|
+
@log.warn 'fails to decode payload', error: $!.to_s
|
396
|
+
send_response_and_close("400 Bad Request", {}, "")
|
397
|
+
return
|
398
|
+
end
|
399
|
+
|
368
400
|
@env['REMOTE_ADDR'] = @remote_addr if @remote_addr
|
369
401
|
|
370
402
|
uri = URI.parse(@parser.request_url)
|
@@ -30,11 +30,17 @@ module Fluent::Plugin
|
|
30
30
|
|
31
31
|
helpers :timer, :thread
|
32
32
|
|
33
|
+
desc 'The address to bind to.'
|
33
34
|
config_param :bind, :string, default: '0.0.0.0'
|
35
|
+
desc 'The port to listen to.'
|
34
36
|
config_param :port, :integer, default: 24220
|
37
|
+
desc 'The tag with which internal metrics are emitted.'
|
35
38
|
config_param :tag, :string, default: nil
|
39
|
+
desc 'Determine the rate to emit internal metrics as events.'
|
36
40
|
config_param :emit_interval, :time, default: 60
|
41
|
+
desc 'Determine whether to include the config information.'
|
37
42
|
config_param :include_config, :bool, default: true
|
43
|
+
desc 'Determine whether to include the retry information.'
|
38
44
|
config_param :include_retry, :bool, default: true
|
39
45
|
|
40
46
|
class MonitorServlet < WEBrick::HTTPServlet::AbstractServlet
|
@@ -216,20 +216,24 @@ module Fluent::Plugin
|
|
216
216
|
path = date.strftime(path)
|
217
217
|
if path.include?('*')
|
218
218
|
paths += Dir.glob(path).select { |p|
|
219
|
-
|
220
|
-
|
221
|
-
if
|
222
|
-
|
219
|
+
begin
|
220
|
+
is_file = !File.directory?(p)
|
221
|
+
if File.readable?(p) && is_file
|
222
|
+
if @limit_recently_modified && File.mtime(p) < (date - @limit_recently_modified)
|
223
|
+
false
|
224
|
+
else
|
225
|
+
true
|
226
|
+
end
|
223
227
|
else
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
log.warn "#{p} unreadable. It is excluded and would be examined next time."
|
230
|
-
@ignore_list << path if @ignore_repeated_permission_error
|
228
|
+
if is_file
|
229
|
+
unless @ignore_list.include?(path)
|
230
|
+
log.warn "#{p} unreadable. It is excluded and would be examined next time."
|
231
|
+
@ignore_list << path if @ignore_repeated_permission_error
|
232
|
+
end
|
231
233
|
end
|
234
|
+
false
|
232
235
|
end
|
236
|
+
rescue Errno::ENOENT
|
233
237
|
false
|
234
238
|
end
|
235
239
|
}
|
@@ -27,8 +27,8 @@ module Fluent
|
|
27
27
|
REGEXP = /^(?<time>[^ ]*\s*[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[^ :\[]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
|
28
28
|
# From in_syslog default pattern
|
29
29
|
REGEXP_WITH_PRI = /^\<(?<pri>[0-9]+)\>(?<time>[^ ]* {1,2}[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[^ :\[]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
|
30
|
-
REGEXP_RFC5424 = /\A^(?<time>[^ ]+) (?<host>[^ ]+) (?<ident>[^ ]+) (?<pid
|
31
|
-
REGEXP_RFC5424_WITH_PRI = /\A^\<(?<pri>[0-9]{1,3})\>[1-9]\d{0,2} (?<time>[^ ]+) (?<host>[^ ]+) (?<ident>[^ ]+) (?<pid
|
30
|
+
REGEXP_RFC5424 = /\A^(?<time>[^ ]+) (?<host>[^ ]+) (?<ident>[^ ]+) (?<pid>.{1,128}) (?<msgid>[^ ]+) (?<extradata>(\[(.*)\]|[^ ])) (?<message>.+)$\z/
|
31
|
+
REGEXP_RFC5424_WITH_PRI = /\A^\<(?<pri>[0-9]{1,3})\>[1-9]\d{0,2} (?<time>[^ ]+) (?<host>[^ ]+) (?<ident>[^ ]+) (?<pid>.{1,128}) (?<msgid>[^ ]+) (?<extradata>(\[(.*)\]|[^ ])) (?<message>.+)$\z/
|
32
32
|
REGEXP_DETECT_RFC5424 = /^\<.*\>[1-9]\d{0,2}/
|
33
33
|
|
34
34
|
config_set_default :time_format, "%b %d %H:%M:%S"
|
data/lib/fluent/version.rb
CHANGED
@@ -6,10 +6,10 @@ module Fluent
|
|
6
6
|
module Plugin
|
7
7
|
class <%= class_name %> < Fluent::Plugin::Parser
|
8
8
|
Fluent::Plugin.register_parser("<%= plugin_name %>", self)
|
9
|
-
end
|
10
9
|
|
11
|
-
|
12
|
-
|
10
|
+
def parse(text)
|
11
|
+
yield time, record
|
12
|
+
end
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
data/test/config/test_dsl.rb
CHANGED
@@ -176,7 +176,7 @@ module Fluent::Config
|
|
176
176
|
assert_equal('source', ele4.name)
|
177
177
|
assert_predicate(ele4.arg, :empty?)
|
178
178
|
assert_equal(2, ele4.keys.size)
|
179
|
-
assert_equal('tail', ele4['type'])
|
179
|
+
assert_equal('tail', ele4['@type'])
|
180
180
|
assert_equal("/var/log/httpd/access.part4.log", ele4['path'])
|
181
181
|
end
|
182
182
|
|
@@ -185,11 +185,11 @@ module Fluent::Config
|
|
185
185
|
|
186
186
|
assert_equal('filter', filter0.name)
|
187
187
|
assert_equal('bar.**', filter0.arg)
|
188
|
-
assert_equal('hoge', filter0['type'])
|
188
|
+
assert_equal('hoge', filter0['@type'])
|
189
189
|
assert_equal('moge', filter0['val1'])
|
190
190
|
assert_equal(JSON.dump(['foo', 'bar', 'baz']), filter0['val2'])
|
191
191
|
assert_equal('10', filter0['val3'])
|
192
|
-
assert_equal('hoge', filter0['id'])
|
192
|
+
assert_equal('hoge', filter0['@id'])
|
193
193
|
|
194
194
|
assert_equal(2, filter0.elements.size)
|
195
195
|
assert_equal('subsection', filter0.elements[0].name)
|
@@ -203,7 +203,7 @@ module Fluent::Config
|
|
203
203
|
|
204
204
|
assert_equal('match', match0.name)
|
205
205
|
assert_equal('{foo,bar}.**', match0.arg)
|
206
|
-
assert_equal('file', match0['type'])
|
206
|
+
assert_equal('file', match0['@type'])
|
207
207
|
assert_equal('/var/log/httpd/access.myhostname.4.log', match0['path'])
|
208
208
|
end
|
209
209
|
end
|
@@ -302,7 +302,7 @@ module Fluent::Config
|
|
302
302
|
assert_equal('source', ele4.name)
|
303
303
|
assert_predicate(ele4.arg, :empty?)
|
304
304
|
assert_equal(2, ele4.keys.size)
|
305
|
-
assert_equal('tail', ele4['type'])
|
305
|
+
assert_equal('tail', ele4['@type'])
|
306
306
|
assert_equal("/var/log/httpd/access.part4.log", ele4['path'])
|
307
307
|
end
|
308
308
|
|
@@ -311,11 +311,11 @@ module Fluent::Config
|
|
311
311
|
|
312
312
|
assert_equal('filter', filter0.name)
|
313
313
|
assert_equal('bar.**', filter0.arg)
|
314
|
-
assert_equal('hoge', filter0['type'])
|
314
|
+
assert_equal('hoge', filter0['@type'])
|
315
315
|
assert_equal('moge', filter0['val1'])
|
316
316
|
assert_equal(JSON.dump(['foo', 'bar', 'baz']), filter0['val2'])
|
317
317
|
assert_equal('10', filter0['val3'])
|
318
|
-
assert_equal('hoge', filter0['id'])
|
318
|
+
assert_equal('hoge', filter0['@id'])
|
319
319
|
|
320
320
|
assert_equal(2, filter0.elements.size)
|
321
321
|
assert_equal('subsection', filter0.elements[0].name)
|
@@ -329,7 +329,7 @@ module Fluent::Config
|
|
329
329
|
|
330
330
|
assert_equal('match', match0.name)
|
331
331
|
assert_equal('{foo,bar}.**', match0.arg)
|
332
|
-
assert_equal('file', match0['type'])
|
332
|
+
assert_equal('file', match0['@type'])
|
333
333
|
assert_equal('/var/log/httpd/access.myhostname.4.log', match0['path'])
|
334
334
|
end
|
335
335
|
end
|
data/test/counter/test_client.rb
CHANGED
@@ -64,6 +64,12 @@ class CounterClientTest < ::Test::Unit::TestCase
|
|
64
64
|
store[key]
|
65
65
|
end
|
66
66
|
|
67
|
+
def travel(sec)
|
68
|
+
# Since Timecop.travel() causes test failures on Windows/AppVeyor by inducing
|
69
|
+
# rounding errors to Time.now, we need to use Timecop.freeze() instead.
|
70
|
+
Timecop.freeze(Time.now + sec)
|
71
|
+
end
|
72
|
+
|
67
73
|
sub_test_case 'establish' do
|
68
74
|
test 'establish a scope' do
|
69
75
|
@client.establish(@scope)
|
@@ -277,7 +283,7 @@ class CounterClientTest < ::Test::Unit::TestCase
|
|
277
283
|
assert_equal 0, v['total']
|
278
284
|
assert_equal 0, v['current']
|
279
285
|
|
280
|
-
|
286
|
+
travel(1)
|
281
287
|
inc_obj = { name: @name, value: 10 }
|
282
288
|
@client.inc(inc_obj).get
|
283
289
|
|
@@ -444,7 +450,7 @@ class CounterClientTest < ::Test::Unit::TestCase
|
|
444
450
|
assert_equal @now, Fluent::EventTime.new(*v1['last_reset_at'])
|
445
451
|
|
446
452
|
travel_sec = 6 # greater than reset_interval
|
447
|
-
|
453
|
+
travel(travel_sec)
|
448
454
|
|
449
455
|
v2 = @client.reset(@name).get
|
450
456
|
data = v2.data.first
|
@@ -472,7 +478,7 @@ class CounterClientTest < ::Test::Unit::TestCase
|
|
472
478
|
assert_equal @now, Fluent::EventTime.new(*v1['last_reset_at'])
|
473
479
|
|
474
480
|
travel_sec = 4 # less than reset_interval
|
475
|
-
|
481
|
+
travel(travel_sec)
|
476
482
|
|
477
483
|
v2 = @client.reset(@name).get
|
478
484
|
data = v2.data.first
|
@@ -520,7 +526,7 @@ class CounterClientTest < ::Test::Unit::TestCase
|
|
520
526
|
unknown_name = 'key2'
|
521
527
|
|
522
528
|
travel_sec = 6 # greater than reset_interval
|
523
|
-
|
529
|
+
travel(travel_sec)
|
524
530
|
|
525
531
|
response = @client.reset(@name, unknown_name).get
|
526
532
|
data = response.data.first
|
data/test/counter/test_server.rb
CHANGED
@@ -28,6 +28,12 @@ class CounterServerTest < ::Test::Unit::TestCase
|
|
28
28
|
store[key]
|
29
29
|
end
|
30
30
|
|
31
|
+
def travel(sec)
|
32
|
+
# Since Timecop.travel() causes test failures on Windows/AppVeyor by inducing
|
33
|
+
# rounding errors to Time.now, we need to use Timecop.freeze() instead.
|
34
|
+
Timecop.freeze(Time.now + sec)
|
35
|
+
end
|
36
|
+
|
31
37
|
test 'raise an error when server name is invalid' do
|
32
38
|
assert_raise do
|
33
39
|
Fluent::Counter::Server.new("\tinvalid_name")
|
@@ -387,7 +393,7 @@ class CounterServerTest < ::Test::Unit::TestCase
|
|
387
393
|
end
|
388
394
|
|
389
395
|
test 'reset a value in the counter' do
|
390
|
-
|
396
|
+
travel(@travel_sec)
|
391
397
|
|
392
398
|
result = @server.send('reset', [@name], @scope, {})
|
393
399
|
assert_nil result['errors']
|
@@ -412,7 +418,7 @@ class CounterServerTest < ::Test::Unit::TestCase
|
|
412
418
|
|
413
419
|
test 'reset a value after `reset_interval` passed' do
|
414
420
|
first_travel_sec = 5
|
415
|
-
|
421
|
+
travel(first_travel_sec) # jump time less than reset_interval
|
416
422
|
result = @server.send('reset', [@name], @scope, {})
|
417
423
|
v = result['data'].first
|
418
424
|
|
@@ -424,7 +430,7 @@ class CounterServerTest < ::Test::Unit::TestCase
|
|
424
430
|
assert_equal @now, Fluent::EventTime.new(*store['last_reset_at'])
|
425
431
|
|
426
432
|
# time is passed greater than reset_interval
|
427
|
-
|
433
|
+
travel(@travel_sec)
|
428
434
|
result = @server.send('reset', [@name], @scope, {})
|
429
435
|
v = result['data'].first
|
430
436
|
|
data/test/counter/test_store.rb
CHANGED
@@ -23,6 +23,12 @@ class CounterStoreTest < ::Test::Unit::TestCase
|
|
23
23
|
store[key]
|
24
24
|
end
|
25
25
|
|
26
|
+
def travel(sec)
|
27
|
+
# Since Timecop.travel() causes test failures on Windows/AppVeyor by inducing
|
28
|
+
# rounding errors to Time.now, we need to use Timecop.freeze() instead.
|
29
|
+
Timecop.freeze(Time.now + sec)
|
30
|
+
end
|
31
|
+
|
26
32
|
sub_test_case 'init' do
|
27
33
|
setup do
|
28
34
|
@reset_interval = 10
|
@@ -142,7 +148,7 @@ class CounterStoreTest < ::Test::Unit::TestCase
|
|
142
148
|
test 'increment or decrement a value in the counter' do |value|
|
143
149
|
key = Fluent::Counter::Store.gen_key(@scope, @name)
|
144
150
|
@store.init(key, @init_data)
|
145
|
-
|
151
|
+
travel(@travel_sec)
|
146
152
|
v = @store.inc(key, { 'value' => value })
|
147
153
|
|
148
154
|
assert_equal value, v['total']
|
@@ -198,7 +204,7 @@ class CounterStoreTest < ::Test::Unit::TestCase
|
|
198
204
|
end
|
199
205
|
|
200
206
|
test 'reset a value in the counter' do
|
201
|
-
|
207
|
+
travel(@travel_sec)
|
202
208
|
|
203
209
|
v = @store.reset(@key)
|
204
210
|
assert_equal @travel_sec, v['elapsed_time']
|
@@ -222,7 +228,7 @@ class CounterStoreTest < ::Test::Unit::TestCase
|
|
222
228
|
|
223
229
|
test 'reset a value after `reset_interval` passed' do
|
224
230
|
first_travel_sec = 5
|
225
|
-
|
231
|
+
travel(first_travel_sec) # jump time less than reset_interval
|
226
232
|
v = @store.reset(@key)
|
227
233
|
|
228
234
|
assert_equal false, v['success']
|
@@ -232,7 +238,7 @@ class CounterStoreTest < ::Test::Unit::TestCase
|
|
232
238
|
assert_equal @now, Fluent::EventTime.new(*store['last_reset_at'])
|
233
239
|
|
234
240
|
# time is passed greater than reset_interval
|
235
|
-
|
241
|
+
travel(@travel_sec)
|
236
242
|
v = @store.reset(@key)
|
237
243
|
assert_true v['success']
|
238
244
|
assert_equal @travel_sec + first_travel_sec, v['elapsed_time']
|
data/test/plugin/test_in_http.rb
CHANGED
@@ -162,6 +162,29 @@ class HttpInputTest < Test::Unit::TestCase
|
|
162
162
|
assert_equal_event_time time, d.events[1][1]
|
163
163
|
end
|
164
164
|
|
165
|
+
def test_multi_json_with_nonexistent_time_key
|
166
|
+
d = create_driver(CONFIG + %[
|
167
|
+
<parse>
|
168
|
+
time_key missing
|
169
|
+
</parse>
|
170
|
+
])
|
171
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
172
|
+
time_i = time.to_i
|
173
|
+
time_f = time.to_f
|
174
|
+
|
175
|
+
records = [{"a" => 1, 'time' => time_i},{"a" => 2, 'time' => time_f}]
|
176
|
+
tag = "tag1"
|
177
|
+
res_codes = []
|
178
|
+
d.run(expect_records: 2, timeout: 5) do
|
179
|
+
res = post("/#{tag}", {"json" => records.to_json})
|
180
|
+
res_codes << res.code
|
181
|
+
end
|
182
|
+
assert_equal ["200"], res_codes
|
183
|
+
assert_equal 2, d.events.size
|
184
|
+
assert_not_equal time_i, d.events[0][1].sec # current time is used because "missing" field doesn't exist
|
185
|
+
assert_not_equal time_i, d.events[1][1].sec
|
186
|
+
end
|
187
|
+
|
165
188
|
def test_json_with_add_remote_addr
|
166
189
|
d = create_driver(CONFIG + "add_remote_addr true")
|
167
190
|
time = event_time("2011-01-02 13:14:15 UTC")
|
@@ -347,6 +370,38 @@ class HttpInputTest < Test::Unit::TestCase
|
|
347
370
|
assert include_http_header?(d.events[1][2])
|
348
371
|
end
|
349
372
|
|
373
|
+
def test_multi_json_with_custom_parser
|
374
|
+
d = create_driver(CONFIG + %[
|
375
|
+
<parse>
|
376
|
+
@type json
|
377
|
+
keep_time_key true
|
378
|
+
time_key foo
|
379
|
+
time_format %iso8601
|
380
|
+
</parse>
|
381
|
+
])
|
382
|
+
|
383
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
384
|
+
time_s = Time.at(time).iso8601
|
385
|
+
|
386
|
+
records = [{"foo"=>time_s,"bar"=>"test1"},{"foo"=>time_s,"bar"=>"test2"}]
|
387
|
+
tag = "tag1"
|
388
|
+
res_codes = []
|
389
|
+
|
390
|
+
d.run(expect_records: 2, timeout: 5) do
|
391
|
+
res = post("/#{tag}", records.to_json, {"Content-Type"=>"application/octet-stream"})
|
392
|
+
res_codes << res.code
|
393
|
+
end
|
394
|
+
assert_equal ["200"], res_codes
|
395
|
+
|
396
|
+
assert_equal "tag1", d.events[0][0]
|
397
|
+
assert_equal_event_time time, d.events[0][1]
|
398
|
+
assert_equal d.events[0][2], records[0]
|
399
|
+
|
400
|
+
assert_equal "tag1", d.events[1][0]
|
401
|
+
assert_equal_event_time time, d.events[1][1]
|
402
|
+
assert_equal d.events[1][2], records[1]
|
403
|
+
end
|
404
|
+
|
350
405
|
def test_application_json
|
351
406
|
d = create_driver
|
352
407
|
time = event_time("2011-01-02 13:14:15 UTC")
|
@@ -549,6 +604,54 @@ class HttpInputTest < Test::Unit::TestCase
|
|
549
604
|
assert_equal_event_time time, d.events[1][1]
|
550
605
|
end
|
551
606
|
|
607
|
+
def test_content_encoding_gzip
|
608
|
+
d = create_driver
|
609
|
+
|
610
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
611
|
+
events = [
|
612
|
+
["tag1", time, {"a"=>1}],
|
613
|
+
["tag2", time, {"a"=>2}],
|
614
|
+
]
|
615
|
+
res_codes = []
|
616
|
+
res_headers = []
|
617
|
+
|
618
|
+
d.run do
|
619
|
+
events.each do |tag, time, record|
|
620
|
+
header = {'Content-Type'=>'application/json', 'Content-Encoding'=>'gzip'}
|
621
|
+
res = post("/#{tag}?time=#{time}", compress_gzip(record.to_json), header)
|
622
|
+
res_codes << res.code
|
623
|
+
end
|
624
|
+
end
|
625
|
+
assert_equal ["200", "200"], res_codes
|
626
|
+
assert_equal events, d.events
|
627
|
+
assert_equal_event_time time, d.events[0][1]
|
628
|
+
assert_equal_event_time time, d.events[1][1]
|
629
|
+
end
|
630
|
+
|
631
|
+
def test_content_encoding_deflate
|
632
|
+
d = create_driver
|
633
|
+
|
634
|
+
time = event_time("2011-01-02 13:14:15 UTC")
|
635
|
+
events = [
|
636
|
+
["tag1", time, {"a"=>1}],
|
637
|
+
["tag2", time, {"a"=>2}],
|
638
|
+
]
|
639
|
+
res_codes = []
|
640
|
+
res_headers = []
|
641
|
+
|
642
|
+
d.run do
|
643
|
+
events.each do |tag, time, record|
|
644
|
+
header = {'Content-Type'=>'application/msgpack', 'Content-Encoding'=>'deflate'}
|
645
|
+
res = post("/#{tag}?time=#{time}", Zlib.deflate(record.to_msgpack), header)
|
646
|
+
res_codes << res.code
|
647
|
+
end
|
648
|
+
end
|
649
|
+
assert_equal ["200", "200"], res_codes
|
650
|
+
assert_equal events, d.events
|
651
|
+
assert_equal_event_time time, d.events[0][1]
|
652
|
+
assert_equal_event_time time, d.events[1][1]
|
653
|
+
end
|
654
|
+
|
552
655
|
def test_cors_disallowed
|
553
656
|
d = create_driver(CONFIG + "cors_allow_origins [\"http://foo.com\"]")
|
554
657
|
assert_equal ["http://foo.com"], d.instance.cors_allow_origins
|
@@ -639,6 +742,13 @@ class HttpInputTest < Test::Unit::TestCase
|
|
639
742
|
http.request(req)
|
640
743
|
end
|
641
744
|
|
745
|
+
def compress_gzip(data)
|
746
|
+
io = StringIO.new
|
747
|
+
io.binmode
|
748
|
+
Zlib::GzipWriter.wrap(io) { |gz| gz.write data }
|
749
|
+
return io.string
|
750
|
+
end
|
751
|
+
|
642
752
|
def include_http_header?(record)
|
643
753
|
record.keys.find { |header| header.start_with?('HTTP_') }
|
644
754
|
end
|
@@ -304,7 +304,11 @@ class FileOutputTest < Test::Unit::TestCase
|
|
304
304
|
assert_equal r4, d.formatted[3]
|
305
305
|
assert_equal r5, d.formatted[4]
|
306
306
|
|
307
|
-
read_gunzip = ->(path){
|
307
|
+
read_gunzip = ->(path){
|
308
|
+
File.open(path){ |fio|
|
309
|
+
Zlib::GzipReader.new(StringIO.new(fio.read)).read
|
310
|
+
}
|
311
|
+
}
|
308
312
|
assert_equal r1 + r2, read_gunzip.call("#{TMP_DIR}/my.data/a/full.20161003.2345.log.gz")
|
309
313
|
assert_equal r3, read_gunzip.call("#{TMP_DIR}/your.data/a/full.20161003.2345.log.gz")
|
310
314
|
assert_equal r4, read_gunzip.call("#{TMP_DIR}/my.data/a/full.20161004.0000.log.gz")
|
@@ -370,7 +374,7 @@ class FileOutputTest < Test::Unit::TestCase
|
|
370
374
|
result = ''
|
371
375
|
File.open(path, "rb") { |io|
|
372
376
|
loop do
|
373
|
-
gzr = Zlib::GzipReader.new(io)
|
377
|
+
gzr = Zlib::GzipReader.new(StringIO.new(io.read))
|
374
378
|
result << gzr.read
|
375
379
|
unused = gzr.unused
|
376
380
|
gzr.finish
|
@@ -422,7 +422,7 @@ class RetryStateHelperTest < Test::Unit::TestCase
|
|
422
422
|
|
423
423
|
sub_test_case 'exponential backoff' do
|
424
424
|
test 'too big steps(check inf handling)' do
|
425
|
-
s = @d.retry_state_create(:t11, :exponential_backoff,
|
425
|
+
s = @d.retry_state_create(:t11, :exponential_backoff, 1, 300, randomize: false, forever: true, backoff_base: 2)
|
426
426
|
dummy_current_time = s.start
|
427
427
|
override_current_time(s, dummy_current_time)
|
428
428
|
|
@@ -431,7 +431,7 @@ class RetryStateHelperTest < Test::Unit::TestCase
|
|
431
431
|
if i >= 1025
|
432
432
|
# With this setting, 1025+ number causes inf in `calc_interval`, so 1024 value is used for next_time
|
433
433
|
assert_nothing_raised(FloatDomainError) { s.step }
|
434
|
-
assert_equal (dummy_current_time +
|
434
|
+
assert_equal (dummy_current_time + (2 ** (1024 - 1))), s.next_time
|
435
435
|
else
|
436
436
|
s.step
|
437
437
|
end
|
data/test/test_configdsl.rb
CHANGED
@@ -65,13 +65,13 @@ match('aa')
|
|
65
65
|
e0 = root.elements[0]
|
66
66
|
assert_equal 'source', e0.name
|
67
67
|
assert_equal '', e0.arg
|
68
|
-
assert_equal 'forward', e0['type']
|
68
|
+
assert_equal 'forward', e0['@type']
|
69
69
|
assert_equal '24224', e0['port']
|
70
70
|
|
71
71
|
e1 = root.elements[1]
|
72
72
|
assert_equal 'match', e1.name
|
73
73
|
assert_equal 'test.**', e1.arg
|
74
|
-
assert_equal 'forward', e1['type']
|
74
|
+
assert_equal 'forward', e1['@type']
|
75
75
|
assert_equal '1s', e1['flush_interval']
|
76
76
|
assert_equal 2, e1.elements.size
|
77
77
|
e1s0 = e1.elements[0]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluentd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sadayuki Furuhashi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-07-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: msgpack
|
@@ -749,7 +749,7 @@ files:
|
|
749
749
|
- test/test_time_formatter.rb
|
750
750
|
- test/test_time_parser.rb
|
751
751
|
- test/test_unique_id.rb
|
752
|
-
homepage: https://fluentd.org/
|
752
|
+
homepage: https://www.fluentd.org/
|
753
753
|
licenses:
|
754
754
|
- Apache-2.0
|
755
755
|
metadata: {}
|