fluentd 0.14.1 → 0.14.2

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 (129) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog +110 -1
  3. data/Rakefile +5 -1
  4. data/appveyor.yml +7 -1
  5. data/example/in_forward.conf +4 -0
  6. data/lib/fluent/compat/exec_util.rb +129 -0
  7. data/lib/fluent/compat/file_util.rb +54 -0
  8. data/lib/fluent/compat/filter.rb +21 -3
  9. data/lib/fluent/compat/formatter.rb +4 -2
  10. data/lib/fluent/compat/formatter_utils.rb +85 -0
  11. data/lib/fluent/compat/handle_tag_and_time_mixin.rb +60 -0
  12. data/lib/fluent/compat/input.rb +1 -3
  13. data/lib/fluent/compat/output.rb +95 -39
  14. data/lib/fluent/compat/parser.rb +17 -0
  15. data/lib/fluent/compat/parser_utils.rb +40 -0
  16. data/lib/fluent/compat/socket_util.rb +165 -0
  17. data/lib/fluent/compat/string_util.rb +34 -0
  18. data/lib/fluent/{test/driver/owner.rb → compat/structured_format_mixin.rb} +5 -11
  19. data/lib/fluent/config/element.rb +2 -2
  20. data/lib/fluent/configurable.rb +2 -1
  21. data/lib/fluent/event.rb +61 -7
  22. data/lib/fluent/event_router.rb +1 -1
  23. data/lib/fluent/plugin.rb +7 -7
  24. data/lib/fluent/plugin/buf_file.rb +5 -2
  25. data/lib/fluent/plugin/buffer.rb +194 -64
  26. data/lib/fluent/plugin/buffer/chunk.rb +28 -3
  27. data/lib/fluent/plugin/buffer/file_chunk.rb +5 -21
  28. data/lib/fluent/plugin/buffer/memory_chunk.rb +1 -11
  29. data/lib/fluent/plugin/exec_util.rb +2 -112
  30. data/lib/fluent/plugin/file_util.rb +3 -38
  31. data/lib/fluent/plugin/file_wrapper.rb +1 -1
  32. data/lib/fluent/plugin/filter_grep.rb +3 -7
  33. data/lib/fluent/plugin/filter_record_transformer.rb +5 -5
  34. data/lib/fluent/plugin/filter_stdout.rb +18 -11
  35. data/lib/fluent/plugin/formatter.rb +0 -48
  36. data/lib/fluent/plugin/formatter_csv.rb +7 -8
  37. data/lib/fluent/plugin/formatter_hash.rb +1 -4
  38. data/lib/fluent/plugin/formatter_json.rb +1 -4
  39. data/lib/fluent/plugin/formatter_ltsv.rb +5 -6
  40. data/lib/fluent/plugin/formatter_msgpack.rb +1 -4
  41. data/lib/fluent/plugin/formatter_out_file.rb +36 -3
  42. data/lib/fluent/plugin/formatter_stdout.rb +36 -1
  43. data/lib/fluent/plugin/in_dummy.rb +9 -2
  44. data/lib/fluent/plugin/in_exec.rb +20 -57
  45. data/lib/fluent/plugin/in_forward.rb +4 -3
  46. data/lib/fluent/plugin/in_object_space.rb +8 -44
  47. data/lib/fluent/plugin/in_syslog.rb +13 -24
  48. data/lib/fluent/plugin/in_tail.rb +3 -0
  49. data/lib/fluent/plugin/out_buffered_stdout.rb +14 -4
  50. data/lib/fluent/plugin/out_exec.rb +7 -5
  51. data/lib/fluent/plugin/out_exec_filter.rb +10 -10
  52. data/lib/fluent/plugin/out_file.rb +1 -3
  53. data/lib/fluent/plugin/out_forward.rb +38 -57
  54. data/lib/fluent/plugin/out_stdout.rb +14 -5
  55. data/lib/fluent/plugin/out_stream.rb +3 -0
  56. data/lib/fluent/plugin/output.rb +31 -14
  57. data/lib/fluent/plugin/parser.rb +0 -69
  58. data/lib/fluent/plugin/parser_apache.rb +10 -6
  59. data/lib/fluent/plugin/parser_apache_error.rb +8 -3
  60. data/lib/fluent/plugin/parser_csv.rb +3 -1
  61. data/lib/fluent/plugin/parser_json.rb +1 -1
  62. data/lib/fluent/plugin/parser_multiline.rb +5 -3
  63. data/lib/fluent/plugin/parser_nginx.rb +10 -6
  64. data/lib/fluent/plugin/parser_regexp.rb +73 -0
  65. data/lib/fluent/plugin/socket_util.rb +2 -148
  66. data/lib/fluent/plugin/storage_local.rb +1 -1
  67. data/lib/fluent/plugin/string_util.rb +3 -18
  68. data/lib/fluent/plugin_helper.rb +1 -0
  69. data/lib/fluent/plugin_helper/compat_parameters.rb +166 -41
  70. data/lib/fluent/plugin_helper/formatter.rb +30 -19
  71. data/lib/fluent/plugin_helper/inject.rb +25 -12
  72. data/lib/fluent/plugin_helper/parser.rb +22 -13
  73. data/lib/fluent/plugin_helper/storage.rb +22 -13
  74. data/lib/fluent/registry.rb +19 -6
  75. data/lib/fluent/supervisor.rb +27 -1
  76. data/lib/fluent/test/driver/base.rb +16 -92
  77. data/lib/fluent/test/driver/base_owned.rb +17 -53
  78. data/lib/fluent/test/driver/base_owner.rb +125 -0
  79. data/lib/fluent/test/driver/filter.rb +24 -2
  80. data/lib/fluent/test/driver/input.rb +2 -2
  81. data/lib/fluent/test/driver/multi_output.rb +2 -2
  82. data/lib/fluent/test/driver/output.rb +3 -5
  83. data/lib/fluent/test/helpers.rb +25 -0
  84. data/lib/fluent/test/input_test.rb +4 -4
  85. data/lib/fluent/test/output_test.rb +3 -3
  86. data/lib/fluent/version.rb +1 -1
  87. data/test/config/test_element.rb +135 -6
  88. data/test/plugin/test_buf_file.rb +71 -3
  89. data/test/plugin/test_buffer.rb +305 -86
  90. data/test/plugin/test_buffer_chunk.rb +60 -2
  91. data/test/plugin/test_buffer_file_chunk.rb +4 -3
  92. data/test/plugin/test_filter_grep.rb +25 -21
  93. data/test/plugin/test_filter_record_transformer.rb +75 -67
  94. data/test/plugin/test_filter_stdout.rb +171 -74
  95. data/test/plugin/test_formatter_csv.rb +94 -0
  96. data/test/plugin/test_formatter_json.rb +30 -0
  97. data/test/plugin/test_formatter_ltsv.rb +52 -0
  98. data/test/plugin/test_formatter_msgpack.rb +28 -0
  99. data/test/plugin/test_formatter_out_file.rb +95 -0
  100. data/test/plugin/test_formatter_single_value.rb +38 -0
  101. data/test/plugin/test_in_dummy.rb +95 -0
  102. data/test/plugin/test_in_exec.rb +27 -31
  103. data/test/plugin/test_in_forward.rb +24 -0
  104. data/test/plugin/test_in_gc_stat.rb +5 -5
  105. data/test/plugin/test_in_object_space.rb +4 -4
  106. data/test/plugin/test_in_syslog.rb +60 -35
  107. data/test/plugin/test_out_buffered_stdout.rb +17 -3
  108. data/test/plugin/test_out_forward.rb +93 -5
  109. data/test/plugin/test_out_stdout.rb +14 -3
  110. data/test/plugin/test_output_as_buffered_retries.rb +20 -0
  111. data/test/plugin/test_output_as_buffered_secondary.rb +16 -0
  112. data/test/plugin/test_output_as_standard.rb +22 -22
  113. data/test/plugin/test_parser_apache.rb +13 -9
  114. data/test/plugin/test_parser_apache_error.rb +11 -6
  115. data/test/plugin/test_parser_csv.rb +35 -25
  116. data/test/plugin/test_parser_nginx.rb +11 -5
  117. data/test/plugin/test_parser_regexp.rb +235 -68
  118. data/test/plugin/test_parser_tsv.rb +54 -58
  119. data/test/plugin_helper/test_compat_parameters.rb +111 -46
  120. data/test/plugin_helper/test_formatter.rb +40 -0
  121. data/test/plugin_helper/test_inject.rb +101 -2
  122. data/test/plugin_helper/test_parser.rb +40 -0
  123. data/test/plugin_helper/test_storage.rb +43 -0
  124. data/test/test_event.rb +93 -0
  125. data/test/test_event_router.rb +13 -4
  126. data/test/test_event_time.rb +0 -3
  127. data/test/test_formatter.rb +7 -164
  128. data/test/test_plugin_classes.rb +28 -1
  129. metadata +24 -3
