fluentd 0.12.40 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (252) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +6 -0
  3. data/.gitignore +2 -0
  4. data/.travis.yml +33 -21
  5. data/CONTRIBUTING.md +1 -0
  6. data/ChangeLog +810 -237
  7. data/README.md +0 -25
  8. data/Rakefile +2 -1
  9. data/Vagrantfile +17 -0
  10. data/appveyor.yml +35 -0
  11. data/example/filter_stdout.conf +5 -5
  12. data/example/in_forward.conf +2 -2
  13. data/example/in_http.conf +2 -2
  14. data/example/in_out_forward.conf +17 -0
  15. data/example/in_syslog.conf +2 -2
  16. data/example/in_tail.conf +2 -2
  17. data/example/in_tcp.conf +2 -2
  18. data/example/in_udp.conf +2 -2
  19. data/example/out_copy.conf +4 -4
  20. data/example/out_file.conf +2 -2
  21. data/example/out_forward.conf +2 -2
  22. data/example/out_forward_buf_file.conf +23 -0
  23. data/example/v0_12_filter.conf +8 -8
  24. data/fluent.conf +29 -0
  25. data/fluentd.gemspec +18 -11
  26. data/lib/fluent/agent.rb +60 -58
  27. data/lib/fluent/command/cat.rb +1 -1
  28. data/lib/fluent/command/debug.rb +7 -5
  29. data/lib/fluent/command/fluentd.rb +97 -2
  30. data/lib/fluent/compat/call_super_mixin.rb +67 -0
  31. data/lib/fluent/compat/filter.rb +50 -0
  32. data/lib/fluent/compat/formatter.rb +109 -0
  33. data/lib/fluent/compat/input.rb +50 -0
  34. data/lib/fluent/compat/output.rb +617 -0
  35. data/lib/fluent/compat/output_chain.rb +60 -0
  36. data/lib/fluent/compat/parser.rb +163 -0
  37. data/lib/fluent/compat/propagate_default.rb +62 -0
  38. data/lib/fluent/config.rb +23 -20
  39. data/lib/fluent/config/configure_proxy.rb +119 -70
  40. data/lib/fluent/config/dsl.rb +5 -18
  41. data/lib/fluent/config/element.rb +72 -8
  42. data/lib/fluent/config/error.rb +0 -3
  43. data/lib/fluent/config/literal_parser.rb +0 -2
  44. data/lib/fluent/config/parser.rb +4 -4
  45. data/lib/fluent/config/section.rb +39 -28
  46. data/lib/fluent/config/types.rb +2 -13
  47. data/lib/fluent/config/v1_parser.rb +1 -3
  48. data/lib/fluent/configurable.rb +48 -16
  49. data/lib/fluent/daemon.rb +15 -0
  50. data/lib/fluent/engine.rb +26 -52
  51. data/lib/fluent/env.rb +6 -4
  52. data/lib/fluent/event.rb +58 -11
  53. data/lib/fluent/event_router.rb +5 -5
  54. data/lib/fluent/filter.rb +2 -50
  55. data/lib/fluent/formatter.rb +4 -293
  56. data/lib/fluent/input.rb +2 -32
  57. data/lib/fluent/label.rb +2 -2
  58. data/lib/fluent/load.rb +3 -2
  59. data/lib/fluent/log.rb +107 -38
  60. data/lib/fluent/match.rb +0 -36
  61. data/lib/fluent/mixin.rb +117 -7
  62. data/lib/fluent/msgpack_factory.rb +62 -0
  63. data/lib/fluent/output.rb +7 -612
  64. data/lib/fluent/output_chain.rb +23 -0
  65. data/lib/fluent/parser.rb +4 -800
  66. data/lib/fluent/plugin.rb +100 -121
  67. data/lib/fluent/plugin/bare_output.rb +63 -0
  68. data/lib/fluent/plugin/base.rb +121 -0
  69. data/lib/fluent/plugin/buf_file.rb +101 -182
  70. data/lib/fluent/plugin/buf_memory.rb +9 -92
  71. data/lib/fluent/plugin/buffer.rb +473 -0
  72. data/lib/fluent/plugin/buffer/chunk.rb +135 -0
  73. data/lib/fluent/plugin/buffer/file_chunk.rb +339 -0
  74. data/lib/fluent/plugin/buffer/memory_chunk.rb +100 -0
  75. data/lib/fluent/plugin/exec_util.rb +80 -75
  76. data/lib/fluent/plugin/file_util.rb +33 -28
  77. data/lib/fluent/plugin/file_wrapper.rb +120 -0
  78. data/lib/fluent/plugin/filter.rb +51 -0
  79. data/lib/fluent/plugin/filter_grep.rb +13 -40
  80. data/lib/fluent/plugin/filter_record_transformer.rb +22 -18
  81. data/lib/fluent/plugin/formatter.rb +93 -0
  82. data/lib/fluent/plugin/formatter_csv.rb +48 -0
  83. data/lib/fluent/plugin/formatter_hash.rb +32 -0
  84. data/lib/fluent/plugin/formatter_json.rb +47 -0
  85. data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
  86. data/lib/fluent/plugin/formatter_msgpack.rb +32 -0
  87. data/lib/fluent/plugin/formatter_out_file.rb +45 -0
  88. data/lib/fluent/plugin/formatter_single_value.rb +34 -0
  89. data/lib/fluent/plugin/formatter_stdout.rb +39 -0
  90. data/lib/fluent/plugin/in_debug_agent.rb +4 -0
  91. data/lib/fluent/plugin/in_dummy.rb +22 -18
  92. data/lib/fluent/plugin/in_exec.rb +18 -8
  93. data/lib/fluent/plugin/in_forward.rb +36 -79
  94. data/lib/fluent/plugin/in_gc_stat.rb +4 -0
  95. data/lib/fluent/plugin/in_http.rb +21 -18
  96. data/lib/fluent/plugin/in_monitor_agent.rb +15 -48
  97. data/lib/fluent/plugin/in_object_space.rb +6 -1
  98. data/lib/fluent/plugin/in_stream.rb +7 -3
  99. data/lib/fluent/plugin/in_syslog.rb +46 -95
  100. data/lib/fluent/plugin/in_tail.rb +51 -595
  101. data/lib/fluent/plugin/in_tcp.rb +8 -1
  102. data/lib/fluent/plugin/in_udp.rb +8 -14
  103. data/lib/fluent/plugin/input.rb +33 -0
  104. data/lib/fluent/plugin/multi_output.rb +95 -0
  105. data/lib/fluent/plugin/out_buffered_null.rb +59 -0
  106. data/lib/fluent/plugin/out_copy.rb +11 -7
  107. data/lib/fluent/plugin/out_exec.rb +15 -11
  108. data/lib/fluent/plugin/out_exec_filter.rb +18 -10
  109. data/lib/fluent/plugin/out_file.rb +34 -5
  110. data/lib/fluent/plugin/out_forward.rb +19 -9
  111. data/lib/fluent/plugin/out_null.rb +0 -14
  112. data/lib/fluent/plugin/out_roundrobin.rb +11 -7
  113. data/lib/fluent/plugin/out_stdout.rb +5 -7
  114. data/lib/fluent/plugin/out_stream.rb +3 -1
  115. data/lib/fluent/plugin/output.rb +979 -0
  116. data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
  117. data/lib/fluent/plugin/parser.rb +244 -0
  118. data/lib/fluent/plugin/parser_apache.rb +24 -0
  119. data/lib/fluent/plugin/parser_apache2.rb +84 -0
  120. data/lib/fluent/plugin/parser_apache_error.rb +21 -0
  121. data/lib/fluent/plugin/parser_csv.rb +31 -0
  122. data/lib/fluent/plugin/parser_json.rb +79 -0
  123. data/lib/fluent/plugin/parser_ltsv.rb +50 -0
  124. data/lib/fluent/plugin/parser_multiline.rb +102 -0
  125. data/lib/fluent/plugin/parser_nginx.rb +24 -0
  126. data/lib/fluent/plugin/parser_none.rb +36 -0
  127. data/lib/fluent/plugin/parser_syslog.rb +82 -0
  128. data/lib/fluent/plugin/parser_tsv.rb +37 -0
  129. data/lib/fluent/plugin/socket_util.rb +120 -114
  130. data/lib/fluent/plugin/storage.rb +84 -0
  131. data/lib/fluent/plugin/storage_local.rb +116 -0
  132. data/lib/fluent/plugin/string_util.rb +16 -13
  133. data/lib/fluent/plugin_helper.rb +39 -0
  134. data/lib/fluent/plugin_helper/child_process.rb +298 -0
  135. data/lib/fluent/plugin_helper/compat_parameters.rb +99 -0
  136. data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
  137. data/lib/fluent/plugin_helper/event_loop.rb +118 -0
  138. data/lib/fluent/plugin_helper/retry_state.rb +177 -0
  139. data/lib/fluent/plugin_helper/storage.rb +308 -0
  140. data/lib/fluent/plugin_helper/thread.rb +147 -0
  141. data/lib/fluent/plugin_helper/timer.rb +85 -0
  142. data/lib/fluent/plugin_id.rb +63 -0
  143. data/lib/fluent/process.rb +21 -30
  144. data/lib/fluent/registry.rb +21 -9
  145. data/lib/fluent/root_agent.rb +115 -40
  146. data/lib/fluent/supervisor.rb +330 -320
  147. data/lib/fluent/system_config.rb +42 -18
  148. data/lib/fluent/test.rb +6 -1
  149. data/lib/fluent/test/base.rb +23 -3
  150. data/lib/fluent/test/driver/base.rb +247 -0
  151. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  152. data/lib/fluent/test/driver/filter.rb +35 -0
  153. data/lib/fluent/test/driver/input.rb +31 -0
  154. data/lib/fluent/test/driver/output.rb +78 -0
  155. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  156. data/lib/fluent/test/filter_test.rb +0 -1
  157. data/lib/fluent/test/formatter_test.rb +2 -1
  158. data/lib/fluent/test/input_test.rb +23 -17
  159. data/lib/fluent/test/output_test.rb +28 -39
  160. data/lib/fluent/test/parser_test.rb +1 -1
  161. data/lib/fluent/time.rb +104 -1
  162. data/lib/fluent/{status.rb → unique_id.rb} +15 -24
  163. data/lib/fluent/version.rb +1 -1
  164. data/lib/fluent/winsvc.rb +72 -0
  165. data/test/compat/test_calls_super.rb +164 -0
  166. data/test/config/test_config_parser.rb +83 -0
  167. data/test/config/test_configurable.rb +547 -274
  168. data/test/config/test_configure_proxy.rb +146 -29
  169. data/test/config/test_dsl.rb +3 -181
  170. data/test/config/test_element.rb +274 -0
  171. data/test/config/test_literal_parser.rb +1 -1
  172. data/test/config/test_section.rb +79 -7
  173. data/test/config/test_system_config.rb +21 -0
  174. data/test/config/test_types.rb +3 -26
  175. data/test/helper.rb +78 -8
  176. data/test/plugin/test_bare_output.rb +118 -0
  177. data/test/plugin/test_base.rb +75 -0
  178. data/test/plugin/test_buf_file.rb +420 -521
  179. data/test/plugin/test_buf_memory.rb +32 -194
  180. data/test/plugin/test_buffer.rb +981 -0
  181. data/test/plugin/test_buffer_chunk.rb +110 -0
  182. data/test/plugin/test_buffer_file_chunk.rb +770 -0
  183. data/test/plugin/test_buffer_memory_chunk.rb +265 -0
  184. data/test/plugin/test_filter.rb +255 -0
  185. data/test/plugin/test_filter_grep.rb +2 -73
  186. data/test/plugin/test_filter_record_transformer.rb +24 -68
  187. data/test/plugin/test_filter_stdout.rb +6 -6
  188. data/test/plugin/test_in_debug_agent.rb +2 -0
  189. data/test/plugin/test_in_dummy.rb +11 -17
  190. data/test/plugin/test_in_exec.rb +6 -25
  191. data/test/plugin/test_in_forward.rb +112 -151
  192. data/test/plugin/test_in_gc_stat.rb +2 -0
  193. data/test/plugin/test_in_http.rb +106 -157
  194. data/test/plugin/test_in_object_space.rb +21 -5
  195. data/test/plugin/test_in_stream.rb +14 -13
  196. data/test/plugin/test_in_syslog.rb +30 -275
  197. data/test/plugin/test_in_tail.rb +95 -234
  198. data/test/plugin/test_in_tcp.rb +14 -0
  199. data/test/plugin/test_in_udp.rb +21 -13
  200. data/test/plugin/test_input.rb +122 -0
  201. data/test/plugin/test_multi_output.rb +180 -0
  202. data/test/plugin/test_out_buffered_null.rb +79 -0
  203. data/test/plugin/test_out_copy.rb +15 -2
  204. data/test/plugin/test_out_exec.rb +75 -25
  205. data/test/plugin/test_out_exec_filter.rb +74 -8
  206. data/test/plugin/test_out_file.rb +61 -7
  207. data/test/plugin/test_out_forward.rb +92 -15
  208. data/test/plugin/test_out_roundrobin.rb +1 -0
  209. data/test/plugin/test_out_stdout.rb +22 -13
  210. data/test/plugin/test_out_stream.rb +18 -0
  211. data/test/plugin/test_output.rb +515 -0
  212. data/test/plugin/test_output_as_buffered.rb +1540 -0
  213. data/test/plugin/test_output_as_buffered_overflow.rb +247 -0
  214. data/test/plugin/test_output_as_buffered_retries.rb +808 -0
  215. data/test/plugin/test_output_as_buffered_secondary.rb +776 -0
  216. data/test/plugin/test_output_as_standard.rb +362 -0
  217. data/test/plugin/test_owned_by.rb +35 -0
  218. data/test/plugin/test_storage.rb +167 -0
  219. data/test/plugin/test_storage_local.rb +8 -0
  220. data/test/plugin_helper/test_child_process.rb +599 -0
  221. data/test/plugin_helper/test_compat_parameters.rb +175 -0
  222. data/test/plugin_helper/test_event_emitter.rb +51 -0
  223. data/test/plugin_helper/test_event_loop.rb +52 -0
  224. data/test/plugin_helper/test_retry_state.rb +399 -0
  225. data/test/plugin_helper/test_storage.rb +411 -0
  226. data/test/plugin_helper/test_thread.rb +164 -0
  227. data/test/plugin_helper/test_timer.rb +100 -0
  228. data/test/scripts/exec_script.rb +0 -6
  229. data/test/scripts/fluent/plugin/out_test.rb +3 -0
  230. data/test/test_config.rb +13 -4
  231. data/test/test_event.rb +24 -13
  232. data/test/test_event_router.rb +8 -7
  233. data/test/test_event_time.rb +187 -0
  234. data/test/test_formatter.rb +13 -51
  235. data/test/test_input.rb +1 -1
  236. data/test/test_log.rb +239 -16
  237. data/test/test_mixin.rb +1 -1
  238. data/test/test_output.rb +53 -66
  239. data/test/test_parser.rb +105 -323
  240. data/test/test_plugin_helper.rb +81 -0
  241. data/test/test_root_agent.rb +4 -52
  242. data/test/test_supervisor.rb +272 -0
  243. data/test/test_unique_id.rb +47 -0
  244. metadata +180 -54
  245. data/lib/fluent/buffer.rb +0 -365
  246. data/lib/fluent/plugin/filter_parser.rb +0 -107
  247. data/lib/fluent/plugin/in_status.rb +0 -76
  248. data/lib/fluent/test/helpers.rb +0 -86
  249. data/test/plugin/data/log/foo/bar2 +0 -0
  250. data/test/plugin/test_filter_parser.rb +0 -744
  251. data/test/plugin/test_in_status.rb +0 -38
  252. data/test/test_buffer.rb +0 -624
