fluentd 1.11.0-x86-mingw32 → 1.11.5-x86-mingw32

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.

Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +92 -1
  3. data/example/copy_roundrobin.conf +3 -3
  4. data/example/counter.conf +1 -1
  5. data/example/filter_stdout.conf +2 -2
  6. data/example/{in_dummy_blocks.conf → in_sample_blocks.conf} +4 -4
  7. data/example/{in_dummy_with_compression.conf → in_sample_with_compression.conf} +3 -3
  8. data/example/logevents.conf +5 -5
  9. data/example/multi_filters.conf +1 -1
  10. data/example/out_exec_filter.conf +2 -2
  11. data/example/out_forward.conf +1 -1
  12. data/example/out_forward_buf_file.conf +1 -1
  13. data/example/out_forward_client.conf +5 -5
  14. data/example/out_forward_heartbeat_none.conf +1 -1
  15. data/example/out_forward_sd.conf +1 -1
  16. data/example/out_forward_shared_key.conf +2 -2
  17. data/example/out_forward_tls.conf +1 -1
  18. data/example/out_forward_users.conf +3 -3
  19. data/example/out_null.conf +4 -4
  20. data/example/secondary_file.conf +1 -1
  21. data/fluentd.gemspec +6 -6
  22. data/lib/fluent/command/fluentd.rb +11 -0
  23. data/lib/fluent/log.rb +33 -3
  24. data/lib/fluent/match.rb +9 -0
  25. data/lib/fluent/plugin/buffer.rb +49 -40
  26. data/lib/fluent/plugin/buffer/chunk.rb +2 -1
  27. data/lib/fluent/plugin/formatter.rb +24 -0
  28. data/lib/fluent/plugin/formatter_hash.rb +3 -1
  29. data/lib/fluent/plugin/formatter_json.rb +3 -1
  30. data/lib/fluent/plugin/formatter_ltsv.rb +3 -1
  31. data/lib/fluent/plugin/formatter_out_file.rb +3 -1
  32. data/lib/fluent/plugin/formatter_single_value.rb +3 -1
  33. data/lib/fluent/plugin/formatter_tsv.rb +3 -1
  34. data/lib/fluent/plugin/in_dummy.rb +2 -123
  35. data/lib/fluent/plugin/in_exec.rb +4 -2
  36. data/lib/fluent/plugin/in_http.rb +148 -77
  37. data/lib/fluent/plugin/in_sample.rb +141 -0
  38. data/lib/fluent/plugin/in_tail.rb +2 -2
  39. data/lib/fluent/plugin/out_http.rb +20 -2
  40. data/lib/fluent/plugin/output.rb +8 -5
  41. data/lib/fluent/plugin/parser_json.rb +5 -2
  42. data/lib/fluent/plugin_helper/cert_option.rb +5 -8
  43. data/lib/fluent/plugin_helper/child_process.rb +3 -2
  44. data/lib/fluent/plugin_helper/inject.rb +2 -1
  45. data/lib/fluent/plugin_helper/socket.rb +1 -1
  46. data/lib/fluent/supervisor.rb +11 -6
  47. data/lib/fluent/system_config.rb +2 -1
  48. data/lib/fluent/version.rb +1 -1
  49. data/test/command/test_binlog_reader.rb +22 -6
  50. data/test/plugin/test_buffer.rb +4 -0
  51. data/test/plugin/test_filter_stdout.rb +6 -1
  52. data/test/plugin/test_formatter_hash.rb +6 -3
  53. data/test/plugin/test_formatter_json.rb +14 -4
  54. data/test/plugin/test_formatter_ltsv.rb +13 -5
  55. data/test/plugin/test_formatter_out_file.rb +35 -14
  56. data/test/plugin/test_formatter_single_value.rb +12 -6
  57. data/test/plugin/test_formatter_tsv.rb +12 -4
  58. data/test/plugin/test_in_exec.rb +18 -0
  59. data/test/plugin/test_in_http.rb +57 -0
  60. data/test/plugin/{test_in_dummy.rb → test_in_sample.rb} +25 -25
  61. data/test/plugin/test_in_tail.rb +3 -0
  62. data/test/plugin/test_out_file.rb +23 -18
  63. data/test/plugin/test_output.rb +12 -0
  64. data/test/plugin_helper/data/cert/empty.pem +0 -0
  65. data/test/plugin_helper/test_cert_option.rb +7 -0
  66. data/test/plugin_helper/test_child_process.rb +15 -0
  67. data/test/plugin_helper/test_compat_parameters.rb +7 -2
  68. data/test/plugin_helper/test_http_server_helper.rb +5 -0
  69. data/test/plugin_helper/test_inject.rb +13 -0
  70. data/test/plugin_helper/test_server.rb +34 -0
  71. data/test/plugin_helper/test_socket.rb +8 -0
  72. data/test/test_formatter.rb +34 -10
  73. data/test/test_log.rb +44 -0
  74. data/test/test_match.rb +11 -0
  75. data/test/test_output.rb +6 -1
  76. data/test/test_static_config_analysis.rb +2 -2
  77. data/test/test_supervisor.rb +26 -0
  78. metadata +21 -18