@@ -2,6 +2,8 @@ require_relative '../helper'
2
2
  require 'fluent/plugin_helper/compat_parameters'
3
3
  require 'fluent/plugin/base'
4
4
 
5
+ require 'time'
6
+
5
7
  class CompatParameterTest < Test::Unit::TestCase
6
8
  setup do
7
9
  Fluent::Test.setup
@@ -19,46 +21,53 @@ class CompatParameterTest < Test::Unit::TestCase
19
21
  end
20
22
  end
21
23
 
22
- class Dummy0 < Fluent::Plugin::Output
24
+ class DummyO0 < Fluent::Plugin::Output
23
25
  helpers :compat_parameters
24
- def compat_parameters_default_chunk_key
25
- ''
26
- end
27
- def write(chunk)
28
- # dummy
26
+ def configure(conf)
27
+ compat_parameters_buffer(conf, default_chunk_key: '')
28
+ super
29
29
  end
30
+ def write(chunk); end # dummy
30
31
  end
31
- class Dummy1 < Fluent::Plugin::Output
32
+ class DummyO1 < Fluent::Plugin::Output
32
33
  helpers :compat_parameters
33
- def compat_parameters_default_chunk_key
34
- 'time'
35
- end
36
- def write(chunk)
37
- # dummy
34
+ def configure(conf)
35
+ compat_parameters_buffer(conf, default_chunk_key: 'time')
36
+ super
38
37
  end
