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,7 +1,20 @@
1
1
  require_relative '../helper'
2
2
  require 'fluent/test'
3
+ require 'fluent/plugin/in_tcp'
3
4
 
4
5
  class TcpInputTest < Test::Unit::TestCase
6
+ class << self
7
+ def startup
8
+ socket_manager_path = ServerEngine::SocketManager::Server.generate_path
9
+ @server = ServerEngine::SocketManager::Server.open(socket_manager_path)
10
+ ENV['SERVERENGINE_SOCKETMANAGER_PATH'] = socket_manager_path.to_s
11
+ end
12
+
13
+ def shutdown
14
+ @server.close
15
+ end
16
+ end
17
+
5
18
  def setup
6
19
  Fluent::Test.setup
7
20
  end
@@ -83,6 +96,7 @@ class TcpInputTest < Test::Unit::TestCase
83
96
  assert_equal(2, emits.size)
84
97
  emits.each_index {|i|
85
98
  assert_equal(tests[i]['expected'], emits[i][2]['message'])
99
+ assert(emits[i][1].is_a?(Fluent::EventTime))
86
100
  }
87
101
  end
88
102
  end
@@ -1,7 +1,20 @@
1
1
  require_relative '../helper'
2
2
  require 'fluent/test'
3
+ require 'fluent/plugin/in_udp'
3
4
 
4
5
  class UdpInputTest < Test::Unit::TestCase
6
+ class << self
7
+ def startup
8
+ socket_manager_path = ServerEngine::SocketManager::Server.generate_path
9
+ @server = ServerEngine::SocketManager::Server.open(socket_manager_path)
10
+ ENV['SERVERENGINE_SOCKETMANAGER_PATH'] = socket_manager_path.to_s
11
+ end
12
+
13
+ def shutdown
14
+ @server.close
15
+ end
16
+ end
17
+
5
18
  def setup
6
19
  Fluent::Test.setup
7
20
  end
@@ -32,19 +45,10 @@ class UdpInputTest < Test::Unit::TestCase
32
45
  d = create_driver(v)
33
46
  assert_equal PORT, d.instance.port
34
47
  assert_equal k, d.instance.bind
35
- assert_equal 4096, d.instance.message_length_limit
48
+ assert_equal 4096, d.instance.body_size_limit
36
49
  }
37
50
  end
38
51
 
39
- data(
40
- 'message_length_limit' => 'message_length_limit 2048',
41
- 'body_size_limit' => 'body_size_limit 2048'
42
- )
43
- test 'message_length_limit/body_size_limit compatibility' do |param|
44
- d = create_driver(CONFIG + param)
45
- assert_equal 2048, d.instance.message_length_limit
46
- end
47
-
48
52
  def test_time_format
49
53
  configs = {'127.0.0.1' => CONFIG}
50
54
  configs.merge!('::1' => IPv6_CONFIG) if ipv6_enabled?
@@ -53,8 +57,8 @@ class UdpInputTest < Test::Unit::TestCase
53
57
  d = create_driver(v)
54
58
 
55
59
  tests = [
56
- {'msg' => '[Sep 11 00:00:00] localhost logger: foo', 'expected' => Time.strptime('Sep 11 00:00:00', '%b %d %H:%M:%S').to_i},
57
- {'msg' => '[Sep 1 00:00:00] localhost logger: foo', 'expected' => Time.strptime('Sep 1 00:00:00', '%b %d %H:%M:%S').to_i},
60
+ {'msg' => '[Sep 11 00:00:00] localhost logger: foo', 'expected' => Fluent::EventTime.from_time(Time.strptime('Sep 11 00:00:00', '%b %d %H:%M:%S'))},
61
+ {'msg' => '[Sep 1 00:00:00] localhost logger: foo', 'expected' => Fluent::EventTime.from_time(Time.strptime('Sep 1 00:00:00', '%b %d %H:%M:%S'))},
58
62
  ]
59
63
 
60
64
  d.run do
@@ -63,14 +67,16 @@ class UdpInputTest < Test::Unit::TestCase
63
67
  tests.each {|test|
64
68
  u.send(test['msg'], 0)
65
69
  }