@@ -1,5 +1,6 @@
1
1
  require_relative '../helper'
2
2
  require 'fluent/test'
3
+ require 'fluent/plugin/out_copy'
3
4
 
4
5
  class CopyOutputTest < Test::Unit::TestCase
5
6
  class << self
@@ -107,7 +108,19 @@ class CopyOutputTest < Test::Unit::TestCase
107
108
 
108
109
  def create_event_test_driver(is_deep_copy = false)
109
110
  deep_copy_config = %[
110
- deep_copy true
111
+ deep_copy #{is_deep_copy}
112
+ <store>
113
+ type test
114
+ name c0
115
+ </store>
116
+ <store>
117
+ type test
118
+ name c1
119
+ </store>
120
+ <store>
121
+ type test
122
+ name c2
123
+ </store>
111
124
  ]
112
125
 
113
126
  output1 = Fluent::Plugin.new_output('test')
@@ -130,7 +143,7 @@ deep_copy true
130
143
  outputs = [output1, output2]
131
144
 
132
145
  d = Fluent::Test::OutputTestDriver.new(Fluent::CopyOutput)
133
- d = d.configure(deep_copy_config) if is_deep_copy
146
+ d = d.configure(deep_copy_config)
134
147
  d.instance.instance_eval { @outputs = outputs }