38
+ def write(chunk); end # dummy
39
39
  end
40
- class Dummy2 < Fluent::Plugin::Output
40
+ class DummyO2 < Fluent::Plugin::Output
41
41
  helpers :compat_parameters
42
- # for test to assume default key time by 'time_slice_format'
43
- def write(chunk)
44
- # dummy
42
+ def configure(conf)
43
+ compat_parameters_buffer(conf, default_chunk_key: 'time')
44
+ super
45
45
  end
46
+ def write(chunk); end # dummy
46
47
  end
47
- class Dummy3 < Fluent::Plugin::Output
48
+ class DummyO3 < Fluent::Plugin::Output
48
49
  helpers :compat_parameters
49
- def compat_parameters_default_chunk_key
50
- 'tag'
51
- end
52
- def write(chunk)
53
- # dummy
50
+ def configure(conf)
51
+ compat_parameters_buffer(conf, default_chunk_key: 'tag')
52
+ super
54
53
  end
54
+ def write(chunk); end # dummy
55
+ end
56
+ class DummyO4 < Fluent::Plugin::Output
57
+ helpers :compat_parameters, :inject, :formatter
58
+ attr_reader :f
59
+ def configure(conf)
60
+ compat_parameters_convert(conf, :buffer, :inject, :formatter, default_chunk_key: 'tag')
61
+ super
62
+ end
63
+ def start
64
+ super
65
+ @f = formatter_create()
66
+ end
67
+ def write(chunk); end # dummy
55
68
  end
56
69
 
57
- sub_test_case 'plugins which does not have default chunk key' do
58
- setup do
59
- @p = Dummy0
60
- end
61
-
70
+ sub_test_case 'output plugins which does not have default chunk key' do
62
71
  test 'plugin helper converts parameters into plugin configuration parameters' do
63
72
  hash = {
64
73
  'num_threads' => 8,
@@ -68,7 +77,7 @@ class CompatParameterTest < Test::Unit::TestCase
68
77
  'flush_at_shutdown' => 'yes',
69
78
  }
70
79
  conf = config_element('ROOT', '', hash)
71
- @i = @p.new
80
+ @i = DummyO0.new
72
81
  @i.configure(conf)
73
82
 
74
83
  assert_equal 'memory', @i.buffer_config[:@type]
@@ -82,11 +91,7 @@ class CompatParameterTest < Test::Unit::TestCase
82
91
  end
