fluentd 0.14.6 → 0.14.7

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 (103) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +46 -0
  3. data/bin/fluent-binlog-reader +7 -0
  4. data/example/in_dummy_with_compression.conf +23 -0
  5. data/lib/fluent/agent.rb +8 -12
  6. data/lib/fluent/command/binlog_reader.rb +234 -0
  7. data/lib/fluent/command/fluentd.rb +17 -1
  8. data/lib/fluent/compat/file_util.rb +1 -1
  9. data/lib/fluent/compat/output.rb +5 -1
  10. data/lib/fluent/config/configure_proxy.rb +18 -4
  11. data/lib/fluent/config/element.rb +1 -1
  12. data/lib/fluent/config/section.rb +1 -1
  13. data/lib/fluent/config/v1_parser.rb +1 -1
  14. data/lib/fluent/env.rb +1 -0
  15. data/lib/fluent/event.rb +49 -2
  16. data/lib/fluent/event_router.rb +6 -2
  17. data/lib/fluent/label.rb +8 -0
  18. data/lib/fluent/log.rb +30 -1
  19. data/lib/fluent/plugin.rb +1 -1
  20. data/lib/fluent/plugin/base.rb +3 -0
  21. data/lib/fluent/plugin/buf_file.rb +2 -2
  22. data/lib/fluent/plugin/buf_memory.rb +1 -1
  23. data/lib/fluent/plugin/buffer.rb +12 -2
  24. data/lib/fluent/plugin/buffer/chunk.rb +68 -7
  25. data/lib/fluent/plugin/buffer/file_chunk.rb +4 -4
  26. data/lib/fluent/plugin/buffer/memory_chunk.rb +4 -4
  27. data/lib/fluent/plugin/compressable.rb +91 -0
  28. data/lib/fluent/plugin/filter_grep.rb +4 -4
  29. data/lib/fluent/plugin/formatter.rb +2 -2
  30. data/lib/fluent/plugin/formatter_json.rb +2 -1
  31. data/lib/fluent/plugin/formatter_out_file.rb +3 -30
  32. data/lib/fluent/plugin/in_forward.rb +3 -2
  33. data/lib/fluent/plugin/in_monitor_agent.rb +7 -21
  34. data/lib/fluent/plugin/in_syslog.rb +1 -1
  35. data/lib/fluent/plugin/in_tail.rb +10 -2
  36. data/lib/fluent/plugin/multi_output.rb +63 -3
  37. data/lib/fluent/plugin/out_exec.rb +1 -1
  38. data/lib/fluent/plugin/out_file.rb +5 -1
  39. data/lib/fluent/plugin/out_forward.rb +17 -5
  40. data/lib/fluent/plugin/out_stdout.rb +2 -1
  41. data/lib/fluent/plugin/output.rb +205 -19
  42. data/lib/fluent/plugin/parser.rb +5 -49
  43. data/lib/fluent/plugin/parser_apache2.rb +1 -1
  44. data/lib/fluent/plugin/parser_json.rb +4 -4
  45. data/lib/fluent/plugin/parser_multiline.rb +5 -5
  46. data/lib/fluent/plugin/parser_regexp.rb +1 -2
  47. data/lib/fluent/plugin/parser_syslog.rb +2 -2
  48. data/lib/fluent/plugin/storage_local.rb +2 -1
  49. data/lib/fluent/plugin_helper.rb +1 -0
  50. data/lib/fluent/plugin_helper/compat_parameters.rb +39 -21
  51. data/lib/fluent/plugin_helper/extract.rb +92 -0
  52. data/lib/fluent/plugin_helper/inject.rb +10 -12
  53. data/lib/fluent/plugin_helper/thread.rb +23 -3
  54. data/lib/fluent/registry.rb +1 -1
  55. data/lib/fluent/root_agent.rb +2 -1
  56. data/lib/fluent/supervisor.rb +28 -8
  57. data/lib/fluent/test/base.rb +0 -7
  58. data/lib/fluent/test/driver/base.rb +1 -0
  59. data/lib/fluent/test/driver/output.rb +3 -0
  60. data/lib/fluent/test/helpers.rb +18 -0
  61. data/lib/fluent/test/input_test.rb +4 -2
  62. data/lib/fluent/test/log.rb +3 -1
  63. data/lib/fluent/time.rb +232 -1
  64. data/lib/fluent/timezone.rb +1 -1
  65. data/lib/fluent/version.rb +1 -1
  66. data/test/command/test_binlog_reader.rb +351 -0
  67. data/test/config/test_config_parser.rb +6 -0
  68. data/test/config/test_configurable.rb +47 -1
  69. data/test/helper.rb +0 -1
  70. data/test/plugin/test_buffer.rb +22 -2
  71. data/test/plugin/test_buffer_chunk.rb +34 -4
  72. data/test/plugin/test_buffer_file_chunk.rb +73 -0
  73. data/test/plugin/test_buffer_memory_chunk.rb +73 -0
  74. data/test/plugin/test_compressable.rb +81 -0
  75. data/test/plugin/test_formatter_json.rb +14 -1
  76. data/test/plugin/test_in_forward.rb +67 -3
  77. data/test/plugin/test_in_monitor_agent.rb +17 -1
  78. data/test/plugin/test_in_tail.rb +8 -8
  79. data/test/plugin/test_out_file.rb +0 -8
  80. data/test/plugin/test_out_forward.rb +85 -0
  81. data/test/plugin/test_out_secondary_file.rb +20 -12
  82. data/test/plugin/test_out_stdout.rb +11 -10
  83. data/test/plugin/test_output.rb +234 -0
  84. data/test/plugin/test_output_as_buffered.rb +223 -0
  85. data/test/plugin/test_output_as_buffered_compress.rb +165 -0
  86. data/test/plugin/test_parser_json.rb +8 -0
  87. data/test/plugin/test_parser_regexp.rb +1 -1
  88. data/test/plugin_helper/test_child_process.rb +2 -2
  89. data/test/plugin_helper/test_extract.rb +195 -0
  90. data/test/plugin_helper/test_inject.rb +0 -7
  91. data/test/scripts/fluent/plugin/formatter1/formatter_test1.rb +7 -0
  92. data/test/scripts/fluent/plugin/formatter2/formatter_test2.rb +7 -0
  93. data/test/test_event.rb +186 -0
  94. data/test/test_event_router.rb +1 -1
  95. data/test/test_formatter.rb +0 -7
  96. data/test/test_log.rb +121 -0
  97. data/test/test_plugin_classes.rb +62 -0
  98. data/test/test_root_agent.rb +125 -0
  99. data/test/test_supervisor.rb +25 -2
  100. data/test/test_time_formatter.rb +103 -7
  101. data/test/test_time_parser.rb +211 -0
  102. metadata +23 -4
  103. data/test/plugin/test_parser_time.rb +0 -46