135
148
  d
136
149
  end
@@ -1,11 +1,18 @@
1
1
  require_relative '../helper'
2
- require 'fluent/test'
2
+ require 'fluent/test/driver/output'
3
+ require 'fluent/plugin/out_exec'
3
4
  require 'fileutils'
4
5
 
5
6
  class ExecOutputTest < Test::Unit::TestCase
6
7
  def setup
7
8
  Fluent::Test.setup
8
- FileUtils.rm_rf(TMP_DIR)
9
+ FileUtils.rm_rf(TMP_DIR, secure: true)
10
+ if File.exist?(TMP_DIR)
11
+ # ensure files are closed for Windows, on which deleted files
12
+ # are still visible from filesystem
13
+ GC.start(full_mark: true, immediate_sweep: true)
14
+ FileUtils.remove_entry_secure(TMP_DIR)
15
+ end
9
16
  FileUtils.mkdir_p(TMP_DIR)
10
17
  end
11
18
 
@@ -25,7 +32,7 @@ class ExecOutputTest < Test::Unit::TestCase
25
32
 
26
33
  def create_driver(conf = TSV_CONFIG)
27
34
  config = CONFIG + conf
28
- Fluent::Test::TimeSlicedOutputTestDriver.new(Fluent::ExecOutput).configure(config, true)
35
+ Fluent::Test::Driver::Output.new(Fluent::Plugin::ExecOutput).configure(config)
29
36
  end