@@ -271,9 +271,9 @@ module Fluent::Plugin
271
271
  end
272
272
  else
273
273
  if is_file
274
- unless @ignore_list.include?(path)
274
+ unless @ignore_list.include?(p)
275
275
  log.warn "#{p} unreadable. It is excluded and would be examined next time."
276
- @ignore_list << path if @ignore_repeated_permission_error
276
+ @ignore_list << p if @ignore_repeated_permission_error
277
277
  end
278
278
  end
279
279
  false
@@ -21,6 +21,16 @@ require 'fluent/tls'
21
21
  require 'fluent/plugin/output'
22
22
  require 'fluent/plugin_helper/socket'
23
23
 
24
+ # patch Net::HTTP to support extra_chain_cert which was added in Ruby feature #9758.
25
+ # see: https://github.com/ruby/ruby/commit/31af0dafba6d3769d2a39617c0dddedb97883712
26
+ unless Net::HTTP::SSL_IVNAMES.include?(:@extra_chain_cert)
27
+ class Net::HTTP
28
+ SSL_IVNAMES << :@extra_chain_cert
29
+ SSL_ATTRIBUTES << :extra_chain_cert
30
+ attr_accessor :extra_chain_cert
31
+ end
32
+ end
33
+
24
34
  module Fluent::Plugin
25
35
  class HTTPOutput < Output
26
36
  Fluent::Plugin.register_output('http', self)
@@ -171,7 +181,15 @@ module Fluent::Plugin
171
181
  end
172
182
  if @tls_client_cert_path
173
183
  raise Fluent::ConfigError, "tls_client_cert_path is wrong: #{@tls_client_cert_path}" unless File.file?(@tls_client_cert_path)
174
- opt[:cert] = OpenSSL::X509::Certificate.new(File.read(@tls_client_cert_path))
184
+
185
+ bundle = File.read(@tls_client_cert_path)
186
+ bundle_certs = bundle.scan(/-----BEGIN CERTIFICATE-----(?:.|\n)+?-----END CERTIFICATE-----/)
187
+ opt[:cert] = OpenSSL::X509::Certificate.new(bundle_certs[0])
188
+
189
+ intermediate_certs = bundle_certs[1..-1]
190
+ if intermediate_certs
191
+ opt[:extra_chain_cert] = intermediate_certs.map { |cert| OpenSSL::X509::Certificate.new(cert) }
192
+ end
175
193
  end
176
194
  if @tls_private_key_path
177
195
  raise Fluent::ConfigError, "tls_private_key_path is wrong: #{@tls_private_key_path}" unless File.file?(@tls_private_key_path)
@@ -215,7 +233,7 @@ module Fluent::Plugin
215
233
  req.basic_auth(@auth.username, @auth.password)
216
234
  end
217
235
  set_headers(req)
218
- req.body = @json_array ? "[#{chunk.read.chop!}]" : chunk.read
236
+ req.body = @json_array ? "[#{chunk.read.chop}]" : chunk.read
219
237
  req
220
238
  end
221
239
 
@@ -340,6 +340,7 @@ module Fluent
340
340
  buffer_conf = conf.elements(name: 'buffer').first || Fluent::Config::Element.new('buffer', '', {}, [])