@@ -307,7 +307,7 @@ class EventRouterTest < ::Test::Unit::TestCase
307
307
 
308
308
  e = OneEventStream.new(@now, @record)
309
309
  assert_rr do
310
- mock($log).info("Filtering works with worse performance, because #{[filter_stream].map(&:class)} uses `#filter_stream` method.")
310
+ mock($log).info("disable filter chain optimization because #{[filter_stream].map(&:class)} uses `#filter_stream` method.")
311
311
  mock(filter_stream).filter_stream('test', is_a(OneEventStream)) { e }
312
312
  mock(filter).filter_stream('test', is_a(OneEventStream)) { e }
313
313
  mock(filter_with_time).filter_stream('test', is_a(OneEventStream)) { e }
@@ -13,13 +13,6 @@ module FormatterTest
13
13
  {'message' => 'awesome', 'greeting' => 'hello'}
14
14
  end
15
15
 
16
- def with_timezone(tz)
17
- oldtz, ENV['TZ'] = ENV['TZ'], tz
18
- yield
19
- ensure
20
- ENV['TZ'] = oldtz
21
- end
22
-
23
16
  class BaseFormatterTest < ::Test::Unit::TestCase
24
17
  include FormatterTest
25
18
 
@@ -2,9 +2,14 @@ require_relative 'helper'
2
2
  require 'fluent/engine'