30
37
 
31
38
  def create_test_case
@@ -44,55 +51,98 @@ class ExecOutputTest < Test::Unit::TestCase
44
51
  assert_equal true, d.instance.localtime
45
52
  end
46
53
 
54
+ def test_configure_with_compat_buffer_parameters
55
+ conf = TSV_CONFIG + %[
56
+ buffer_type memory
57
+ time_slice_format %Y%m%d%H
58
+ num_threads 5
59
+ buffer_chunk_limit 50m
60
+ buffer_queue_limit 128
61
+ flush_at_shutdown yes
62
+ ]
63
+ d = create_driver(conf)
64
+ assert_equal 3600, d.instance.buffer_config.timekey
65
+ assert_equal 5, d.instance.buffer_config.flush_thread_count
66
+ assert_equal 50*1024*1024, d.instance.buffer.chunk_limit_size
67
+ assert_equal 128, d.instance.buffer.queue_length_limit
68
+ assert d.instance.buffer_config.flush_at_shutdown
69
+ end
70
+
47
71
  def test_format
48
72
  d = create_driver
49
73
  time, tests = create_test_case
50
74
 
51
- tests.each { |test|
52
- d.emit(test, time)
53
- }
54
-
55
- d.expect_format %[2011-01-02 13:14:15\ttest\tv1\n]
56
- d.expect_format %[2011-01-02 13:14:15\ttest\tv2\n]
75
+ d.run(default_tag: 'test') do
76
+ d.feed(time, tests[0])
77
+ d.feed(time, tests[1])
78
+ end
57
79
 