341
341
  @buffer = Plugin.new_buffer(buffer_type, parent: self)
342
342
  @buffer.configure(buffer_conf)
343
+ @buffer.enable_update_timekeys if @chunk_key_time
343
344
 
344
345
  @flush_at_shutdown = @buffer_config.flush_at_shutdown
345
346
  if @flush_at_shutdown.nil?
@@ -768,17 +769,19 @@ module Fluent
768
769
  end
769
770
  end
770
771
 
771
- if rvalue =~ CHUNK_KEY_PLACEHOLDER_PATTERN
772
- log.warn "chunk key placeholder '#{$1}' not replaced. template:#{str}"
773
- end
774
-
775
- rvalue.sub(CHUNK_ID_PLACEHOLDER_PATTERN) {
772
+ rvalue = rvalue.sub(CHUNK_ID_PLACEHOLDER_PATTERN) {
776
773
  if chunk_passed
777
774
  dump_unique_id_hex(chunk.unique_id)
778
775
  else
779
776
  log.warn "${chunk_id} is not allowed in this plugin. Pass Chunk instead of metadata in extract_placeholders's 2nd argument"
780
777
  end
781
778
  }
779
+
780
+ if rvalue =~ CHUNK_KEY_PLACEHOLDER_PATTERN
781
+ log.warn "chunk key placeholder '#{$1}' not replaced. template:#{str}"
782
+ end
783
+
784
+ rvalue
782
785
  end
783
786
  end
784
787
 
@@ -71,8 +71,11 @@ module Fluent
71
71
  end
72
72
 
73
73
  def parse(text)
74
- r = @load_proc.call(text)
75
- time, record = convert_values(parse_time(r), r)
74
+ record = @load_proc.call(text)
75
+ time = parse_time(record)
76
+ if @execute_convert_values
77
+ time, record = convert_values(time, record)
78
+ end
76
79
  yield time, record
77
80
  rescue @error_class, EncodingError # EncodingError is for oj 3.x or later
78
81
  yield nil, nil
@@ -27,13 +27,9 @@ module Fluent
27
27
  cert, key, extra = cert_option_server_validate!(conf)
28
28
 
29
29
  ctx = OpenSSL::SSL::SSLContext.new
30
- unless insecure
31
- # inject OpenSSL::SSL::SSLContext::DEFAULT_PARAMS
32
- # https://bugs.ruby-lang.org/issues/9424
33
- ctx.set_params({})
34
-
35
- ctx.ciphers = ciphers
36
- end
30
+ # inject OpenSSL::SSL::SSLContext::DEFAULT_PARAMS
31
+ # https://bugs.ruby-lang.org/issues/9424
32
+ ctx.set_params({}) unless insecure
37
33
 
38
34
  if conf.client_cert_auth
39
35
  ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
@@ -56,6 +52,7 @@ module Fluent
56
52
  end
57
53
 
58
54
  Fluent::TLS.set_version_to_context(ctx, version, conf.min_version, conf.max_version)
55
+ ctx.ciphers = ciphers unless insecure
59
56
 
60
57
  ctx
61
58
  end
@@ -185,7 +182,7 @@ module Fluent
185
182
  list = []
186
183
  data.scan(pattern){|match| list << OpenSSL::X509::Certificate.new(match) }
187
184
  if list.length == 0
188
- log.warn "cert_path does not contain a valid certificate"
185
+ raise Fluent::ConfigError, "cert_path does not contain a valid certificate"
189
186
  end
190
187
  list
191
188
  end
@@ -259,6 +259,9 @@ module Fluent
259
259
 
260
260
  if !mode.include?(:stderr) && !mode.include?(:read_with_stderr)
261
261
  spawn_opts[:err] = IO::NULL if stderr == :discard
262
+ if !mode.include?(:read) && !mode.include?(:read_with_stderr)
263
+ spawn_opts[:out] = IO::NULL
264
+ end
262
265
  writeio, readio, wait_thread = *Open3.popen2(*spawn_args, spawn_opts)
263
266
  elsif mode.include?(:read_with_stderr)
264
267
  writeio, readio, wait_thread = *Open3.popen2e(*spawn_args, spawn_opts)
@@ -275,8 +278,6 @@ module Fluent
275
278
  if mode.include?(:read) || mode.include?(:read_with_stderr)
276
279
  readio.set_encoding(external_encoding, internal_encoding, **encoding_options)
277
280
  readio_in_use = true
278
- else
279
- readio.reopen(IO::NULL) if readio
280
281
  end
281
282
  if mode.include?(:stderr)
282
283
  stderrio.set_encoding(external_encoding, internal_encoding, **encoding_options)
@@ -76,7 +76,7 @@ module Fluent
76
76
  config_param :time_key, :string, default: nil
77
77
 
78
78
  # To avoid defining :time_type twice
79
- config_param :time_type, :enum, list: [:float, :unixtime, :string], default: :float
79
+ config_param :time_type, :enum, list: [:float, :unixtime, :unixtime_millis, :string], default: :float
80
80
 
81
81
  Fluent::TimeMixin::TIME_PARAMETERS.each do |name, type, opts|
82
82
  config_param(name, type, **opts)
@@ -132,6 +132,7 @@ module Fluent
132
132
  if @_inject_time_key
133
133
  @_inject_time_formatter = case @inject_config.time_type
134
134
  when :float then ->(time){ time.to_r.truncate(+6).to_f } # microsecond floating point value
135
+ when :unixtime_millis then ->(time) { time.to_f.floor(3) * 1000 }
135
136
  when :unixtime then ->(time){ time.to_i }
136
137
  else
137
138
  localtime = @inject_config.localtime && !@inject_config.utc
@@ -199,7 +199,7 @@ module Fluent
199
199
  list = []
200
200
  data.scan(pattern) { |match| list << OpenSSL::X509::Certificate.new(match) }
201
201
  if list.length == 0
202
- log.warn "cert_path does not contain a valid certificate"
202
+ raise Fluent::ConfigError, "cert_path does not contain a valid certificate"
203
203
  end
204
204
  list
205
205
  end
@@ -183,7 +183,6 @@ module Fluent
183
183
  until WaitForSingleObject(ev.handle, 0) == WAIT_OBJECT_0
184
184
  sleep 1
185
185
  end
186
- kill_worker
187
186
  stop(true)
188
187
  ensure
189
188
  ev.close
@@ -302,6 +301,7 @@ module Fluent
302
301
  log_level = params['log_level']
303
302
  suppress_repeated_stacktrace = params['suppress_repeated_stacktrace']
304
303
  ignore_repeated_log_interval = params['ignore_repeated_log_interval']
304
+ ignore_same_log_interval = params['ignore_same_log_interval']
305
305
 
306
306
  log_path = params['log_path']
307
307
  chuser = params['chuser']
@@ -309,7 +309,8 @@ module Fluent
309
309
  log_rotate_age = params['log_rotate_age']
310
310
  log_rotate_size = params['log_rotate_size']
311
311
 
312
- log_opts = {suppress_repeated_stacktrace: suppress_repeated_stacktrace, ignore_repeated_log_interval: ignore_repeated_log_interval}
312
+ log_opts = {suppress_repeated_stacktrace: suppress_repeated_stacktrace, ignore_repeated_log_interval: ignore_repeated_log_interval,
313
+ ignore_same_log_interval: ignore_same_log_interval}
313
314
  logger_initializer = Supervisor::LoggerInitializer.new(
314
315
  log_path, log_level, chuser, chgroup, log_opts,
315
316
  log_rotate_age: log_rotate_age,
@@ -347,6 +348,7 @@ module Fluent
347
348
  chumask: 0,
348
349
  suppress_repeated_stacktrace: suppress_repeated_stacktrace,
349
350
  ignore_repeated_log_interval: ignore_repeated_log_interval,
351
+ ignore_same_log_interval: ignore_same_log_interval,
350
352
  daemonize: daemonize,
351
353
  rpc_endpoint: params['rpc_endpoint'],
352
354
  counter_server: params['counter_server'],
@@ -441,10 +443,11 @@ module Fluent
441
443
  self
442
444
  end
443
445
 
444
- def apply_options(format: nil, time_format: nil, log_dir_perm: nil, ignore_repeated_log_interval: nil)
446
+ def apply_options(format: nil, time_format: nil, log_dir_perm: nil, ignore_repeated_log_interval: nil, ignore_same_log_interval: nil)
445
447
  $log.format = format if format
446
448
  $log.time_format = time_format if time_format
447
449
  $log.ignore_repeated_log_interval = ignore_repeated_log_interval if ignore_repeated_log_interval
450
+ $log.ignore_same_log_interval = ignore_same_log_interval if ignore_same_log_interval
448
451
 
449
452
  if @path && log_dir_perm
450
453
  File.chmod(log_dir_perm || 0755, File.dirname(@path))
@@ -511,7 +514,8 @@ module Fluent
511
514
  @cl_opt = opt
512
515
  @conf = nil
513
516
 
514
- log_opts = {suppress_repeated_stacktrace: opt[:suppress_repeated_stacktrace], ignore_repeated_log_interval: opt[:ignore_repeated_log_interval]}
517
+ log_opts = {suppress_repeated_stacktrace: opt[:suppress_repeated_stacktrace], ignore_repeated_log_interval: opt[:ignore_repeated_log_interval],
518
+ ignore_same_log_interval: opt[:ignore_same_log_interval]}
515
519
  @log = LoggerInitializer.new(
516
520
  @log_path, opt[:log_level], @chuser, @chgroup, log_opts,
517
521
  log_rotate_age: @log_rotate_age,
@@ -635,7 +639,8 @@ module Fluent
635
639
  format: @system_config.log.format,
636
640
  time_format: @system_config.log.time_format,
637
641
  log_dir_perm: @system_config.dir_permission,
638
- ignore_repeated_log_interval: @system_config.ignore_repeated_log_interval
642
+ ignore_repeated_log_interval: @system_config.ignore_repeated_log_interval,
643
+ ignore_same_log_interval: @system_config.ignore_same_log_interval
639
644
  )
640
645
 
641
646
  $log.info :supervisor, 'parsing config file is succeeded', path: @config_path
@@ -804,7 +809,7 @@ module Fluent
804
809
  Fluent::Engine.reload_config(conf)
805
810
  end
806
811
  rescue => e
807
- # it is guranteed that config file is valid by supervisor side. but it's not atomic becuase of using signals to commnicate between worker and super
812
+ # it is guaranteed that config file is valid by supervisor side. but it's not atomic because of using signals to commnicate between worker and super
808
813
  # So need this rescue code
809
814
  $log.error("failed to reload config: #{e}")
810
815
  next
@@ -24,7 +24,7 @@ module Fluent
24
24
  SYSTEM_CONFIG_PARAMETERS = [
25
25
  :workers, :root_dir, :log_level,
26
26
  :suppress_repeated_stacktrace, :emit_error_log_interval, :suppress_config_dump,
27
- :log_event_verbose, :ignore_repeated_log_interval,
27
+ :log_event_verbose, :ignore_repeated_log_interval, :ignore_same_log_interval,
28
28
  :without_source, :rpc_endpoint, :enable_get_dump, :process_name,
29
29
  :file_permission, :dir_permission, :counter_server, :counter_client,
30
30
  :strict_config_value, :enable_msgpack_time_support
@@ -35,6 +35,7 @@ module Fluent
35
35
  config_param :log_level, :enum, list: [:trace, :debug, :info, :warn, :error, :fatal], default: 'info'
36
36
  config_param :suppress_repeated_stacktrace, :bool, default: nil
37
37
  config_param :ignore_repeated_log_interval, :time, default: nil
38
+ config_param :ignore_same_log_interval, :time, default: nil
38
39
  config_param :emit_error_log_interval, :time, default: nil
39
40
  config_param :suppress_config_dump, :bool, default: nil
40
41
  config_param :log_event_verbose, :bool, default: nil
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '1.11.0'
19
+ VERSION = '1.11.5'
20
20
 
21
21
  end
@@ -82,6 +82,14 @@ class TestBaseCommand < ::Test::Unit::TestCase
82
82
  end
83
83
 
84
84
  class TestHead < TestBaseCommand
85
+ setup do
86
+ @default_newline = if Fluent.windows?
87
+ "\r\n"
88
+ else
89
+ "\n"
90
+ end
91
+ end
92
+
85
93
  sub_test_case 'initialize' do
86
94
  data(
87
95
  'file is not passed' => %w(),
@@ -138,7 +146,7 @@ class TestHead < TestBaseCommand
138
146
  create_message_packed_file(@file_name, [event_time(@t).to_i] * 6, [@record] * 6)
139
147
  head = BinlogReaderCommand::Head.new(argv)
140
148
  out = capture_stdout { head.call }
141
- assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}\n" * 5, out
149
+ assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}#{@default_newline}" * 5, out
142
150
  end
143
151
  end
144
152
 
@@ -149,7 +157,7 @@ class TestHead < TestBaseCommand
149
157
  create_message_packed_file(@file_name, [event_time(@t).to_i] * 6, [@record] * 6)
150
158
  head = BinlogReaderCommand::Head.new(argv)
151
159
  out = capture_stdout { head.call }
152
- assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}\n", out
160
+ assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}#{@default_newline}", out
153
161
  end