3
3
  require 'fluent/log'
4
4
  require 'timecop'
5
+ require 'logger'
5
6
 
6
7
  class LogTest < Test::Unit::TestCase
8
+ TMP_DIR = File.expand_path(File.dirname(__FILE__) + "/tmp/log/#{ENV['TEST_ENV_NUMBER']}")
9
+
7
10
  def setup
11
+ FileUtils.rm_rf(TMP_DIR)
12
+ FileUtils.mkdir_p(TMP_DIR)
8
13
  @log_device = Fluent::Test::DummyLogDevice.new
9
14
  @timestamp = Time.parse("2016-04-21 11:58:41 +0900")
10
15
  @timestamp_str = @timestamp.strftime("%Y-%m-%d %H:%M:%S %z")
@@ -404,6 +409,84 @@ class LogTest < Test::Unit::TestCase
404
409
  # check fluentd log side level is also changed
405
410
  assert_equal(Fluent::Log::LEVEL_DEBUG, log.level)
406
411
  end
412
+
413
+ DAY_SEC = 60 * 60 * 24
414
+ data(
415
+ rotate_daily_age: ['daily', 100000, DAY_SEC + 1],
416
+ rotate_weekly_age: ['weekly', 100000, DAY_SEC * 7 + 1],
417
+ rotate_monthly_age: ['monthly', 100000, DAY_SEC * 31 + 1],
418
+ rotate_size: [1, 100, 0, '0'],
419
+ )
420
+ def test_log_with_logdevio(expected)
421
+ with_timezone('utc') do
422
+ @timestamp = Time.parse("2016-04-21 00:00:00 +0000")
423
+ @timestamp_str = @timestamp.strftime("%Y-%m-%d %H:%M:%S %z")
424
+ Timecop.freeze(@timestamp)
425
+
426
+ rotate_age, rotate_size, travel_term = expected
427
+ path = "#{TMP_DIR}/log-dev-io-#{rotate_size}-#{rotate_age}"
428
+
429
+ logdev = Fluent::LogDeviceIO.new(path, shift_age: rotate_age, shift_size: rotate_size)
430
+ logger = ServerEngine::DaemonLogger.new(logdev)
431
+ log = Fluent::Log.new(logger)
432
+
433
+ msg = 'a' * 101
434
+ log.info msg
435
+ assert_match msg, File.read(path)
436
+
437
+ Timecop.freeze(@timestamp + travel_term)
438
+
439
+ msg2 = 'b' * 101
440
+ log.info msg2
441
+ c = File.read(path)
442
+
443
+ assert_match msg2, c
444
+ assert_not_equal msg, c
445
+ end
446
+ end
447
+
448
+ def test_log_rotates_specifed_size_with_logdevio
449
+ with_timezone('utc') do
450
+ rotate_age = 2
451
+ rotate_size = 100
452
+ path = "#{TMP_DIR}/log-dev-io-#{rotate_size}-#{rotate_age}"
453
+ path0 = path + '.0'
454
+ path1 = path + '.1'
455
+
456
+ logdev = Fluent::LogDeviceIO.new(path, shift_age: rotate_age, shift_size: rotate_size)
457
+ logger = ServerEngine::DaemonLogger.new(logdev)
458
+ log = Fluent::Log.new(logger)
459
+
460
+ msg = 'a' * 101
461
+ log.info msg
462
+ assert_match msg, File.read(path)
463
+ assert_true File.exist?(path)
464
+ assert_true !File.exist?(path0)
465
+ assert_true !File.exist?(path1)
466
+
467
+ # create log.0
468
+ msg2 = 'b' * 101
469
+ log.info msg2
470
+ c = File.read(path)
471
+ c0 = File.read(path0)
472
+ assert_match msg2, c
473
+ assert_match msg, c0
474
+ assert_true File.exist?(path)
475
+ assert_true File.exist?(path0)
476
+ assert_true !File.exist?(path1)
477
+
478
+ # rotate
479
+ msg3 = 'c' * 101
480
+ log.info msg3
481
+ c = File.read(path)
482
+ c0 = File.read(path0)
483
+ assert_match msg3, c
484
+ assert_match msg2, c0
485
+ assert_true File.exist?(path)
486
+ assert_true File.exist?(path0)
487
+ assert_true !File.exist?(path1)
488
+ end
489
+ end
407
490
  end