58
- d.run
80
+ assert_equal %[2011-01-02 13:14:15\ttest\tv1\n], d.formatted[0]
81
+ assert_equal %[2011-01-02 13:14:15\ttest\tv2\n], d.formatted[1]
59
82
  end
60
83
 
61
84
  def test_format_json
62
85
  d = create_driver("format json")
63
86
  time, tests = create_test_case
64
87
 
65
- tests.each { |test|
66
- d.emit(test, time)
67
- d.expect_format Yajl.dump(test) + "\n"
68
- }
88
+ d.run(default_tag: 'test') do
89
+ d.feed(time, tests[0])
90
+ d.feed(time, tests[1])
91
+ end
69
92
 
70
- d.run
93
+ assert_equal Yajl.dump(tests[0]) + "\n", d.formatted[0]
94
+ assert_equal Yajl.dump(tests[1]) + "\n", d.formatted[1]
71
95
  end
72
96
 
73
97
  def test_format_msgpack
74
98
  d = create_driver("format msgpack")
75
99
  time, tests = create_test_case
76
100
 
77
- tests.each { |test|
78
- d.emit(test, time)
79
- d.expect_format test.to_msgpack
80
- }
101
+ d.run(default_tag: 'test') do
102
+ d.feed(time, tests[0])
103
+ d.feed(time, tests[1])
104
+ end
105
+
106
+ assert_equal tests[0].to_msgpack, d.formatted[0]
107
+ assert_equal tests[1].to_msgpack, d.formatted[1]
108
+ end
109
+
110
+ def test_format_time
111
+ config = %[
112
+ keys "time,tag,k1"
113
+ tag_key "tag"
114
+ time_key "time"
115
+ time_format %Y-%m-%d %H:%M:%S.%3N
116
+ ]
117
+ d = create_driver(config)
81
118
 
82
- d.run
119
+ time = event_time("2011-01-02 13:14:15.123")
120
+ tests = [{"k1"=>"v1","kx"=>"vx"}, {"k1"=>"v2","kx"=>"vx"}]
121
+
122
+ d.run(default_tag: 'test') do
123
+ d.feed(time, tests[0])
124
+ d.feed(time, tests[1])
125
+ end
126
+
127
+ assert_equal %[2011-01-02 13:14:15.123\ttest\tv1\n], d.formatted[0]
128
+ assert_equal %[2011-01-02 13:14:15.123\ttest\tv2\n], d.formatted[1]
83
129
  end
84
130
 
85
131
  def test_write
86
132
  d = create_driver
87
133
  time, tests = create_test_case
88
134
 
89
- tests.each { |test|
90
- d.emit(test, time)
91
- }
92
-
93
- d.run
135
+ d.run(default_tag: 'test', flush: true) do
136
+ d.feed(time, tests[0])
137
+ d.feed(time, tests[1])
138
+ end
94
139
 
95
140
  expect_path = "#{TMP_DIR}/out"
141
+
142
+ waiting(10, plugin: d.instance) do
143
+ sleep(0.1) until File.exist?(expect_path)
144
+ end
145
+
96
146
  assert_equal true, File.exist?(expect_path)
97
147
 
98
148
  data = File.read(expect_path)
@@ -1,5 +1,6 @@
1
1
  require_relative '../helper'
2
2
  require 'fluent/test'
3
+ require 'fluent/plugin/out_exec_filter'
3
4
  require 'fileutils'
4
5
 
5
6
  class ExecFilterOutputTest < Test::Unit::TestCase
@@ -20,12 +21,12 @@ class ExecFilterOutputTest < Test::Unit::TestCase
20
21
  ]
21
22
 
22
23
  def create_driver(conf = CONFIG, tag = 'test')
23
- Fluent::Test::OutputTestDriver.new(Fluent::ExecFilterOutput, tag).configure(conf)
24
+ Fluent::Test::BufferedOutputTestDriver.new(Fluent::ExecFilterOutput, tag).configure(conf)
24
25
  end
25
26
 