83
92
  end
84
93
 
85
- sub_test_case 'plugins which has default chunk key: time' do
86
- setup do
87
- @p = Dummy1
88
- end
89
-
94
+ sub_test_case 'output plugins which has default chunk key: time' do
90
95
  test 'plugin helper converts parameters into plugin configuration parameters' do
91
96
  hash = {
92
97
  'buffer_type' => 'file',
@@ -96,7 +101,7 @@ class CompatParameterTest < Test::Unit::TestCase
96
101
  'buffer_queue_full_action' => 'block',
97
102
  }
98
103
  conf = config_element('ROOT', '', hash)
99
- @i = @p.new
104
+ @i = DummyO1.new
100
105
  @i.configure(conf)
101
106
 
102
107
  assert_equal 'file', @i.buffer_config[:@type]
@@ -112,11 +117,7 @@ class CompatParameterTest < Test::Unit::TestCase
112
117
  end
113
118
  end
114
119
 
115
- sub_test_case 'plugins which does not have default chunk key' do
116
- setup do
117
- @p = Dummy2
118
- end
119
-
120
+ sub_test_case 'output plugins which does not have default chunk key' do
120
121
  test 'plugin helper converts parameters into plugin configuration parameters' do
121
122
  hash = {
122
123
  'buffer_type' => 'file',
@@ -127,7 +128,7 @@ class CompatParameterTest < Test::Unit::TestCase
127
128
  'buffer_queue_full_action' => 'drop_oldest_chunk',
128
129
  }
129
130
  conf = config_element('ROOT', '', hash)
130
- @i = @p.new
131
+ @i = DummyO2.new
131
132
  @i.configure(conf)
132
133
 
133
134
  assert_equal 'file', @i.buffer_config[:@type]
@@ -144,11 +145,7 @@ class CompatParameterTest < Test::Unit::TestCase
144
145
  end
145
146
  end
146
147
 
147
- sub_test_case 'plugins which has default chunk key: tag' do
148
- setup do
149
- @p = Dummy3
150
- end
151
-
148
+ sub_test_case 'output plugins which has default chunk key: tag' do
152
149
  test 'plugin helper converts parameters into plugin configuration parameters' do
153
150
  hash = {
154
151
  'buffer_type' => 'memory',
@@ -158,7 +155,7 @@ class CompatParameterTest < Test::Unit::TestCase
158
155
  'queued_chunk_flush_interval' => '0.5',
159
156
  }
160
157
  conf = config_element('ROOT', '', hash)
161
- @i = @p.new
158
+ @i = DummyO3.new
162
159
  @i.configure(conf)
163
160
 
164
161
  assert_equal 'memory', @i.buffer_config[:@type]
@@ -172,4 +169,72 @@ class CompatParameterTest < Test::Unit::TestCase
172
169
  assert_equal [], @i.chunk_keys
173
170
  end
174
171
  end