408
491
 
409
492
  class PluginLoggerTest < Test::Unit::TestCase
@@ -570,3 +653,41 @@ class PluginLoggerMixinTest < Test::Unit::TestCase
570
653
  plugin.terminate
571
654
  end
572
655
  end
656
+
657
+ class LogDeviceIOTest < Test::Unit::TestCase
658
+ test 'flush' do
659
+ io = StringIO.new
660
+ logdev = Fluent::LogDeviceIO.new(io)
661
+ assert_equal io, logdev.flush
662
+
663
+ io.instance_eval { undef :flush }
664
+ logdev = Fluent::LogDeviceIO.new(io)
665
+ assert_raise NoMethodError do
666
+ logdev.flush
667
+ end
668
+ end
669
+
670
+ test 'tty?' do
671
+ io = StringIO.new
672
+ logdev = Fluent::LogDeviceIO.new(io)
673
+ assert_equal io.tty?, logdev.tty?
674
+
675
+ io.instance_eval { undef :tty? }
676
+ logdev = Fluent::LogDeviceIO.new(io)
677
+ assert_raise NoMethodError do
678
+ logdev.tty?
679
+ end
680
+ end
681
+
682
+ test 'sync=' do
683
+ io = StringIO.new
684
+ logdev = Fluent::LogDeviceIO.new(io)
685
+ assert_true logdev.sync = true
686
+
687
+ io.instance_eval { undef :sync= }
688
+ logdev = Fluent::LogDeviceIO.new(io)
689
+ assert_raise NoMethodError do
690
+ logdev.sync = true
691
+ end
692
+ end
693
+ end
@@ -1,6 +1,7 @@
1
1
  require_relative 'helper'
2
2
  require 'fluent/plugin/input'
3
3
  require 'fluent/plugin/output'
4
+ require 'fluent/plugin/bare_output'
4
5
  require 'fluent/plugin/filter'
5
6
 
6
7
  module FluentTest
@@ -48,6 +49,67 @@ module FluentTest
48
49
  end
49
50
  end
50
51
 
52
+ class FluentTestDynamicOutput < ::Fluent::Plugin::BareOutput
53
+ ::Fluent::Plugin.register_output('test_dynamic_out', self)
54
+
55
+ attr_reader :child
56
+ attr_reader :started
57
+
58
+ def start
59
+ super
60
+ @started = true
61
+ @child = Fluent::Plugin.new_output('copy')
62
+ conf = config_element('DYNAMIC', '', {}, [
63
+ config_element('store', '', {'@type' => 'test_out', '@id' => 'dyn_out1'}),
64
+ config_element('store', '', {'@type' => 'test_out', '@id' => 'dyn_out2'}),
65
+ ])
66
+ @child.configure(conf)
67
+ @child.start
68
+ end
69
+
70
+ def after_start
71
+ super
72
+ @child.after_start
73
+ end
74
+
75
+ def stop
76
+ super
77
+ @child.stop
78
+ end
79
+
80
+ def before_shutdown
81
+ super
82
+ @child.before_shutdown
83
+ end
84
+
85
+ def shutdown
86
+ @started = false
87
+ super
88
+ @child.shutdown
89
+ end
90
+
91
+ def after_shutdown
92
+ super
93
+ @child.after_shutdown
94
+ end
95
+
96
+ def close
97
+ super
98
+ @child.close
99
+ end
100
+
101
+ def terminate
102
+ super
103
+ @child.terminate
104
+ end
105
+
106
+ def process(tag, es)
107
+ es.each do |time, record|
108
+ @events[tag] << record
109
+ end
110
+ end
111
+ end
112
+
51
113
  class FluentTestErrorOutput < ::Fluent::Plugin::Output