154
162
  end
155
163
 
@@ -169,7 +177,7 @@ class TestHead < TestBaseCommand
169
177
  create_message_packed_file(@file_name, [event_time(@t).to_i], [@record])
170
178
  head = BinlogReaderCommand::Head.new(argv)
171
179
  out = capture_stdout { head.call }
172
- assert_equal "#{Yajl.dump(@record)}\n", out
180
+ assert_equal "#{Yajl.dump(@record)}#{@default_newline}", out
173
181
  end
174
182
  end
175
183
 
@@ -198,6 +206,14 @@ class TestHead < TestBaseCommand
198
206
  end
199
207
 
200
208
  class TestCat < TestBaseCommand
209
+ setup do
210
+ @default_newline = if Fluent.windows?
211
+ "\r\n"
212
+ else
213
+ "\n"
214
+ end
215
+ end
216
+
201
217
  sub_test_case 'initialize' do
202
218
  data(
203
219
  'file is not passed' => [],
@@ -254,7 +270,7 @@ class TestCat < TestBaseCommand
254
270
  create_message_packed_file(@file_name, [event_time(@t).to_i] * 6, [@record] * 6)
255
271
  head = BinlogReaderCommand::Cat.new(argv)
256
272
  out = capture_stdout { head.call }
257
- assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}\n" * 6, out
273
+ assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}#{@default_newline}" * 6, out
258
274
  end