172
+
173
+ sub_test_case 'output plugins which has default chunk key: tag, and enables inject and formatter' do
174
+ test 'plugin helper converts parameters into plugin configuration parameters for all of buffer, inject and formatter' do
175
+ hash = {
176
+ 'buffer_type' => 'file',
177
+ 'buffer_path' => File.expand_path('../../tmp/compat_parameters/mybuffer.*.log', __FILE__),
178
+ 'num_threads' => '10',
179
+ 'format' => 'ltsv',
180
+ 'delimiter' => ',',
181
+ 'label_delimiter' => '%',
182
+ 'include_time_key' => 'true', # default time_key 'time' and default time format (iso8601: 2016-06-24T15:57:38) at localtime
183
+ 'include_tag_key' => 'yes', # default tag_key 'tag'
184
+ }
185
+ conf = config_element('ROOT', '', hash)
186
+ @i = DummyO4.new
187
+ @i.configure(conf)
188
+ @i.start
189
+
190
+ assert_equal 'file', @i.buffer_config[:@type]
191
+ assert_equal 10, @i.buffer_config.flush_thread_count
192
+ formatter = @i.f
193
+ assert{ formatter.is_a? Fluent::Plugin::LabeledTSVFormatter }
194
+ assert_equal ',', @i.f.delimiter
195
+ assert_equal '%', @i.f.label_delimiter
196
+
197
+ assert !@i.chunk_key_time
198
+ assert @i.chunk_key_tag
199
+ assert_equal [], @i.chunk_keys
200
+
201
+ t = event_time('2016-06-24 16:05:01') # localtime
202
+ iso8601str = Time.at(t.to_i).iso8601
203
+ formatted = @i.f.format('tag.test', t, @i.inject_values_to_record('tag.test', t, {"value" => 1}))
204
+ assert_equal "value%1,tag%tag.test,time%#{iso8601str}\n", formatted
205
+ end
206
+
207
+ test 'plugin helper setups time injecting as unix time (integer from epoch)' do
208
+ hash = {
209
+ 'buffer_type' => 'file',
210
+ 'buffer_path' => File.expand_path('../../tmp/compat_parameters/mybuffer.*.log', __FILE__),
211
+ 'num_threads' => '10',
212
+ 'format' => 'ltsv',
213
+ 'delimiter' => ',',
214
+ 'label_delimiter' => '%',
215
+ 'include_time_key' => 'true', # default time_key 'time' and default time format (iso8601: 2016-06-24T15:57:38) at localtime
216
+ 'include_tag_key' => 'yes', # default tag_key 'tag'
217
+ }
218
+ conf = config_element('ROOT', '', hash)
219
+ @i = DummyO4.new
220
+ @i.configure(conf)
221
+ @i.start
222
+
223
+ assert_equal 'file', @i.buffer_config[:@type]
224
+ assert_equal 10, @i.buffer_config.flush_thread_count
225
+ formatter = @i.f
226
+ assert{ formatter.is_a? Fluent::Plugin::LabeledTSVFormatter }
227
+ assert_equal ',', @i.f.delimiter
228
+ assert_equal '%', @i.f.label_delimiter
229
+
230
+ assert !@i.chunk_key_time
231
+ assert @i.chunk_key_tag
232
+ assert_equal [], @i.chunk_keys
233
+
234
+ t = event_time('2016-06-24 16:05:01') # localtime
235
+ iso8601str = Time.at(t.to_i).iso8601
236
+ formatted = @i.f.format('tag.test', t, @i.inject_values_to_record('tag.test', t, {"value" => 1}))
237
+ assert_equal "value%1,tag%tag.test,time%#{iso8601str}\n", formatted
238
+ end
239
+ end
175
240
  end
@@ -19,6 +19,13 @@ class FormatterHelperTest < Test::Unit::TestCase
19
19
  helpers :formatter
20
20
  end
21
21
 
22
+ class Dummy2 < Fluent::Plugin::TestBase
23
+ helpers :formatter
24
+ config_section :format do
25
+ config_set_default :@type, 'example2'
26
+ end
27
+ end
28
+
22
29
  setup do
23
30
  @d = nil
24
31
  end
@@ -37,6 +44,39 @@ class FormatterHelperTest < Test::Unit::TestCase
37
44
  assert_equal 0, d._formatters.size
38
45
  end
39
46
 
47
+ test 'can override default configuration parameters, but not overwrite whole definition' do
48
+ d = Dummy.new
49
+ assert_equal [], d.formatter_configs
50
+
51
+ d = Dummy2.new
52
+ d.configure(config_element('ROOT', '', {}, [config_element('format', '', {}, [])]))
53
+ assert_raise NoMethodError do
54
+ d.format
55
+ end
56
+ assert_equal 1, d.formatter_configs.size
57
+ assert_equal 'example2', d.formatter_configs.first[:@type]
58
+ end
59
+
60
+ test 'creates instance of type specified by conf, or default_type if @type is missing in conf' do
61
+ d = Dummy2.new
62
+ d.configure(config_element())
63
+ i = d.formatter_create(conf: config_element('format', '', {'@type' => 'example'}), default_type: 'example2')
64
+ assert{ i.is_a?(ExampleFormatter) }
65
+
66
+ d = Dummy2.new
67
+ d.configure(config_element())
68
+ i = d.formatter_create(conf: nil, default_type: 'example2')
69
+ assert{ i.is_a?(Example2Formatter) }
70
+ end
71
+
72
+ test 'raises config error if config section is specified, but @type is not specified' do
73
+ d = Dummy2.new
74
+ d.configure(config_element())
75
+ assert_raise Fluent::ConfigError.new("@type is required in <format>") do
76
+ d.formatter_create(conf: config_element('format', '', {}), default_type: 'example2')
77
+ end
78
+ end
79
+
40
80
  test 'can be configured without format sections' do