52
114
  ::Fluent::Plugin.register_output('test_out_error', self)
53
115
 
@@ -89,6 +89,41 @@ EOC
89
89
  end
90
90
  end
91
91
 
92
+ test 'raises configuration error if there are two same label section' do
93
+ conf = <<-EOC
94
+ <source>
95
+ @type test_in
96
+ @label @test
97
+ </source>
98
+ <label @test>
99
+ @type test_out
100
+ </label>
101
+ <label @test>
102
+ @type test_out
103
+ </label>
104
+ EOC
105
+ errmsg = "Section <label @test> appears twice"
106
+ assert_raise Fluent::ConfigError.new(errmsg) do
107
+ configure_ra(conf)
108
+ end
109
+ end
110
+
111
+ test 'raises configuration error if there are not match sections in label section' do
112
+ conf = <<-EOC
113
+ <source>
114
+ @type test_in
115
+ @label @test
116
+ </source>
117
+ <label @test>
118
+ @type test_out
119
+ </label>
120
+ EOC
121
+ errmsg = "Missing <match> sections in <label @test> section"
122
+ assert_raise Fluent::ConfigError.new(errmsg) do
123
+ configure_ra(conf)
124
+ end
125
+ end
126
+
92
127
  test 'with plugins' do
93
128
  # check @type and type in one configuration
94
129
  conf = <<-EOC
@@ -316,5 +351,95 @@ EOC
316
351
  assert_equal [true], label_filters.map{|i| i.terminated? }
317
352
  assert_equal [true, true, true], label_outputs.map{|i| i.terminated? }
318
353
  end