259
275
  end
260
276
 
@@ -265,7 +281,7 @@ class TestCat < TestBaseCommand
265
281
  create_message_packed_file(@file_name, [event_time(@t).to_i] * 6, [@record] * 6)
266
282
  head = BinlogReaderCommand::Cat.new(argv)
267
283
  out = capture_stdout { head.call }
268
- assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}\n", out
284
+ assert_equal "2011-01-02T13:14:15+00:00\t#{TMP_DIR}/#{@file_name}\t#{Yajl.dump(@record)}#{@default_newline}", out
269
285
  end
270
286
  end
271
287
 
@@ -276,7 +292,7 @@ class TestCat < TestBaseCommand
276
292
  create_message_packed_file(@file_name, [event_time(@t).to_i], [@record])
277
293
  head = BinlogReaderCommand::Cat.new(argv)
278
294
  out = capture_stdout { head.call }
279
- assert_equal "#{Yajl.dump(@record)}\n", out
295
+ assert_equal "#{Yajl.dump(@record)}#{@default_newline}", out
280
296
  end
281
297
  end
282
298
 
@@ -543,6 +543,8 @@ class BufferTest < Test::Unit::TestCase
543
543
  assert_equal [@dm0,@dm1,@dm1], @p.queue.map(&:metadata)