41
81
  d = Dummy.new
42
82
  assert_nothing_raised do
@@ -8,6 +8,13 @@ class InjectHelperTest < Test::Unit::TestCase
8
8
  helpers :inject
9
9
  end
10
10
 
11
+ class Dummy2 < Fluent::Plugin::TestBase
12
+ helpers :inject
13
+ config_section :inject do
14
+ config_set_default :hostname_key, 'host'
15
+ end
16
+ end
17
+
11
18
  def config_inject_section(hash = {})
12
19
  config_element('ROOT', '', {}, [config_element('inject', '', hash)])
13
20
  end
@@ -26,6 +33,17 @@ class InjectHelperTest < Test::Unit::TestCase
26
33
  end
27
34
  end
28
35
 
36
+ test 'can override default parameters, but not overwrite whole definition' do
37
+ d = Dummy.new
38
+ d.configure(config_element())
39
+ assert_nil d.inject_config
40
+
41
+ d = Dummy2.new
42
+ d.configure(config_element('ROOT', '', {}, [config_element('inject')]))
43
+ assert d.inject_config
44
+ assert_equal 'host', d.inject_config.hostname_key
45
+ end
46
+
29
47
  test 'do nothing in default' do
30
48
  @d.configure(config_inject_section())
31
49
  @d.start
@@ -75,7 +93,7 @@ class InjectHelperTest < Test::Unit::TestCase
75
93
  assert_not_nil @d.instance_eval{ @_inject_time_formatter }
76
94
  end
77
95
 
78
- sub_test_case 'using inject_record' do
96
+ sub_test_case 'using inject_values_to_record' do
79
97
  test 'injects hostname automatically detected' do
80
98
  detected_hostname = `hostname`.chomp
81
99
  @d.configure(config_inject_section("hostname_key" => "host"))
@@ -204,7 +222,8 @@ class InjectHelperTest < Test::Unit::TestCase
204
222
  assert_equal record.merge(injected), @d.inject_values_to_record('tag', time, record)
205
223
  end
206
224
  end
207
- sub_test_case 'using inject_event_stream' do
225
+
226
+ sub_test_case 'using inject_values_to_event_stream' do
208
227
  local_timezone = Time.now.strftime('%z')
209
228
  time_in_unix = Time.parse("2016-06-21 08:10:11 #{local_timezone}").to_i
210
229
  time_subsecond = 320_101_224
@@ -385,4 +404,84 @@ class InjectHelperTest < Test::Unit::TestCase
385
404
  assert_equal expected_es, @d.inject_values_to_event_stream('tag', data)
386
405
  end
387
406
  end