354
+
355
+ test 'plugin #shutdown is not called twice' do
356
+ assert_equal 1, @ra.inputs.size
357
+ assert_equal 0, @ra.filters.size
358
+ assert_equal 0, @ra.outputs.size
359
+ assert_equal 1, @ra.labels.size
360
+ assert_equal '@testing', @ra.labels.keys.first
361
+ assert_equal 1, @ra.labels.values.first.filters.size
362
+ assert_equal 3, @ra.labels.values.first.outputs.size
363
+
364
+ @ra.start
365
+
366
+ old_level = @ra.log.level
367
+ begin
368
+ @ra.log.instance_variable_get(:@logger).level = Fluent::Log::LEVEL_INFO - 1
369
+ assert_equal Fluent::Log::LEVEL_INFO, @ra.log.level
370
+
371
+ @ra.log.out.flush_logs = false
372
+
373
+ @ra.shutdown
374
+
375
+ test_out1_shutdown_logs = @ra.log.out.logs.select{|line| line =~ /shutting down output plugin type=:test_out plugin_id="test_out1"/ }
376
+ assert_equal 1, test_out1_shutdown_logs.size
377
+ ensure
378
+ @ra.log.out.flush_logs = true
379
+ @ra.log.out.reset
380
+ @ra.log.level = old_level
381
+ end
382
+ end
383
+ end
384
+
385
+ sub_test_case 'configured with MultiOutput plugin which creates plugin instances dynamically' do
386
+ setup do
387
+ @ra = RootAgent.new(log: $log)
388
+ stub(Engine).root_agent { @ra }
389
+ @ra.configure(Config.parse(<<-EOC, "(test)", "(test_dir)", true))
390
+ <source>
391
+ @type test_in
392
+ @id test_in
393
+ @label @testing
394
+ </source>
395
+ <label @testing>
396
+ <match **>
397
+ @type test_dynamic_out
398
+ @id test_dyn
399
+ </match>
400
+ </label>
401
+ EOC
402
+ @ra
403
+ end
404
+
405
+ test 'plugin status with multi output' do
406
+ assert_equal 1, @ra.inputs.size
407
+ assert_equal 0, @ra.filters.size
408
+ assert_equal 0, @ra.outputs.size
409
+ assert_equal 1, @ra.labels.size
410
+ assert_equal '@testing', @ra.labels.keys.first
411
+ assert_equal 0, @ra.labels.values.first.filters.size
412
+ assert_equal 1, @ra.labels.values.first.outputs.size
413
+
414
+ dyn_out = @ra.labels.values.first.outputs.first
415
+ assert_nil dyn_out.child
416
+
417
+ @ra.start
418
+
419
+ assert_equal 1, @ra.labels.values.first.outputs.size
420
+
421
+ assert dyn_out.child
422
+ assert_false dyn_out.child.outputs_statically_created
423
+ assert_equal 2, dyn_out.child.outputs.size
424
+
425
+ assert_equal true, dyn_out.child.outputs[0].started?
426
+ assert_equal true, dyn_out.child.outputs[1].started?
427
+ assert_equal true, dyn_out.child.outputs[0].after_started?
428
+ assert_equal true, dyn_out.child.outputs[1].after_started?
429
+
430
+ @ra.shutdown
431
+
432
+ assert_equal 1, @ra.labels.values.first.outputs.size
433
+
434
+ assert_false dyn_out.child.outputs_statically_created
435
+ assert_equal 2, dyn_out.child.outputs.size
436
+
437
+ assert_equal [true, true], dyn_out.child.outputs.map{|i| i.stopped? }
438
+ assert_equal [true, true], dyn_out.child.outputs.map{|i| i.before_shutdown? }
439
+ assert_equal [true, true], dyn_out.child.outputs.map{|i| i.shutdown? }
440
+ assert_equal [true, true], dyn_out.child.outputs.map{|i| i.after_shutdown? }
441
+ assert_equal [true, true], dyn_out.child.outputs.map{|i| i.closed? }
442
+ assert_equal [true, true], dyn_out.child.outputs.map{|i| i.terminated? }
443
+ end
319
444
  end
320
445
  end
@@ -14,10 +14,11 @@ class SupervisorTest < ::Test::Unit::TestCase
14
14
  include ServerModule
15
15
  include WorkerModule
16
16
 
17
- TMP_DIR = File.dirname(__FILE__) + "/tmp/config#{ENV['TEST_ENV_NUMBER']}"
17
+ TMP_DIR = File.expand_path(File.dirname(__FILE__) + "/tmp/supervisor#{ENV['TEST_ENV_NUMBER']}")
18
18
 
19
19
  def setup
20
- FileUtils.mkdir_p('test/tmp/supervisor')
20
+ FileUtils.rm_rf(TMP_DIR)
21
+ FileUtils.mkdir_p(TMP_DIR)
21
22
  end
22
23
 
23
24
  def write_config(path, data)
@@ -319,6 +320,28 @@ class SupervisorTest < ::Test::Unit::TestCase
319
320
  # test that DamonLogger#level= overwrites Fluent.log#level
320
321
  logger.level = 'debug'
321
322
  assert_equal Fluent::Log::LEVEL_DEBUG, $log.level