26
27
  def sed_unbuffered_support?
27
28
  @sed_unbuffered_support ||= lambda {
28
- system("echo xxx | sed --unbuffered -l -e 's/x/y/g' >/dev/null 2>&1")
29
+ system("echo xxx | sed --unbuffered -l -e 's/x/y/g' >#{IO::NULL} 2>&1")
29
30
  $?.success?
30
31
  }.call
31
32
  end
@@ -37,6 +38,8 @@ class ExecFilterOutputTest < Test::Unit::TestCase
37
38
  def test_configure
38
39
  d = create_driver
39
40
 
41
+ assert d.instance.instance_eval{ @overrides_format_stream }
42
+
40
43
  assert_equal ["time_in","tag","k1"], d.instance.in_keys
41
44
  assert_equal ["time_out","tag","k2"], d.instance.out_keys
42
45
  assert_equal "tag", d.instance.out_tag_key
@@ -69,8 +72,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
69
72
  def test_emit_1
70
73
  d = create_driver
71
74
 
72
- time = Time.parse("2011-01-02 13:14:15").to_i
75
+ time = Fluent::EventTime.parse("2011-01-02 13:14:15")
73
76
 
77
+ d.expected_emits_length = 2
74
78
  d.run do
75
79
  d.emit({"k1"=>1}, time)
76
80
  d.emit({"k1"=>2}, time)
@@ -79,7 +83,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
79
83
  emits = d.emits
80
84
  assert_equal 2, emits.length
81
85
  assert_equal ["test", time, {"k2"=>"1"}], emits[0]
86
+ assert_equal_event_time time, emits[0][1]
82
87
  assert_equal ["test", time, {"k2"=>"2"}], emits[1]
88
+ assert_equal_event_time time, emits[1][1]
83
89
  end
84
90
 
85
91
  def test_emit_2
@@ -92,8 +98,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
92
98
  num_children 3
93
99
  ]
94
100
 
95
- time = Time.parse("2011-01-02 13:14:15").to_i
101
+ time = Fluent::EventTime.parse("2011-01-02 13:14:15")
96
102
 
103
+ d.expected_emits_length = 2
97
104
  d.run do
98
105
  d.emit({"k1"=>1}, time)
99
106
  d.emit({"k1"=>2}, time)
@@ -102,7 +109,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
102
109
  emits = d.emits
103
110
  assert_equal 2, emits.length
104
111
  assert_equal ["xxx", time, {"k2"=>"1"}], emits[0]
112
+ assert_equal_event_time time, emits[0][1]
105
113
  assert_equal ["xxx", time, {"k2"=>"2"}], emits[1]
114
+ assert_equal_event_time time, emits[1][1]
106
115
  end
107
116
 
108
117
  def test_emit_3
@@ -115,8 +124,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
115
124
  num_children 3
116
125
  ]
117
126
 
118
- time = Time.parse("2011-01-02 13:14:15").to_i
127
+ time = Fluent::EventTime.parse("2011-01-02 13:14:15")
119
128
 
129
+ d.expected_emits_length = 2
120
130
  d.run do
121
131
  d.emit({"val1"=>"sed-ed value foo"}, time)
122
132
  d.emit({"val1"=>"sed-ed value poo"}, time)
@@ -125,6 +135,7 @@ class ExecFilterOutputTest < Test::Unit::TestCase
125
135
  emits = d.emits
126
136
  assert_equal 1, emits.length
127
137
  assert_equal ["xxx", time, {"val2"=>"sed-ed value foo"}], emits[0]
138
+ assert_equal_event_time time, emits[0][1]
128
139
 
129
140
  d = create_driver %[
130
141
  command sed #{sed_unbuffered_option} -l -e s/foo/bar/
@@ -135,8 +146,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
135
146
  num_children 3
136
147
  ]
137
148
 
138
- time = Time.parse("2011-01-02 13:14:15").to_i
149
+ time = Fluent::EventTime.parse("2011-01-02 13:14:15")
139
150
 
151
+ d.expected_emits_length = 2
140
152
  d.run do
141
153
  d.emit({"val1"=>"sed-ed value foo"}, time)
142
154
  d.emit({"val1"=>"sed-ed value poo"}, time)
@@ -145,7 +157,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
145
157
  emits = d.emits
146
158
  assert_equal 2, emits.length
147
159
  assert_equal ["xxx", time, {"val2"=>"sed-ed value bar"}], emits[0]
160
+ assert_equal_event_time time, emits[0][1]
148
161
  assert_equal ["xxx", time, {"val2"=>"sed-ed value poo"}], emits[1]
162
+ assert_equal_event_time time, emits[1][1]
149
163
  end
150
164
 
151
165
  def test_emit_4
@@ -160,8 +174,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
160
174
  num_children 3
161
175
  ], 'input.test')
162
176
 
163
- time = Time.parse("2011-01-02 13:14:15").to_i
177
+ time = Fluent::EventTime.parse("2011-01-02 13:14:15")
164
178
 