407
+
408
+ sub_test_case 'time formatting with modified timezone' do
409
+ setup do
410
+ @time = event_time("2014-09-27 00:00:00 +00:00").to_i
411
+ end
412
+
413
+ def with_timezone(tz)
414
+ oldtz, ENV['TZ'] = ENV['TZ'], tz
415
+ yield
416
+ ensure
417
+ ENV['TZ'] = oldtz
418
+ end
419
+
420
+ def format(conf)
421
+ @d.configure(config_inject_section(
422
+ "hostname_key" => "hostnamedata",
423
+ "hostname" => "myname.local",
424
+ "tag_key" => "tagdata",
425
+ "time_key" => "timedata",
426
+ "time_type" => "string",
427
+ "time_format" => "%Y_%m_%d %H:%M:%S.%N %z",
428
+ "timezone" => "+0000",
429
+ ))
430
+ @d.start
431
+
432
+ record = {"key1" => "value1", "key2" => 2}
433
+ injected = {"hostnamedata" => "myname.local", "tagdata" => "tag", "timedata" => "2016_06_20 23:10:11.320101224 +0000"}
434
+ assert_equal record.merge(injected), @d.inject_values_to_record('tag', time, record)
435
+
436
+
437
+ d = create_driver({'include_time_key' => true}.merge(conf))
438
+ formatted = d.instance.format("tag", @time, {})
439
+ # Drop the leading "time:" and the trailing "\n".
440
+ formatted[5..-2]
441
+ end
442
+
443
+ def test_nothing_specified_about_time_formatting
444
+ with_timezone("UTC-01") do
445
+ # 'localtime' is true by default.
446
+ @d.configure(config_inject_section("time_key" => "t", "time_type" => "string"))
447
+ @d.start
448
+ record = @d.inject_values_to_record('tag', @time, {"message" => "yay"})
449
+
450
+ assert_equal("2014-09-27T01:00:00+01:00", record['t'])
451
+ end
452
+ end
453
+
454
+ def test_utc
455
+ with_timezone("UTC-01") do
456
+ # 'utc' takes precedence over 'localtime'.
457
+ @d.configure(config_inject_section("time_key" => "t", "time_type" => "string", "utc" => "true"))
458
+ @d.start
459
+ record = @d.inject_values_to_record('tag', @time, {"message" => "yay"})
460
+
461
+ assert_equal("2014-09-27T00:00:00Z", record['t'])
462
+ end
463
+ end
464
+
465
+ def test_timezone
466
+ with_timezone("UTC-01") do
467
+ # 'timezone' takes precedence over 'localtime'.
468
+ @d.configure(config_inject_section("time_key" => "t", "time_type" => "string", "timezone" => "+02"))
469
+ @d.start
470
+ record = @d.inject_values_to_record('tag', @time, {"message" => "yay"})
471
+
472
+ assert_equal("2014-09-27T02:00:00+02:00", record['t'])
473
+ end
474
+ end
475
+
476
+ def test_utc_timezone
477
+ with_timezone("UTC-01") do
478
+ # 'timezone' takes precedence over 'utc'.
479
+ @d.configure(config_inject_section("time_key" => "t", "time_type" => "string", "timezone" => "Asia/Tokyo", "utc" => "true"))
480
+ @d.start
481
+ record = @d.inject_values_to_record('tag', @time, {"message" => "yay"})
482
+
483
+ assert_equal("2014-09-27T09:00:00+09:00", record['t'])
484
+ end
485
+ end
486
+ end
388
487
  end
@@ -30,6 +30,13 @@ class ParserHelperTest < Test::Unit::TestCase
30
30
  helpers :parser
31
31
  end
32
32
 
33
+ class Dummy2 < Fluent::Plugin::TestBase
34
+ helpers :parser
35
+ config_section :parse do
36
+ config_set_default :@type, 'example2'
37
+ end
38
+ end
39
+
33
40
  setup do
34
41
  @d = nil
35
42
  end
@@ -48,6 +55,39 @@ class ParserHelperTest < Test::Unit::TestCase
48
55
  assert_equal 0, d._parsers.size
49
56
  end
50
57
 
58
+ test 'can override default configuration parameters, but not overwrite whole definition' do
59
+ d = Dummy.new
60
+ assert_equal [], d.parser_configs
61
+
62
+ d = Dummy2.new
63
+ d.configure(config_element('ROOT', '', {}, [config_element('parse', '', {}, [])]))
64
+ assert_raise NoMethodError do
65
+ d.parse
66
+ end
67
+ assert_equal 1, d.parser_configs.size
68
+ assert_equal 'example2', d.parser_configs.first[:@type]
69
+ end
70
+
71
+ test 'creates instance of type specified by conf, or default_type if @type is missing in conf' do
72
+ d = Dummy2.new
73
+ d.configure(config_element())
74
+ i = d.parser_create(conf: config_element('parse', '', {'@type' => 'example'}), default_type: 'example2')
75
+ assert{ i.is_a?(ExampleParser) }
76
+
77
+ d = Dummy2.new
78
+ d.configure(config_element())
79
+ i = d.parser_create(conf: nil, default_type: 'example2')
80
+ assert{ i.is_a?(Example2Parser) }
81
+ end
82
+
83
+ test 'raises config error if config section is specified, but @type is not specified' do
84
+ d = Dummy2.new
85
+ d.configure(config_element())
86
+ assert_raise Fluent::ConfigError.new("@type is required in <parse>") do
87
+ d.parser_create(conf: config_element('parse', '', {}), default_type: 'example2')
88
+ end
89
+ end
90
+
51
91
  test 'can be configured without parse sections' do
52
92
  d = Dummy.new
53
93
  assert_nothing_raised do