323
+
324
+ assert_equal 5, logger.instance_variable_get(:@rotate_age)
325
+ assert_equal 1048576, logger.instance_variable_get(:@rotate_size)
326
+ end
327
+
328
+ data(
329
+ daily_age: 'daily',
330
+ weekly_age: 'weekly',
331
+ monthly_age: 'monthly',
332
+ integer_age: 2,
333
+ )
334
+ def test_logger_with_rotate_age_and_rotate_size(rotate_age)
335
+ opts = Fluent::Supervisor.default_options.merge(
336
+ log_path: "#{TMP_DIR}/test", log_rotate_age: rotate_age, log_rotate_size: 10
337
+ )
338
+ sv = Fluent::Supervisor.new(opts)
339
+ log = sv.instance_variable_get(:@log)
340
+ log.init
341
+
342
+ assert_equal Fluent::LogDeviceIO, $log.out.class
343
+ assert_equal rotate_age, $log.out.instance_variable_get(:@shift_age)
344
+ assert_equal 10, $log.out.instance_variable_get(:@shift_size)
322
345
  end
323
346
 
324
347
  def create_debug_dummy_logger
@@ -3,13 +3,6 @@ require 'fluent/test'
3
3
  require 'fluent/time'
4
4
 
5
5
  class TimeFormatterTest < ::Test::Unit::TestCase
6
- def with_timezone(tz)
7
- oldtz, ENV['TZ'] = ENV['TZ'], tz
8
- yield
9
- ensure
10
- ENV['TZ'] = oldtz
11
- end
12
-
13
6
  def setup
14
7
  @time = Time.new(2014, 9, 27, 0, 0, 0, 0).to_i
15
8
  @fmt = "%Y%m%d %H%M%z" # YYYYMMDD HHMM[+-]HHMM
@@ -183,4 +176,107 @@ class TimeFormatterTest < ::Test::Unit::TestCase
183
176
  formatter = Fluent::TimeFormatter.new("%Y%m%d %H%M.%N", false, nil)
184
177
  assert_equal("20140927 0000.000000000", formatter.format(time))
185
178
  end