544
544
  assert_equal [@dm2,@dm3,m], @p.stage.keys
545
545
 
546
+ @p.update_timekeys
547
+
546
548
  assert @p.timekeys.include?(timekey)
547
549
  end
548
550
 
@@ -675,6 +677,8 @@ class BufferTest < Test::Unit::TestCase
675
677
  assert_equal [@dm2,@dm3,m], @p.stage.keys
676
678
  assert_equal 1, @p.stage[m].append_count
677
679
 
680
+ @p.update_timekeys
681
+
678
682
  assert @p.timekeys.include?(timekey)
679
683
  end
680
684
 
@@ -12,6 +12,11 @@ class StdoutFilterTest < Test::Unit::TestCase
12
12
  @old_tz = ENV["TZ"]
13
13
  ENV["TZ"] = "UTC"
14
14
  Timecop.freeze
15
+ @default_newline = if Fluent.windows?
16
+ "\r\n"
17
+ else
18
+ "\n"
19
+ end
15
20
  end
16
21
 
17
22
  def teardown
@@ -106,7 +111,7 @@ class StdoutFilterTest < Test::Unit::TestCase
106
111
  def test_format_json
107
112
  d = create_driver(CONFIG + config_element("", "", { "format" => "json" }))
108
113
  out = capture_log(d) { filter(d, event_time, {'test' => 'test'}) }