179
+ d.expected_emits_length = 2
165
180
  d.run do
166
181
  d.emit({"val1"=>"sed-ed value foo"}, time)
167
182
  d.emit({"val1"=>"sed-ed value poo"}, time)
@@ -170,7 +185,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
170
185
  emits = d.emits
171
186
  assert_equal 2, emits.length
172
187
  assert_equal ["output.test", time, {"val2"=>"sed-ed value bar"}], emits[0]
188
+ assert_equal_event_time time, emits[0][1]
173
189
  assert_equal ["output.test", time, {"val2"=>"sed-ed value poo"}], emits[1]
190
+ assert_equal_event_time time, emits[1][1]
174
191
  end
175
192
 
176
193
  def test_json_1
@@ -182,8 +199,9 @@ class ExecFilterOutputTest < Test::Unit::TestCase
182
199
  tag_key tag
183
200
  ], 'input.test')
184
201
 
185
- time = Time.parse("2011-01-02 13:14:15").to_i
202
+ time = Fluent::EventTime.parse("2011-01-02 13:14:15")
186
203
 
204
+ d.expected_emits_length = 1
187
205
  d.run do
188
206
  d.emit({"message"=>%[{"time":#{time},"tag":"t1","k1":"v1"}]}, time+10)
189
207
  end
@@ -191,6 +209,54 @@ class ExecFilterOutputTest < Test::Unit::TestCase
191
209
  emits = d.emits
192
210
  assert_equal 1, emits.length
193
211
  assert_equal ["t1", time, {"k1"=>"v1"}], emits[0]
212
+ assert_equal_event_time time, emits[0][1]
213
+ end
214
+
215
+ def test_json_with_float_time
216
+ d = create_driver(%[
217
+ command cat
218
+ in_keys message
219
+ out_format json
220
+ time_key time
221
+ tag_key tag
222
+ ], 'input.test')
223
+
224
+ float_time = Time.parse("2011-01-02 13:14:15").to_f
225
+ time = Fluent::EventTime.from_time(Time.at(float_time))
226
+
227
+ d.expected_emits_length = 1
228
+ d.run do
229
+ d.emit({"message"=>%[{"time":#{float_time},"tag":"t1","k1":"v1"}]}, time+10)
230
+ end
231
+
232
+ emits = d.emits
233
+ assert_equal 1, emits.length
234
+ assert_equal ["t1", time, {"k1"=>"v1"}], emits[0]
235
+ assert_equal_event_time time, emits[0][1]
236
+ end
237
+
238
+ def test_json_with_time_format
239
+ d = create_driver(%[
240
+ command cat
241
+ in_keys message
242
+ out_format json
243
+ time_key time
244
+ time_format %d/%b/%Y %H:%M:%S.%N %z
245
+ tag_key tag
246
+ ], 'input.test')
247
+
248
+ time_str = "28/Feb/2013 12:00:00.123456789 +0900"
249
+ time = Fluent::EventTime.from_time(Time.strptime(time_str, "%d/%b/%Y %H:%M:%S.%N %z"))
250
+
251
+ d.expected_emits_length = 1
252
+ d.run do
253
+ d.emit({"message"=>%[{"time":"#{time_str}","tag":"t1","k1":"v1"}]}, time+10)
254
+ end
255
+
256
+ emits = d.emits
257
+ assert_equal 1, emits.length
258
+ assert_equal ["t1", time, {"k1"=>"v1"}], emits[0]
259
+ assert_equal_event_time time, emits[0][1]
194
260
  end
195
261
  end
196
262
 
@@ -1,5 +1,6 @@
1
1
  require_relative '../helper'
2
2
  require 'fluent/test'
3
+ require 'fluent/plugin/out_file'
3
4
  require 'fileutils'
4
5
  require 'time'
5
6
 
@@ -62,7 +63,7 @@ class FileOutputTest < Test::Unit::TestCase
62
63
  d = create_driver(%[path #{TMP_DIR}/out_file_test])
63
64
  time = Time.parse("2011-01-02 13:14:15 UTC").to_i
64
65
 
65
- with_timezone('Asia/Taipei') do
66
+ with_timezone(Fluent.windows? ? 'NST-8' : 'Asia/Taipei') do
66
67
  d.emit({"a"=>1}, time)
67
68
  d.expect_format %[2011-01-02T21:14:15+08:00\ttest\t{"a":1}\n]
68
69
  d.run
@@ -121,7 +122,7 @@ class FileOutputTest < Test::Unit::TestCase
121
122
  # Zlib::GzipReader has a bug of concatenated file: https://bugs.ruby-lang.org/issues/9790
122
123
  # Following code from https://www.ruby-forum.com/topic/971591#979520
123
124
  result = ''
124
- File.open(path) { |io|
125
+ File.open(path, "rb") { |io|
125
126
  loop do
126
127
  gzr = Zlib::GzipReader.new(io)
127
128
  result << gzr.read
@@ -150,6 +151,54 @@ class FileOutputTest < Test::Unit::TestCase
150
151
  check_gzipped_result(paths[0], %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n])
151
152
  end
152
153
 
154
+ class TestWithSystem < self
155
+ TMP_DIR_WITH_SYSTEM = File.expand_path(File.dirname(__FILE__) + "/../tmp/out_file_system#{ENV['TEST_ENV_NUMBER']}")
156
+ # 0750 interprets as "488". "488".to_i(8) # => 4. So, it makes wrong permission. Umm....
157
+ OVERRIDE_DIR_PERMISSION = 750
158
+ OVERRIDE_FILE_PERMISSION = 0620
159
+ CONFIG_WITH_SYSTEM = %[
160
+ path #{TMP_DIR_WITH_SYSTEM}/out_file_test
161
+ compress gz
162
+ utc
163
+ <system>
164
+ file_permission #{OVERRIDE_FILE_PERMISSION}
165
+ dir_permission #{OVERRIDE_DIR_PERMISSION}
166
+ </system>
167
+ ]
168
+
169
+ def setup
170
+ omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?
171
+ FileUtils.rm_rf(TMP_DIR_WITH_SYSTEM)
172
+ end
173
+
174
+ def parse_system(text)
175
+ basepath = File.expand_path(File.dirname(__FILE__) + '/../../')
176
+ Fluent::Config.parse(text, '(test)', basepath, true).elements.find { |e| e.name == 'system' }
177
+ end
178
+
179
+ def test_write_with_system
180
+ system_conf = parse_system(CONFIG_WITH_SYSTEM)
181
+ sc = Fluent::SystemConfig.new(system_conf)
182
+ Fluent::Engine.init(sc)
183
+ d = create_driver CONFIG_WITH_SYSTEM
184
+
185
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
186
+ d.emit({"a"=>1}, time)
187
+ d.emit({"a"=>2}, time)
188
+
189
+ # FileOutput#write returns path
190
+ paths = d.run
191
+ expect_paths = ["#{TMP_DIR_WITH_SYSTEM}/out_file_test.20110102_0.log.gz"]
192
+ assert_equal expect_paths, paths
193
+
194
+ check_gzipped_result(paths[0], %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n])
195
+ dir_mode = "%o" % File::stat(TMP_DIR_WITH_SYSTEM).mode
196
+ assert_equal(OVERRIDE_DIR_PERMISSION, dir_mode[-3, 3].to_i)
197
+ file_mode = "%o" % File::stat(paths[0]).mode
198
+ assert_equal(OVERRIDE_FILE_PERMISSION, file_mode[-3, 3].to_i)
199
+ end
200
+ end
201
+
153
202
  def test_write_with_format_json
154
203
  d = create_driver [CONFIG, 'format json', 'include_time_key true', 'time_as_epoch'].join("\n")
155
204
 
@@ -245,28 +294,33 @@ class FileOutputTest < Test::Unit::TestCase
245
294
  end
246
295
 
247
296
  def test_write_with_symlink
297
+ omit "Windows doesn't support symlink" if Fluent.windows?
248
298
  conf = CONFIG + %[
249
299
  symlink_path #{SYMLINK_PATH}
250
300
  ]
251
301
  symlink_path = "#{SYMLINK_PATH}"
252
302
 
253
- Fluent::FileBuffer.clear_buffer_paths
254
303
  d = Fluent::Test::TestDriver.new(Fluent::FileOutput).configure(conf)
255
304
 
256
305
  begin
257
306
  d.instance.start
258
307
  10.times { sleep 0.05 }
308
+
259
309
  time = Time.parse("2011-01-02 13:14:15 UTC").to_i
260
310
  es = Fluent::OneEventStream.new(time, {"a"=>1})
261
- d.instance.emit('tag', es, Fluent::NullOutputChain.instance)
311
+ d.instance.emit_events('tag', es)
262
312
 
263
- assert File.exists?(symlink_path)
313
+ assert File.exist?(symlink_path)
264
314
  assert File.symlink?(symlink_path)
265
315
 
266
- d.instance.enqueue_buffer
316
+ es = Fluent::OneEventStream.new(event_time("2011-01-03 14:15:16 UTC"), {"a"=>2})
317
+ d.instance.emit_events('tag', es)
267
318
 
268
- assert !File.exists?(symlink_path)
319
+ assert File.exist?(symlink_path)
269
320
  assert File.symlink?(symlink_path)
321
+
322
+ meta = d.instance.metadata('tag', event_time("2011-01-03 14:15:16 UTC"), {})
323
+ assert_equal d.instance.buffer.instance_eval{ @stage[meta].path }, File.readlink(symlink_path)
270
324
  ensure
271
325
  d.instance.shutdown
272
326
  FileUtils.rm_rf(symlink_path)