179
+
180
+ sub_test_case 'TimeMixin::Formatter' do
181
+ class DummyForTimeFormatter
182
+ include Fluent::Configurable
183
+ include Fluent::TimeMixin::Formatter
184
+ end
185
+
186
+ test 'provides configuration parameters for TimeFormatter with default values for localtime' do
187
+ str = with_timezone("UTC+07") do
188
+ i = DummyForTimeFormatter.new
189
+ i.configure(config_element('format'))
190
+
191
+ assert_nil i.time_format
192
+ assert_true i.localtime
193
+ assert_false i.utc
194
+ assert_nil i.timezone
195
+
196
+ fmt = i.time_formatter_create
197
+ fmt.format(event_time("2016-09-02 18:42:31.012345678 UTC", format: '%Y-%m-%d %H:%M:%S.%N %z'))
198
+ end
199
+ assert_equal "2016-09-02T11:42:31-07:00", str
200
+ end
201
+
202
+ test 'provides configuration parameters for TimeFormatter, configurable for any time format' do
203
+ str = with_timezone("UTC+07") do
204
+ i = DummyForTimeFormatter.new
205
+ i.configure(config_element('format', '', {'time_format' => '%Y-%m-%d %H:%M:%S.%N %z'}))
206
+
207
+ fmt = i.time_formatter_create
208
+ fmt.format(event_time("2016-09-02 18:42:31.012345678 UTC", format: '%Y-%m-%d %H:%M:%S.%N %z'))
209
+ end
210
+ assert_equal "2016-09-02 11:42:31.012345678 -0700", str
211
+ end
212
+
213
+ test 'provides configuration parameters for TimeFormatter, configurable for UTC' do
214
+ str = with_timezone("UTC+07") do
215
+ i = DummyForTimeFormatter.new
216
+ i.configure(config_element('format', '', {'time_format' => '%Y-%m-%d %H:%M:%S.%N %z', 'utc' => 'true'}))
217
+
218
+ fmt = i.time_formatter_create
219
+ fmt.format(event_time("2016-09-02 18:42:31.012345678 UTC", format: '%Y-%m-%d %H:%M:%S.%N %z'))
220
+ end
221
+ assert_equal "2016-09-02 18:42:31.012345678 +0000", str
222
+ end
223
+
224
+ test 'provides configuration parameters for TimeFormatter, configurable for any timezone' do
225
+ str = with_timezone("UTC+07") do
226
+ i = DummyForTimeFormatter.new
227
+ i.configure(config_element('format', '', {'time_format' => '%Y-%m-%d %H:%M:%S.%N %z', 'timezone' => '+0900'}))
228
+
229
+ fmt = i.time_formatter_create
230
+ fmt.format(event_time("2016-09-02 18:42:31.012345678 UTC", format: '%Y-%m-%d %H:%M:%S.%N %z'))
231
+ end
232
+ assert_equal "2016-09-03 03:42:31.012345678 +0900", str
233
+ end
234
+
235
+ test '#time_formatter_create returns TimeFormatter with specified time format and timezone' do
236
+ str = with_timezone("UTC+07") do
237
+ i = DummyForTimeFormatter.new
238
+ i.configure(config_element('format', '', {'time_format' => '%Y-%m-%d %H:%M:%S.%N %z', 'timezone' => '+0900'}))
239
+
240
+ fmt = i.time_formatter_create(format: '%m/%d/%Y %H-%M-%S %N', timezone: '+0000')
241
+ fmt.format(event_time("2016-09-02 18:42:31.012345678 UTC", format: '%Y-%m-%d %H:%M:%S.%N %z'))
242
+ end
243
+ assert_equal "09/02/2016 18-42-31 012345678", str
244
+ end
245
+
246
+ test '#time_formatter_create returns TimeFormatter with localtime besides any configuration parameters' do
247
+ str = with_timezone("UTC+07") do
248
+ i = DummyForTimeFormatter.new
249
+ i.configure(config_element('format', '', {'time_format' => '%Y-%m-%d %H:%M:%S.%N %z', 'utc' => 'true'}))
250
+
251
+ fmt = i.time_formatter_create(format: '%m/%d/%Y %H-%M-%S %N', force_localtime: true)
252
+ fmt.format(event_time("2016-09-02 18:42:31.012345678 UTC", format: '%Y-%m-%d %H:%M:%S.%N %z'))
253
+ end
254
+ assert_equal "09/02/2016 11-42-31 012345678", str
255
+
256
+ str = with_timezone("UTC+07") do
257
+ i = DummyForTimeFormatter.new
258
+ i.configure(config_element('format', '', {'time_format' => '%Y-%m-%d %H:%M:%S.%N %z', 'timezone' => '+0900'}))
259
+
260
+ fmt = i.time_formatter_create(format: '%m/%d/%Y %H-%M-%S %N', force_localtime: true)
261
+ fmt.format(event_time("2016-09-02 18:42:31.012345678 UTC", format: '%Y-%m-%d %H:%M:%S.%N %z'))
262
+ end
263
+ assert_equal "09/02/2016 11-42-31 012345678", str
264
+ end
265
+ end
266
+
267
+ test '#time_formatter_create returns NumericTimeFormatter to format time as unixtime when time_type unixtime specified' do
268
+ i = DummyForTimeFormatter.new
269
+ i.configure(config_element('format', '', {'time_type' => 'unixtime'}))
270
+ fmt = i.time_formatter_create
271
+ time = event_time("2016-10-03 20:08:30.123456789 +0100", format: '%Y-%m-%d %H:%M:%S.%N %z')
272
+ assert_equal "#{time.sec}", fmt.format(time)
273
+ end
274
+
275
+ test '#time_formatter_create returns NumericTimeFormatter to format time as float when time_type float specified' do
276
+ i = DummyForTimeFormatter.new
277
+ i.configure(config_element('format', '', {'time_type' => 'float'}))
278
+ fmt = i.time_formatter_create
279
+ time = event_time("2016-10-03 20:08:30.123456789 +0100", format: '%Y-%m-%d %H:%M:%S.%N %z')
280
+ assert_equal "#{time.sec}.#{time.nsec}", fmt.format(time)
281
+ end
186
282
  end