109
- assert_equal "{\"test\":\"test\"}\n", out
114
+ assert_equal "{\"test\":\"test\"}#{@default_newline}", out
110
115
  end
111
116
  end
112
117
 
@@ -19,11 +19,14 @@ class HashFormatterTest < ::Test::Unit::TestCase
19
19
  {'message' => 'awesome', 'greeting' => 'hello'}
20
20
  end
21
21
 
22
- def test_format
23
- d = create_driver({})
22
+ data("newline (LF)" => ["lf", "\n"],
23
+ "newline (CRLF)" => ["crlf", "\r\n"])
24
+ def test_format(data)
25
+ newline_conf, newline = data
26
+ d = create_driver({"newline" => newline_conf})
24
27
  formatted = d.instance.format(tag, @time, record)
25
28
 
26
- assert_equal(%Q!{"message"=>"awesome", "greeting"=>"hello"}\n!, formatted.encode(Encoding::UTF_8))
29
+ assert_equal(%Q!{"message"=>"awesome", "greeting"=>"hello"}#{newline}!, formatted.encode(Encoding::UTF_8))
27
30
  end
28
31
 
29
32
  def test_format_without_newline
@@ -7,6 +7,11 @@ class JsonFormatterTest < ::Test::Unit::TestCase
7
7
 
8
8
  def setup
9
9
  @time = event_time
10
+ @default_newline = if Fluent.windows?
11
+ "\r\n"
12
+ else
13
+ "\n"
14
+ end
10
15
  end
11
16
 
12
17
  def create_driver(conf = "")
@@ -25,12 +30,17 @@ class JsonFormatterTest < ::Test::Unit::TestCase
25
30
  {:message => :awesome}
26
31
  end
27
32
 
28
- data('oj' => 'oj', 'yajl' => 'yajl')
33
+ data('oj with LF' => ['oj', "lf", "\n"],
34
+ 'oj with CRLF' => ['oj', "crlf", "\r\n"],
35
+ 'yajl with LF' => ['yajl', "lf", "\n"],
36
+ 'yajl with CRLF' => ['yajl', "crlf", "\r\n"]
37
+ )
29
38
  def test_format(data)
30
- d = create_driver('json_parser' => data)
39
+ parser, newline_conf, newline = data
40
+ d = create_driver('json_parser' => parser, 'newline' => newline_conf)
31
41
  formatted = d.instance.format(tag, @time, record)
32
42
 
33
- assert_equal("#{JSON.generate(record)}\n", formatted)
43
+ assert_equal("#{JSON.generate(record)}#{newline}", formatted)
34
44
  end
35
45
 
36
46
  data('oj' => 'oj', 'yajl' => 'yajl')
@@ -46,6 +56,6 @@ class JsonFormatterTest < ::Test::Unit::TestCase
46
56
  d = create_driver('json_parser' => data)
47
57
  formatted = d.instance.format(tag, @time, symbolic_record)
48
58
 
49
- assert_equal("#{JSON.generate(record)}\n", formatted)
59
+ assert_equal("#{JSON.generate(record)}#{@default_newline}", formatted)
50
60
  end
51
61
  end