70
+ u.close
66
71
  sleep 1
67
72
  end
68
73
 
69
74
  emits = d.emits
70
75
  emits.each_index {|i|
71
- assert_equal(tests[i]['expected'], emits[i][1])
76
+ assert_equal_event_time(tests[i]['expected'], emits[i][1])
72
77
  }
73
78
  }
79
+
74
80
  end
75
81
 
76
82
  {
@@ -97,6 +103,7 @@ class UdpInputTest < Test::Unit::TestCase
97
103
  tests.each { |test|
98
104
  u.send(test['msg'], 0)
99
105
  }
106
+ u.close
100
107
  sleep 1
101
108
  end
102
109
 
@@ -108,6 +115,7 @@ class UdpInputTest < Test::Unit::TestCase
108
115
  assert_equal(2, emits.size)
109
116
  emits.each_index {|i|
110
117
  assert_equal(tests[i]['expected'], emits[i][2]['message'])
118
+ assert(emits[i][1].is_a?(Fluent::EventTime))
111
119
  }
112
120
  end
113
121
  end
@@ -0,0 +1,122 @@
1
+ require_relative '../helper'
2
+ require 'fluent/plugin/input'
3
+ require 'flexmock/test_unit'
4
+
5
+ module FluentPluginInputTest
6
+ class DummyPlugin < Fluent::Plugin::Input
7
+ end
8
+ end
9
+
10
+ class InputTest < Test::Unit::TestCase
11
+ setup do
12
+ Fluent::Test.setup
13
+ @p = FluentPluginInputTest::DummyPlugin.new
14
+ end
15
+
16
+ test 'has healthy lifecycle' do
17
+ assert !@p.configured?
18
+ @p.configure(config_element())
19
+ assert @p.configured?
20
+
21
+ assert !@p.started?
22
+ @p.start
23
+ assert @p.start
24
+
25
+ assert !@p.stopped?
26
+ @p.stop
27
+ assert @p.stopped?
28
+
29
+ assert !@p.before_shutdown?
30
+ @p.before_shutdown
31
+ assert @p.before_shutdown?
32
+
33
+ assert !@p.shutdown?
34
+ @p.shutdown
35
+ assert @p.shutdown?
36
+
37
+ assert !@p.after_shutdown?
38
+ @p.after_shutdown
39
+ assert @p.after_shutdown?
40
+
41
+ assert !@p.closed?
42
+ @p.close
43
+ assert @p.closed?
44
+
45
+ assert !@p.terminated?
46
+ @p.terminate
47
+ assert @p.terminated?
48
+ end
49
+
50
+ test 'has plugin_id automatically generated' do
51
+ assert @p.respond_to?(:plugin_id_configured?)
52
+ assert @p.respond_to?(:plugin_id)
53
+
54
+ @p.configure(config_element())
55
+
56
+ assert !@p.plugin_id_configured?
57
+ assert @p.plugin_id
58
+ assert{ @p.plugin_id != 'mytest' }
59
+ end
60
+
61
+ test 'has plugin_id manually configured' do
62
+ @p.configure(config_element('ROOT', '', {'@id' => 'mytest'}))
63
+ assert @p.plugin_id_configured?
64
+ assert_equal 'mytest', @p.plugin_id
65
+ end
66
+
67
+ test 'has plugin logger' do
68
+ assert @p.respond_to?(:log)
69
+ assert @p.log
70
+
71
+ # default logger
72
+ original_logger = @p.log
73
+
74
+ @p.configure(config_element('ROOT', '', {'@log_level' => 'debug'}))
75
+
76
+ assert{ @p.log.object_id != original_logger.object_id }
77
+ assert_equal Fluent::Log::LEVEL_DEBUG, @p.log.level
78
+ end
79
+
80
+ test 'can load plugin helpers' do
81
+ assert_nothing_raised do
82
+ class FluentPluginInputTest::DummyPlugin2 < Fluent::Plugin::Input
83
+ helpers :storage
84
+ end
85
+ end
86
+ end
87
+
88
+ test 'has router and can emit into it' do
89
+ assert @p.has_router?
90
+
91
+ @p.configure(config_element())
92
+ assert @p.router
93
+
94
+ DummyRouter = Struct.new(:emits) do
95
+ def emit(tag, es)
96
+ self.emits << [tag, es]
97
+ end
98
+ end
99
+ @p.router = DummyRouter.new([])
100
+ @p.router.emit('mytag', [])
101
+ @p.router.emit('mytag.testing', ['it is not es, but no problem for tests'])
102
+
103
+ assert_equal ['mytag', []], @p.router.emits[0]
104
+ assert_equal ['mytag.testing', ['it is not es, but no problem for tests']], @p.router.emits[1]
105
+ end
106
+
107
+ test 'has router for specified label if configured' do
108
+ @p.configure(config_element())
109
+ original_router = @p.router
110
+
111
+ router_mock = flexmock('mytest')
112
+ router_mock.should_receive(:emit).once.with('mytag.testing', ['for mock'])
113
+ label_mock = flexmock('mylabel')
114
+ label_mock.should_receive(:event_router).once.and_return(router_mock)
115
+ Fluent::Engine.root_agent.labels['@mytest'] = label_mock
116
+
117
+ @p.configure(config_element('ROOT', '', {'@label' => '@mytest'}))
118
+ assert{ @p.router.object_id != original_router.object_id }
119
+
120
+ @p.router.emit('mytag.testing', ['for mock'])
121
+ end
122
+ end
@@ -0,0 +1,180 @@
1
+ require_relative '../helper'
2
+ require 'fluent/plugin/multi_output'
3
+ require 'fluent/event'
4
+
5
+ require 'json'
6
+ require 'time'
7
+ require 'timeout'
8
+
9
+ module FluentPluginMultiOutputTest
10
+ class DummyMultiOutput < Fluent::Plugin::MultiOutput
11
+ attr_reader :events
12
+ def initialize
13
+ super
14
+ @events = []
15
+ end
16
+ def configure(conf)
17
+ super
18
+ end
19
+ def process(tag, es)
20
+ es.each do |time, record|
21
+ @events << [tag, time, record]
22
+ end
23
+ end
24
+ end
25
+ class DummyCompatMultiOutput < Fluent::Plugin::MultiOutput
26
+ def initialize
27
+ super
28
+ @compat = true
29
+ end
30
+ def configure(conf)
31
+ super
32
+ end
33
+ def process(tag, es)
34
+ # ...
35
+ end
36
+ end
37
+
38
+ class Dummy1Output < Fluent::Plugin::Output
39
+ Fluent::Plugin.register_output('dummy_test_multi_output_1', self)
40
+ attr_reader :configured
41
+ def configure(conf)
42
+ super
43
+ @configured = true
44
+ end
45
+ def process(tag, es)
46
+ end
47
+ end
48
+ class Dummy2Output < Fluent::Plugin::Output
49
+ Fluent::Plugin.register_output('dummy_test_multi_output_2', self)
50
+ attr_reader :configured
51
+ def configure(conf)
52
+ super
53
+ @configured = true
54
+ end
55
+ def process(tag, es)
56
+ end
57
+ end
58
+ class Dummy3Output < Fluent::Plugin::Output
59
+ Fluent::Plugin.register_output('dummy_test_multi_output_3', self)
60
+ attr_reader :configured
61
+ def configure(conf)
62
+ super
63
+ @configured = true
64
+ end
65
+ def process(tag, es)
66
+ end
67
+ end
68
+ class Dummy4Output < Fluent::Plugin::Output
69
+ Fluent::Plugin.register_output('dummy_test_multi_output_4', self)
70
+ attr_reader :configured
71
+ def configure(conf)
72
+ super
73
+ @configured = true
74
+ end
75
+ def process(tag, es)
76
+ end
77
+ end
78
+ end
79
+
80
+ class MultiOutputTest < Test::Unit::TestCase
81
+ def create_output(type=:multi)
82
+ case type
83
+ when :compat_multi
84
+ FluentPluginMultiOutputTest::DummyCompatMultiOutput.new
85
+ else
86
+ FluentPluginMultiOutputTest::DummyMultiOutput.new
87
+ end
88
+ end
89
+
90
+ sub_test_case 'basic multi output plugin' do
91
+ setup do
92
+ Fluent::Test.setup
93
+ @i = create_output()
94
+ end
95
+
96
+ teardown do
97
+ @i.log.out.reset
98
+ end
99
+
100
+ test '#configure raises error if <store> sections are missing' do
101
+ conf = config_element('ROOT', '', { '@type' => 'dummy_test_multi_output' }, [])
102
+ assert_raise Fluent::ConfigError do
103
+ @i.configure(conf)
104
+ end
105
+ end
106
+
107
+ test '#configure initialize child plugins and call these #configure' do
108
+ assert_equal [], @i.outputs
109
+
110
+ conf = config_element('ROOT', '', { '@type' => 'dummy_test_multi_output' },
111
+ [
112
+ config_element('store', '', { '@type' => 'dummy_test_multi_output_1' }),
113
+ config_element('store', '', { '@type' => 'dummy_test_multi_output_2' }),
114
+ config_element('store', '', { '@type' => 'dummy_test_multi_output_3' }),
115
+ config_element('store', '', { '@type' => 'dummy_test_multi_output_4' }),
116
+ ]
117
+ )
118
+ @i.configure(conf)
119
+
120
+ assert_equal 4, @i.outputs.size
121
+
122
+ assert @i.outputs[0].is_a? FluentPluginMultiOutputTest::Dummy1Output
123
+ assert @i.outputs[0].configured
124
+
125
+ assert @i.outputs[1].is_a? FluentPluginMultiOutputTest::Dummy2Output
126
+ assert @i.outputs[1].configured
127
+
128
+ assert @i.outputs[2].is_a? FluentPluginMultiOutputTest::Dummy3Output
129
+ assert @i.outputs[2].configured
130
+
131
+ assert @i.outputs[3].is_a? FluentPluginMultiOutputTest::Dummy4Output
132
+ assert @i.outputs[3].configured
133
+ end
134
+
135
+ test '#configure warns if "type" is used in <store> sections instead of "@type"' do
136
+ assert_equal [], @i.log.out.logs
137
+
138
+ conf = config_element('ROOT', '', { '@type' => 'dummy_test_multi_output' },
139
+ [
140
+ config_element('store', '', { 'type' => 'dummy_test_multi_output_1' }),
141
+ config_element('store', '', { 'type' => 'dummy_test_multi_output_2' }),
142
+ config_element('store', '', { 'type' => 'dummy_test_multi_output_3' }),
143
+ config_element('store', '', { 'type' => 'dummy_test_multi_output_4' }),
144
+ ]
145
+ )
146
+ @i.configure(conf)
147
+ assert_equal 4, @i.outputs.size
148
+
149
+ logs = @i.log.out.logs
150
+ assert{ logs.select{|log| log.include?('[warn]') && log.include?("'type' is deprecated parameter name. use '@type' instead.") }.size == 4 }
151
+ end
152
+
153
+ test '#emit_events calls #process always' do
154
+ conf = config_element('ROOT', '', { '@type' => 'dummy_test_multi_output' },
155
+ [
156
+ config_element('store', '', { '@type' => 'dummy_test_multi_output_1' }),
157
+ config_element('store', '', { '@type' => 'dummy_test_multi_output_2' }),
158
+ config_element('store', '', { '@type' => 'dummy_test_multi_output_3' }),
159
+ config_element('store', '', { '@type' => 'dummy_test_multi_output_4' }),
160
+ ]
161
+ )
162
+ @i.configure(conf)
163
+ @i.start
164
+
165
+ assert @i.events.empty?
166
+
167
+ @i.emit_events(
168
+ 'test.tag',
169
+ Fluent::ArrayEventStream.new(
170
+ [
171
+ [event_time(), {"message" => "multi test 1"}],
172
+ [event_time(), {"message" => "multi test 1"}],
173
+ ]
174
+ )
175
+ )
176
+
177
+ assert_equal 2, @i.events.size
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,79 @@
1
+ require_relative '../helper'
2
+ require 'fluent/test/driver/output'
3
+ require 'fluent/plugin/out_buffered_null'
4
+
5
+ class BufferedNullOutputTestCase < Test::Unit::TestCase
6
+ sub_test_case 'BufferedNullOutput' do
7
+ test 'default chunk limit size is 100' do
8
+ d = Fluent::Test::Driver::Output.new(Fluent::Plugin::BufferedNullOutput).configure('')
9
+ assert_equal 10 * 1024, d.instance.buffer_config.chunk_limit_size
10
+ assert d.instance.buffer_config.flush_at_shutdown
11
+ assert_equal ['tag'], d.instance.buffer_config.chunk_keys
12
+ assert d.instance.chunk_key_tag
13
+ assert !d.instance.chunk_key_time
14
+ assert_equal [], d.instance.chunk_keys
15
+ end
16
+
17
+ test 'writes standard formattted chunks' do
18
+ d = Fluent::Test::Driver::Output.new(Fluent::Plugin::BufferedNullOutput).configure('')
19
+ t = event_time("2016-05-23 00:22:13 -0800")
20
+ d.run(default_tag: 'test', flush: true) do
21
+ d.feed(t, {"message" => "null null null"})
22
+ d.feed(t, {"message" => "null null"})
23
+ d.feed(t, {"message" => "null"})
24
+ end
25
+
26
+ assert_equal 3, d.instance.emit_count
27
+ assert_equal 3, d.instance.emit_records
28
+ end
29
+
30
+ test 'check for chunk passed to #write' do
31
+ d = Fluent::Test::Driver::Output.new(Fluent::Plugin::BufferedNullOutput).configure('')
32
+ data = []
33
+ d.instance.feed_proc = ->(chunk){ data << [chunk.unique_id, chunk.metadata.tag, chunk.read] }
34
+
35
+ t = event_time("2016-05-23 00:22:13 -0800")
36
+ d.run(default_tag: 'test', flush: true) do
37
+ d.feed(t, {"message" => "null null null"})
38
+ d.feed(t, {"message" => "null null"})
39
+ d.feed(t, {"message" => "null"})
40
+ end
41
+
42
+ assert_equal 1, data.size
43
+ _, tag, binary = data.first
44
+ events = []
45
+ Fluent::MessagePackFactory.unpacker.feed_each(binary){|obj| events << obj }
46
+ assert_equal 'test', tag
47
+ assert_equal [ [t, {"message" => "null null null"}], [t, {"message" => "null null"}], [t, {"message" => "null"}] ], events
48
+ end
49
+
50
+ test 'check for chunk passed to #try_write' do
51
+ d = Fluent::Test::Driver::Output.new(Fluent::Plugin::BufferedNullOutput).configure('')
52
+ data = []
53
+ d.instance.feed_proc = ->(chunk){ data << [chunk.unique_id, chunk.metadata.tag, chunk.read] }
54
+ d.instance.delayed = true
55
+
56
+ t = event_time("2016-05-23 00:22:13 -0800")
57
+ d.run(default_tag: 'test', flush: true, shutdown: false) do
58
+ d.feed(t, {"message" => "null null null"})
59
+ d.feed(t, {"message" => "null null"})
60
+ d.feed(t, {"message" => "null"})
61
+ end
62
+
63
+ assert_equal 1, data.size
64
+ chunk_id, tag, binary = data.first
65
+ events = []
66
+ Fluent::MessagePackFactory.unpacker.feed_each(binary){|obj| events << obj }
67
+ assert_equal 'test', tag
68
+ assert_equal [ [t, {"message" => "null null null"}], [t, {"message" => "null null"}], [t, {"message" => "null"}] ], events
69
+
70
+ assert_equal [chunk_id], d.instance.buffer.dequeued.keys
71
+
72
+ d.instance.commit_write(chunk_id)
73
+
74
+ assert_equal [], d.instance.buffer.dequeued.keys
75
+
76
+ d.instance_shutdown
77
+ end
78
+ end
79
+ end