fluentd 0.12.40 → 1.6.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 (428) hide show
  1. checksums.yaml +5 -5
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
  4. data/.github/ISSUE_TEMPLATE.md +17 -0
  5. data/.github/PULL_REQUEST_TEMPLATE.md +13 -0
  6. data/.gitignore +5 -0
  7. data/.gitlab/cicd-template.yaml +10 -0
  8. data/.gitlab-ci.yml +147 -0
  9. data/.travis.yml +56 -20
  10. data/ADOPTERS.md +5 -0
  11. data/CHANGELOG.md +1369 -0
  12. data/CONTRIBUTING.md +16 -5
  13. data/GOVERNANCE.md +55 -0
  14. data/Gemfile +5 -0
  15. data/GithubWorkflow.md +78 -0
  16. data/LICENSE +202 -0
  17. data/MAINTAINERS.md +7 -0
  18. data/README.md +23 -11
  19. data/Rakefile +48 -2
  20. data/Vagrantfile +17 -0
  21. data/appveyor.yml +37 -0
  22. data/bin/fluent-binlog-reader +7 -0
  23. data/bin/fluent-ca-generate +6 -0
  24. data/bin/fluent-plugin-config-format +5 -0
  25. data/bin/fluent-plugin-generate +5 -0
  26. data/bin/fluentd +3 -0
  27. data/code-of-conduct.md +3 -0
  28. data/example/copy_roundrobin.conf +39 -0
  29. data/example/counter.conf +18 -0
  30. data/example/in_dummy_blocks.conf +17 -0
  31. data/example/in_dummy_with_compression.conf +23 -0
  32. data/example/in_forward.conf +7 -0
  33. data/example/in_forward_client.conf +37 -0
  34. data/example/in_forward_shared_key.conf +15 -0
  35. data/example/in_forward_tls.conf +14 -0
  36. data/example/in_forward_users.conf +24 -0
  37. data/example/in_forward_workers.conf +21 -0
  38. data/example/in_http.conf +3 -1
  39. data/example/in_out_forward.conf +17 -0
  40. data/example/logevents.conf +25 -0
  41. data/example/multi_filters.conf +61 -0
  42. data/example/out_exec_filter.conf +42 -0
  43. data/example/out_forward.conf +13 -13
  44. data/example/out_forward_buf_file.conf +23 -0
  45. data/example/out_forward_client.conf +109 -0
  46. data/example/out_forward_heartbeat_none.conf +16 -0
  47. data/example/out_forward_shared_key.conf +36 -0
  48. data/example/out_forward_tls.conf +18 -0
  49. data/example/out_forward_users.conf +65 -0
  50. data/example/out_null.conf +36 -0
  51. data/example/secondary_file.conf +42 -0
  52. data/example/suppress_config_dump.conf +7 -0
  53. data/example/worker_section.conf +36 -0
  54. data/fluent.conf +29 -0
  55. data/fluentd.gemspec +21 -11
  56. data/lib/fluent/agent.rb +67 -90
  57. data/lib/fluent/clock.rb +62 -0
  58. data/lib/fluent/command/binlog_reader.rb +244 -0
  59. data/lib/fluent/command/ca_generate.rb +181 -0
  60. data/lib/fluent/command/cat.rb +42 -18
  61. data/lib/fluent/command/debug.rb +12 -10
  62. data/lib/fluent/command/fluentd.rb +153 -5
  63. data/lib/fluent/command/plugin_config_formatter.rb +292 -0
  64. data/lib/fluent/command/plugin_generator.rb +324 -0
  65. data/lib/fluent/compat/call_super_mixin.rb +67 -0
  66. data/lib/fluent/compat/detach_process_mixin.rb +33 -0
  67. data/lib/fluent/compat/exec_util.rb +129 -0
  68. data/lib/fluent/compat/file_util.rb +54 -0
  69. data/lib/fluent/compat/filter.rb +68 -0
  70. data/lib/fluent/compat/formatter.rb +111 -0
  71. data/lib/fluent/compat/formatter_utils.rb +85 -0
  72. data/lib/fluent/compat/handle_tag_and_time_mixin.rb +62 -0
  73. data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
  74. data/lib/fluent/compat/input.rb +49 -0
  75. data/lib/fluent/compat/output.rb +718 -0
  76. data/lib/fluent/compat/output_chain.rb +60 -0
  77. data/lib/fluent/compat/parser.rb +310 -0
  78. data/lib/fluent/compat/parser_utils.rb +40 -0
  79. data/lib/fluent/compat/propagate_default.rb +62 -0
  80. data/lib/fluent/compat/record_filter_mixin.rb +34 -0
  81. data/lib/fluent/compat/set_tag_key_mixin.rb +50 -0
  82. data/lib/fluent/compat/set_time_key_mixin.rb +69 -0
  83. data/lib/fluent/compat/socket_util.rb +165 -0
  84. data/lib/fluent/compat/string_util.rb +34 -0
  85. data/lib/fluent/compat/structured_format_mixin.rb +26 -0
  86. data/lib/fluent/compat/type_converter.rb +90 -0
  87. data/lib/fluent/config/configure_proxy.rb +210 -62
  88. data/lib/fluent/config/dsl.rb +12 -5
  89. data/lib/fluent/config/element.rb +107 -9
  90. data/lib/fluent/config/literal_parser.rb +9 -3
  91. data/lib/fluent/config/parser.rb +4 -4
  92. data/lib/fluent/config/section.rb +51 -14
  93. data/lib/fluent/config/types.rb +28 -13
  94. data/lib/fluent/config/v1_parser.rb +3 -5
  95. data/lib/fluent/config.rb +23 -20
  96. data/lib/fluent/configurable.rb +79 -21
  97. data/lib/fluent/counter/base_socket.rb +46 -0
  98. data/lib/fluent/counter/client.rb +297 -0
  99. data/lib/fluent/counter/error.rb +86 -0
  100. data/lib/fluent/counter/mutex_hash.rb +163 -0
  101. data/lib/fluent/counter/server.rb +273 -0
  102. data/lib/fluent/counter/store.rb +205 -0
  103. data/lib/fluent/counter/validator.rb +145 -0
  104. data/lib/fluent/counter.rb +23 -0
  105. data/lib/fluent/daemon.rb +15 -0
  106. data/lib/fluent/engine.rb +102 -65
  107. data/lib/fluent/env.rb +7 -3
  108. data/lib/fluent/error.rb +30 -0
  109. data/lib/fluent/event.rb +197 -21
  110. data/lib/fluent/event_router.rb +93 -10
  111. data/lib/fluent/filter.rb +2 -50
  112. data/lib/fluent/formatter.rb +4 -293
  113. data/lib/fluent/input.rb +2 -32
  114. data/lib/fluent/label.rb +10 -2
  115. data/lib/fluent/load.rb +3 -3
  116. data/lib/fluent/log.rb +348 -81
  117. data/lib/fluent/match.rb +37 -36
  118. data/lib/fluent/mixin.rb +12 -176
  119. data/lib/fluent/msgpack_factory.rb +62 -0
  120. data/lib/fluent/output.rb +10 -612
  121. data/lib/fluent/output_chain.rb +23 -0
  122. data/lib/fluent/parser.rb +4 -800
  123. data/lib/fluent/plugin/bare_output.rb +63 -0
  124. data/lib/fluent/plugin/base.rb +192 -0
  125. data/lib/fluent/plugin/buf_file.rb +128 -174
  126. data/lib/fluent/plugin/buf_memory.rb +9 -92
  127. data/lib/fluent/plugin/buffer/chunk.rb +221 -0
  128. data/lib/fluent/plugin/buffer/file_chunk.rb +383 -0
  129. data/lib/fluent/plugin/buffer/memory_chunk.rb +90 -0
  130. data/lib/fluent/plugin/buffer.rb +779 -0
  131. data/lib/fluent/plugin/compressable.rb +92 -0
  132. data/lib/fluent/plugin/exec_util.rb +3 -108
  133. data/lib/fluent/plugin/file_util.rb +4 -34
  134. data/lib/fluent/plugin/file_wrapper.rb +120 -0
  135. data/lib/fluent/plugin/filter.rb +93 -0
  136. data/lib/fluent/plugin/filter_grep.rb +117 -34
  137. data/lib/fluent/plugin/filter_parser.rb +85 -62
  138. data/lib/fluent/plugin/filter_record_transformer.rb +27 -39
  139. data/lib/fluent/plugin/filter_stdout.rb +15 -12
  140. data/lib/fluent/plugin/formatter.rb +50 -0
  141. data/lib/fluent/plugin/formatter_csv.rb +52 -0
  142. data/lib/fluent/plugin/formatter_hash.rb +33 -0
  143. data/lib/fluent/plugin/formatter_json.rb +55 -0
  144. data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
  145. data/lib/fluent/plugin/formatter_msgpack.rb +33 -0
  146. data/lib/fluent/plugin/formatter_out_file.rb +51 -0
  147. data/lib/fluent/plugin/formatter_single_value.rb +34 -0
  148. data/lib/fluent/plugin/formatter_stdout.rb +76 -0
  149. data/lib/fluent/plugin/formatter_tsv.rb +38 -0
  150. data/lib/fluent/plugin/in_debug_agent.rb +17 -6
  151. data/lib/fluent/plugin/in_dummy.rb +47 -20
  152. data/lib/fluent/plugin/in_exec.rb +55 -123
  153. data/lib/fluent/plugin/in_forward.rb +299 -216
  154. data/lib/fluent/plugin/in_gc_stat.rb +14 -36
  155. data/lib/fluent/plugin/in_http.rb +204 -91
  156. data/lib/fluent/plugin/in_monitor_agent.rb +186 -258
  157. data/lib/fluent/plugin/in_object_space.rb +13 -41
  158. data/lib/fluent/plugin/in_syslog.rb +112 -134
  159. data/lib/fluent/plugin/in_tail.rb +408 -745
  160. data/lib/fluent/plugin/in_tcp.rb +66 -9
  161. data/lib/fluent/plugin/in_udp.rb +60 -11
  162. data/lib/fluent/plugin/{in_stream.rb → in_unix.rb} +8 -4
  163. data/lib/fluent/plugin/input.rb +37 -0
  164. data/lib/fluent/plugin/multi_output.rb +158 -0
  165. data/lib/fluent/plugin/out_copy.rb +23 -35
  166. data/lib/fluent/plugin/out_exec.rb +67 -70
  167. data/lib/fluent/plugin/out_exec_filter.rb +204 -271
  168. data/lib/fluent/plugin/out_file.rb +267 -73
  169. data/lib/fluent/plugin/out_forward.rb +854 -325
  170. data/lib/fluent/plugin/out_null.rb +42 -9
  171. data/lib/fluent/plugin/out_relabel.rb +9 -5
  172. data/lib/fluent/plugin/out_roundrobin.rb +18 -37
  173. data/lib/fluent/plugin/out_secondary_file.rb +133 -0
  174. data/lib/fluent/plugin/out_stdout.rb +43 -10
  175. data/lib/fluent/plugin/out_stream.rb +7 -2
  176. data/lib/fluent/plugin/output.rb +1498 -0
  177. data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
  178. data/lib/fluent/plugin/parser.rb +191 -0
  179. data/lib/fluent/plugin/parser_apache.rb +28 -0
  180. data/lib/fluent/plugin/parser_apache2.rb +88 -0
  181. data/lib/fluent/plugin/parser_apache_error.rb +26 -0
  182. data/lib/fluent/plugin/parser_csv.rb +39 -0
  183. data/lib/fluent/plugin/parser_json.rb +94 -0
  184. data/lib/fluent/plugin/parser_ltsv.rb +49 -0
  185. data/lib/fluent/plugin/parser_msgpack.rb +50 -0
  186. data/lib/fluent/plugin/parser_multiline.rb +106 -0
  187. data/lib/fluent/plugin/parser_nginx.rb +28 -0
  188. data/lib/fluent/plugin/parser_none.rb +36 -0
  189. data/lib/fluent/plugin/parser_regexp.rb +68 -0
  190. data/lib/fluent/plugin/parser_syslog.rb +142 -0
  191. data/lib/fluent/plugin/parser_tsv.rb +42 -0
  192. data/lib/fluent/plugin/socket_util.rb +3 -143
  193. data/lib/fluent/plugin/storage.rb +84 -0
  194. data/lib/fluent/plugin/storage_local.rb +164 -0
  195. data/lib/fluent/plugin/string_util.rb +3 -15
  196. data/lib/fluent/plugin.rb +122 -121
  197. data/lib/fluent/plugin_helper/cert_option.rb +178 -0
  198. data/lib/fluent/plugin_helper/child_process.rb +364 -0
  199. data/lib/fluent/plugin_helper/compat_parameters.rb +333 -0
  200. data/lib/fluent/plugin_helper/counter.rb +51 -0
  201. data/lib/fluent/plugin_helper/event_emitter.rb +93 -0
  202. data/lib/fluent/plugin_helper/event_loop.rb +170 -0
  203. data/lib/fluent/plugin_helper/extract.rb +104 -0
  204. data/lib/fluent/plugin_helper/formatter.rb +147 -0
  205. data/lib/fluent/plugin_helper/http_server/app.rb +79 -0
  206. data/lib/fluent/plugin_helper/http_server/compat/server.rb +81 -0
  207. data/lib/fluent/plugin_helper/http_server/compat/webrick_handler.rb +58 -0
  208. data/lib/fluent/plugin_helper/http_server/methods.rb +35 -0
  209. data/lib/fluent/plugin_helper/http_server/request.rb +42 -0
  210. data/lib/fluent/plugin_helper/http_server/router.rb +54 -0
  211. data/lib/fluent/plugin_helper/http_server/server.rb +87 -0
  212. data/lib/fluent/plugin_helper/http_server.rb +76 -0
  213. data/lib/fluent/plugin_helper/inject.rb +151 -0
  214. data/lib/fluent/plugin_helper/parser.rb +147 -0
  215. data/lib/fluent/plugin_helper/record_accessor.rb +210 -0
  216. data/lib/fluent/plugin_helper/retry_state.rb +205 -0
  217. data/lib/fluent/plugin_helper/server.rb +807 -0
  218. data/lib/fluent/plugin_helper/socket.rb +250 -0
  219. data/lib/fluent/plugin_helper/socket_option.rb +80 -0
  220. data/lib/fluent/plugin_helper/storage.rb +349 -0
  221. data/lib/fluent/plugin_helper/thread.rb +179 -0
  222. data/lib/fluent/plugin_helper/timer.rb +92 -0
  223. data/lib/fluent/plugin_helper.rb +73 -0
  224. data/lib/fluent/plugin_id.rb +80 -0
  225. data/lib/fluent/process.rb +3 -489
  226. data/lib/fluent/registry.rb +52 -10
  227. data/lib/fluent/root_agent.rb +204 -42
  228. data/lib/fluent/supervisor.rb +597 -359
  229. data/lib/fluent/system_config.rb +131 -42
  230. data/lib/fluent/test/base.rb +6 -54
  231. data/lib/fluent/test/driver/base.rb +224 -0
  232. data/lib/fluent/test/driver/base_owned.rb +70 -0
  233. data/lib/fluent/test/driver/base_owner.rb +135 -0
  234. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  235. data/lib/fluent/test/driver/filter.rb +57 -0
  236. data/lib/fluent/test/driver/formatter.rb +30 -0
  237. data/lib/fluent/test/driver/input.rb +31 -0
  238. data/lib/fluent/test/driver/multi_output.rb +53 -0
  239. data/lib/fluent/test/driver/output.rb +102 -0
  240. data/lib/fluent/test/driver/parser.rb +30 -0
  241. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  242. data/lib/fluent/test/filter_test.rb +0 -1
  243. data/lib/fluent/test/formatter_test.rb +4 -1
  244. data/lib/fluent/test/helpers.rb +58 -10
  245. data/lib/fluent/test/input_test.rb +27 -19
  246. data/lib/fluent/test/log.rb +79 -0
  247. data/lib/fluent/test/output_test.rb +28 -39
  248. data/lib/fluent/test/parser_test.rb +3 -1
  249. data/lib/fluent/test/startup_shutdown.rb +46 -0
  250. data/lib/fluent/test.rb +33 -1
  251. data/lib/fluent/time.rb +450 -1
  252. data/lib/fluent/timezone.rb +27 -3
  253. data/lib/fluent/{status.rb → unique_id.rb} +15 -24
  254. data/lib/fluent/version.rb +1 -1
  255. data/lib/fluent/winsvc.rb +85 -0
  256. data/templates/new_gem/Gemfile +3 -0
  257. data/templates/new_gem/README.md.erb +43 -0
  258. data/templates/new_gem/Rakefile +13 -0
  259. data/templates/new_gem/fluent-plugin.gemspec.erb +27 -0
  260. data/templates/new_gem/lib/fluent/plugin/filter.rb.erb +14 -0
  261. data/templates/new_gem/lib/fluent/plugin/formatter.rb.erb +14 -0
  262. data/templates/new_gem/lib/fluent/plugin/input.rb.erb +11 -0
  263. data/templates/new_gem/lib/fluent/plugin/output.rb.erb +11 -0
  264. data/templates/new_gem/lib/fluent/plugin/parser.rb.erb +15 -0
  265. data/templates/new_gem/test/helper.rb.erb +8 -0
  266. data/templates/new_gem/test/plugin/test_filter.rb.erb +18 -0
  267. data/templates/new_gem/test/plugin/test_formatter.rb.erb +18 -0
  268. data/templates/new_gem/test/plugin/test_input.rb.erb +18 -0
  269. data/templates/new_gem/test/plugin/test_output.rb.erb +18 -0
  270. data/templates/new_gem/test/plugin/test_parser.rb.erb +18 -0
  271. data/templates/plugin_config_formatter/param.md-compact.erb +25 -0
  272. data/templates/plugin_config_formatter/param.md.erb +34 -0
  273. data/templates/plugin_config_formatter/section.md.erb +12 -0
  274. data/test/command/test_binlog_reader.rb +346 -0
  275. data/test/command/test_ca_generate.rb +70 -0
  276. data/test/command/test_fluentd.rb +901 -0
  277. data/test/command/test_plugin_config_formatter.rb +276 -0
  278. data/test/command/test_plugin_generator.rb +92 -0
  279. data/test/compat/test_calls_super.rb +166 -0
  280. data/test/compat/test_parser.rb +92 -0
  281. data/test/config/test_config_parser.rb +126 -2
  282. data/test/config/test_configurable.rb +946 -187
  283. data/test/config/test_configure_proxy.rb +424 -74
  284. data/test/config/test_dsl.rb +11 -11
  285. data/test/config/test_element.rb +500 -0
  286. data/test/config/test_literal_parser.rb +8 -0
  287. data/test/config/test_plugin_configuration.rb +56 -0
  288. data/test/config/test_section.rb +79 -7
  289. data/test/config/test_system_config.rb +122 -35
  290. data/test/config/test_types.rb +38 -0
  291. data/test/counter/test_client.rb +559 -0
  292. data/test/counter/test_error.rb +44 -0
  293. data/test/counter/test_mutex_hash.rb +179 -0
  294. data/test/counter/test_server.rb +589 -0
  295. data/test/counter/test_store.rb +258 -0
  296. data/test/counter/test_validator.rb +137 -0
  297. data/test/helper.rb +89 -6
  298. data/test/helpers/fuzzy_assert.rb +89 -0
  299. data/test/plugin/test_bare_output.rb +118 -0
  300. data/test/plugin/test_base.rb +115 -0
  301. data/test/plugin/test_buf_file.rb +823 -460
  302. data/test/plugin/test_buf_memory.rb +32 -194
  303. data/test/plugin/test_buffer.rb +1233 -0
  304. data/test/plugin/test_buffer_chunk.rb +198 -0
  305. data/test/plugin/test_buffer_file_chunk.rb +844 -0
  306. data/test/plugin/test_buffer_memory_chunk.rb +338 -0
  307. data/test/plugin/test_compressable.rb +84 -0
  308. data/test/plugin/test_filter.rb +357 -0
  309. data/test/plugin/test_filter_grep.rb +540 -29
  310. data/test/plugin/test_filter_parser.rb +439 -452
  311. data/test/plugin/test_filter_record_transformer.rb +123 -166
  312. data/test/plugin/test_filter_stdout.rb +160 -72
  313. data/test/plugin/test_formatter_csv.rb +111 -0
  314. data/test/plugin/test_formatter_hash.rb +35 -0
  315. data/test/plugin/test_formatter_json.rb +51 -0
  316. data/test/plugin/test_formatter_ltsv.rb +62 -0
  317. data/test/plugin/test_formatter_msgpack.rb +28 -0
  318. data/test/plugin/test_formatter_out_file.rb +95 -0
  319. data/test/plugin/test_formatter_single_value.rb +38 -0
  320. data/test/plugin/test_formatter_tsv.rb +68 -0
  321. data/test/plugin/test_in_debug_agent.rb +24 -1
  322. data/test/plugin/test_in_dummy.rb +111 -18
  323. data/test/plugin/test_in_exec.rb +200 -113
  324. data/test/plugin/test_in_forward.rb +990 -387
  325. data/test/plugin/test_in_gc_stat.rb +10 -8
  326. data/test/plugin/test_in_http.rb +600 -224
  327. data/test/plugin/test_in_monitor_agent.rb +690 -0
  328. data/test/plugin/test_in_object_space.rb +24 -8
  329. data/test/plugin/test_in_syslog.rb +154 -215
  330. data/test/plugin/test_in_tail.rb +1006 -707
  331. data/test/plugin/test_in_tcp.rb +125 -48
  332. data/test/plugin/test_in_udp.rb +204 -63
  333. data/test/plugin/{test_in_stream.rb → test_in_unix.rb} +14 -13
  334. data/test/plugin/test_input.rb +126 -0
  335. data/test/plugin/test_metadata.rb +89 -0
  336. data/test/plugin/test_multi_output.rb +180 -0
  337. data/test/plugin/test_out_copy.rb +117 -112
  338. data/test/plugin/test_out_exec.rb +258 -53
  339. data/test/plugin/test_out_exec_filter.rb +538 -115
  340. data/test/plugin/test_out_file.rb +865 -178
  341. data/test/plugin/test_out_forward.rb +998 -210
  342. data/test/plugin/test_out_null.rb +105 -0
  343. data/test/plugin/test_out_relabel.rb +28 -0
  344. data/test/plugin/test_out_roundrobin.rb +36 -29
  345. data/test/plugin/test_out_secondary_file.rb +458 -0
  346. data/test/plugin/test_out_stdout.rb +135 -37
  347. data/test/plugin/test_out_stream.rb +18 -0
  348. data/test/plugin/test_output.rb +984 -0
  349. data/test/plugin/test_output_as_buffered.rb +2021 -0
  350. data/test/plugin/test_output_as_buffered_backup.rb +312 -0
  351. data/test/plugin/test_output_as_buffered_compress.rb +165 -0
  352. data/test/plugin/test_output_as_buffered_overflow.rb +250 -0
  353. data/test/plugin/test_output_as_buffered_retries.rb +911 -0
  354. data/test/plugin/test_output_as_buffered_secondary.rb +874 -0
  355. data/test/plugin/test_output_as_standard.rb +374 -0
  356. data/test/plugin/test_owned_by.rb +35 -0
  357. data/test/plugin/test_parser.rb +359 -0
  358. data/test/plugin/test_parser_apache.rb +42 -0
  359. data/test/plugin/test_parser_apache2.rb +47 -0
  360. data/test/plugin/test_parser_apache_error.rb +45 -0
  361. data/test/plugin/test_parser_csv.rb +103 -0
  362. data/test/plugin/test_parser_json.rb +138 -0
  363. data/test/plugin/test_parser_labeled_tsv.rb +145 -0
  364. data/test/plugin/test_parser_multiline.rb +100 -0
  365. data/test/plugin/test_parser_nginx.rb +88 -0
  366. data/test/plugin/test_parser_none.rb +52 -0
  367. data/test/plugin/test_parser_regexp.rb +289 -0
  368. data/test/plugin/test_parser_syslog.rb +441 -0
  369. data/test/plugin/test_parser_tsv.rb +122 -0
  370. data/test/plugin/test_storage.rb +167 -0
  371. data/test/plugin/test_storage_local.rb +335 -0
  372. data/test/plugin_helper/data/cert/cert-key.pem +27 -0
  373. data/test/plugin_helper/data/cert/cert-with-no-newline.pem +19 -0
  374. data/test/plugin_helper/data/cert/cert.pem +19 -0
  375. data/test/plugin_helper/http_server/test_app.rb +65 -0
  376. data/test/plugin_helper/http_server/test_route.rb +32 -0
  377. data/test/plugin_helper/test_cert_option.rb +16 -0
  378. data/test/plugin_helper/test_child_process.rb +794 -0
  379. data/test/plugin_helper/test_compat_parameters.rb +353 -0
  380. data/test/plugin_helper/test_event_emitter.rb +51 -0
  381. data/test/plugin_helper/test_event_loop.rb +52 -0
  382. data/test/plugin_helper/test_extract.rb +194 -0
  383. data/test/plugin_helper/test_formatter.rb +255 -0
  384. data/test/plugin_helper/test_http_server_helper.rb +205 -0
  385. data/test/plugin_helper/test_inject.rb +519 -0
  386. data/test/plugin_helper/test_parser.rb +264 -0
  387. data/test/plugin_helper/test_record_accessor.rb +197 -0
  388. data/test/plugin_helper/test_retry_state.rb +442 -0
  389. data/test/plugin_helper/test_server.rb +1714 -0
  390. data/test/plugin_helper/test_storage.rb +542 -0
  391. data/test/plugin_helper/test_thread.rb +164 -0
  392. data/test/plugin_helper/test_timer.rb +132 -0
  393. data/test/scripts/exec_script.rb +0 -6
  394. data/test/scripts/fluent/plugin/formatter1/formatter_test1.rb +7 -0
  395. data/test/scripts/fluent/plugin/formatter2/formatter_test2.rb +7 -0
  396. data/test/scripts/fluent/plugin/out_test.rb +23 -15
  397. data/test/scripts/fluent/plugin/out_test2.rb +80 -0
  398. data/test/test_clock.rb +164 -0
  399. data/test/test_config.rb +16 -7
  400. data/test/test_configdsl.rb +2 -2
  401. data/test/test_event.rb +360 -13
  402. data/test/test_event_router.rb +108 -11
  403. data/test/test_event_time.rb +199 -0
  404. data/test/test_filter.rb +48 -6
  405. data/test/test_formatter.rb +11 -391
  406. data/test/test_input.rb +1 -1
  407. data/test/test_log.rb +591 -31
  408. data/test/test_mixin.rb +1 -1
  409. data/test/test_output.rb +121 -185
  410. data/test/test_plugin.rb +251 -0
  411. data/test/test_plugin_classes.rb +177 -10
  412. data/test/test_plugin_helper.rb +81 -0
  413. data/test/test_plugin_id.rb +101 -0
  414. data/test/test_process.rb +8 -42
  415. data/test/test_root_agent.rb +766 -21
  416. data/test/test_supervisor.rb +481 -0
  417. data/test/test_test_drivers.rb +135 -0
  418. data/test/test_time_formatter.rb +282 -0
  419. data/test/test_time_parser.rb +231 -0
  420. data/test/test_unique_id.rb +47 -0
  421. metadata +454 -60
  422. data/COPYING +0 -14
  423. data/ChangeLog +0 -666
  424. data/lib/fluent/buffer.rb +0 -365
  425. data/lib/fluent/plugin/in_status.rb +0 -76
  426. data/test/plugin/test_in_status.rb +0 -38
  427. data/test/test_buffer.rb +0 -624
  428. data/test/test_parser.rb +0 -1305
@@ -14,21 +14,78 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
- require 'cool.io'
17
+ require 'fluent/plugin/input'
18
18
 
19
- require 'fluent/plugin/socket_util'
19
+ module Fluent::Plugin
20
+ class TcpInput < Input
21
+ Fluent::Plugin.register_input('tcp', self)
20
22
 
21
- module Fluent
22
- class TcpInput < SocketUtil::BaseInput
23
- Plugin.register_input('tcp', self)
23
+ helpers :server, :parser, :extract, :compat_parameters
24
+
25
+ desc 'Tag of output events.'
26
+ config_param :tag, :string
27
+ desc 'The port to listen to.'
28
+ config_param :port, :integer, default: 5170
29
+ desc 'The bind address to listen to.'
30
+ config_param :bind, :string, default: '0.0.0.0'
31
+
32
+ desc "The field name of the client's hostname."
33
+ config_param :source_host_key, :string, default: nil, deprecated: "use source_hostname_key instead."
34
+ desc "The field name of the client's hostname."
35
+ config_param :source_hostname_key, :string, default: nil
36
+ desc "The field name of the client's address."
37
+ config_param :source_address_key, :string, default: nil
38
+
39
+ config_param :blocking_timeout, :time, default: 0.5
24
40
 
25
- config_set_default :port, 5170
26
41
  desc 'The payload is read up to this character.'
27
42
  config_param :delimiter, :string, default: "\n" # syslog family add "\n" to each message and this seems only way to split messages in tcp stream
28
43
 
29
- def listen(callback)
30
- log.info "listening tcp socket on #{@bind}:#{@port}"
31
- Coolio::TCPServer.new(@bind, @port, SocketUtil::TcpHandler, log, @delimiter, callback, !!@source_hostname_key)
44
+ def configure(conf)
45
+ compat_parameters_convert(conf, :parser)
46
+ parser_config = conf.elements('parse').first
47
+ unless parser_config
48
+ raise Fluent::ConfigError, "<parse> section is required."
49
+ end
50
+ super
51
+ @_event_loop_blocking_timeout = @blocking_timeout
52
+ @source_hostname_key ||= @source_host_key if @source_host_key
53
+
54
+ @parser = parser_create(conf: parser_config)
55
+ end
56
+
57
+ def multi_workers_ready?
58
+ true
59
+ end
60
+
61
+ def start
62
+ super
63
+
64
+ server_create(:in_tcp_server, @port, bind: @bind, resolve_name: !!@source_hostname_key) do |data, conn|
65
+ conn.buffer << data
66
+ begin
67
+ pos = 0
68
+ while i = conn.buffer.index(@delimiter, pos)
69
+ msg = conn.buffer[pos...i]
70
+ pos = i + @delimiter.length
71
+
72
+ @parser.parse(msg) do |time, record|
73
+ unless time && record
74
+ log.warn "pattern not matched", message: msg
75
+ next
76
+ end
77
+
78
+ tag = extract_tag_from_record(record)
79
+ tag ||= @tag
80
+ time ||= extract_time_from_record(record) || Fluent::EventTime.now
81
+ record[@source_address_key] = conn.remote_addr if @source_address_key
82
+ record[@source_hostname_key] = conn.remote_host if @source_hostname_key
83
+ router.emit(tag, time, record)
84
+ end
85
+ end
86
+ conn.buffer.slice!(0, pos) if pos > 0
87
+ end
88
+ end
32
89
  end
33
90
  end
34
91
  end
@@ -14,30 +14,79 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
- require 'fluent/plugin/socket_util'
17
+ require 'fluent/plugin/input'
18
18
 
19
- module Fluent
20
- class UdpInput < SocketUtil::BaseInput
21
- Plugin.register_input('udp', self)
19
+ module Fluent::Plugin
20
+ class UdpInput < Input
21
+ Fluent::Plugin.register_input('udp', self)
22
22
 
23
- config_set_default :port, 5160
23
+ helpers :server, :parser, :extract, :compat_parameters
24
+
25
+ desc 'Tag of output events.'
26
+ config_param :tag, :string
27
+ desc 'The port to listen to.'
28
+ config_param :port, :integer, default: 5160
29
+ desc 'The bind address to listen to.'
30
+ config_param :bind, :string, default: '0.0.0.0'
31
+
32
+ desc "The field name of the client's hostname."
33
+ config_param :source_host_key, :string, default: nil, deprecated: "use source_hostname_key instead."
34
+ desc "The field name of the client's hostname."
35
+ config_param :source_hostname_key, :string, default: nil
36
+ desc "The field name of the client's address."
37
+ config_param :source_address_key, :string, default: nil
24
38
 
25
39
  desc "Deprecated parameter. Use message_length_limit instead"
26
40
  config_param :body_size_limit, :size, default: nil, deprecated: "use message_length_limit instead."
27
41
  desc "The max bytes of message"
28
42
  config_param :message_length_limit, :size, default: 4096
43
+ desc "Remove newline from the end of incoming payload"
44
+ config_param :remove_newline, :bool, default: true
45
+ desc "The max size of socket receive buffer. SO_RCVBUF"
46
+ config_param :receive_buffer_size, :size, default: nil
47
+
48
+ config_param :blocking_timeout, :time, default: 0.5
29
49
 
30
50
  def configure(conf)
51
+ compat_parameters_convert(conf, :parser)
52
+ parser_config = conf.elements('parse').first
53
+ unless parser_config
54
+ raise Fluent::ConfigError, "<parse> section is required."
55
+ end
31
56
  super
32
-
57
+ @_event_loop_blocking_timeout = @blocking_timeout
58
+ @source_hostname_key ||= @source_host_key if @source_host_key
33
59
  @message_length_limit = @body_size_limit if @body_size_limit
60
+
61
+ @parser = parser_create(conf: parser_config)
34
62
  end
35
63
 
36
- def listen(callback)
37
- log.info "listening udp socket on #{@bind}:#{@port}"
38
- @usock = SocketUtil.create_udp_socket(@bind)
39
- @usock.bind(@bind, @port)
40
- SocketUtil::UdpHandler.new(@usock, log, @message_length_limit, callback, !!@source_hostname_key)
64
+ def multi_workers_ready?
65
+ true
66
+ end
67
+
68
+ def start
69
+ super
70
+
71
+ log.info "listening udp socket", bind: @bind, port: @port
72
+ server_create(:in_udp_server, @port, proto: :udp, bind: @bind, resolve_name: !!@source_hostname_key, max_bytes: @message_length_limit, receive_buffer_size: @receive_buffer_size) do |data, sock|
73
+ data.chomp! if @remove_newline
74
+ begin
75
+ @parser.parse(data) do |time, record|
76
+ unless time && record
77
+ log.warn "pattern not matched", data: data
78
+ next
79
+ end
80
+
81
+ tag = extract_tag_from_record(record)
82
+ tag ||= @tag
83
+ time ||= extract_time_from_record(record) || Fluent::EventTime.now
84
+ record[@source_address_key] = sock.remote_addr if @source_address_key
85
+ record[@source_hostname_key] = sock.remote_host if @source_hostname_key
86
+ router.emit(tag, time, record)
87
+ end
88
+ end
89
+ end
41
90
  end
42
91
  end
43
92
  end
@@ -35,6 +35,8 @@ module Fluent
35
35
  end
36
36
 
37
37
  def start
38
+ super
39
+
38
40
  @loop = Coolio::Loop.new
39
41
  @lsock = listen
40
42
  @loop.attach(@lsock)
@@ -46,6 +48,8 @@ module Fluent
46
48
  @loop.stop
47
49
  @lsock.close
48
50
  @thread.join
51
+
52
+ super
49
53
  end
50
54
 
51
55
  #def listen
@@ -96,8 +100,8 @@ module Fluent
96
100
  entries.each {|e|
97
101
  record = e[1]
98
102
  next if record.nil?
99
- time = e[0].to_i
100
- time = (now ||= Engine.now) if time == 0
103
+ time = e[0]
104
+ time = (now ||= Engine.now) if time.to_i == 0
101
105
  es.add(time, record)
102
106
  }
103
107
  router.emit_stream(tag, es)
@@ -108,7 +112,7 @@ module Fluent
108
112
  return if record.nil?
109
113
 
110
114
  time = msg[1]
111
- time = Engine.now if time == 0
115
+ time = Engine.now if time.to_i == 0
112
116
  router.emit(tag, time, record)
113
117
  end
114
118
  end
@@ -142,7 +146,7 @@ module Fluent
142
146
  @u = Fluent::Engine.msgpack_factory.unpacker
143
147
  end
144
148
 
145
- (class << self; self; end).module_eval do
149
+ singleton_class.module_eval do
146
150
  define_method(:on_read, m)
147
151
  end
148
152
  m.call(data)
@@ -0,0 +1,37 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'fluent/plugin/base'
18
+
19
+ require 'fluent/log'
20
+ require 'fluent/plugin_id'
21
+ require 'fluent/plugin_helper'
22
+
23
+ module Fluent
24
+ module Plugin
25
+ class Input < Base
26
+ include PluginId
27
+ include PluginLoggerMixin
28
+ include PluginHelper::Mixin
29
+
30
+ helpers_internal :event_emitter
31
+
32
+ def multi_workers_ready?
33
+ false
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,158 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'fluent/plugin/base'
18
+ require 'fluent/log'
19
+ require 'fluent/plugin_id'
20
+ require 'fluent/plugin_helper'
21
+
22
+ module Fluent
23
+ module Plugin
24
+ class MultiOutput < Base
25
+ include PluginId
26
+ include PluginLoggerMixin
27
+ include PluginHelper::Mixin # for event_emitter
28
+
29
+ helpers :event_emitter # to get router from agent, which will be supplied to child plugins
30
+
31
+ config_section :store, param_name: :stores, multi: true, required: true do
32
+ config_argument :arg, :string, default: ''
33
+ config_param :@type, :string, default: nil
34
+ end
35
+
36
+ attr_reader :outputs, :outputs_statically_created
37
+
38
+ def process(tag, es)
39
+ raise NotImplementedError, "BUG: output plugins MUST implement this method"
40
+ end
41
+
42
+ def initialize
43
+ super
44
+ @outputs = []
45
+ @outputs_statically_created = false
46
+
47
+ @counters_monitor = Monitor.new
48
+ # TODO: well organized counters
49
+ @num_errors = 0
50
+ @emit_count = 0
51
+ @emit_records = 0
52
+ # @write_count = 0
53
+ # @rollback_count = 0
54
+ end
55
+
56
+ def multi_output?
57
+ true
58
+ end
59
+
60
+ def configure(conf)
61
+ super
62
+
63
+ @stores.each do |store|
64
+ store_conf = store.corresponding_config_element
65
+ type = store_conf['@type']
66
+ unless type
67
+ raise Fluent::ConfigError, "Missing '@type' parameter in <store> section"
68
+ end
69
+
70
+ log.debug "adding store", type: type
71
+
72
+ output = Fluent::Plugin.new_output(type)
73
+ output.context_router = self.context_router
74
+ output.configure(store_conf)
75
+ @outputs << output
76
+ end
77
+ end
78
+
79
+ def static_outputs
80
+ @outputs_statically_created = true
81
+ @outputs
82
+ end
83
+
84
+ # Child plugin's lifecycles are controlled by agent automatically.
85
+ # It calls `outputs` to traverse plugins, and invoke start/stop/*shutdown/close/terminate on these directly.
86
+ # * `start` of this plugin will be called after child plugins
87
+ # * `stop`, `*shutdown`, `close` and `terminate` of this plugin will be called before child plugins
88
+
89
+ # But when MultiOutput plugins are created dynamically (by forest plugin or others), agent cannot find
90
+ # sub-plugins. So child plugins' lifecycles MUST be controlled by MultiOutput plugin itself.
91
+ # TODO: this hack will be removed at v2.
92
+ def call_lifecycle_method(method_name, checker_name)
93
+ return if @outputs_statically_created
94
+ @outputs.each do |o|
95
+ begin
96
+ log.debug "calling #{method_name} on output plugin dynamically created", type: Fluent::Plugin.lookup_type_from_class(o.class), plugin_id: o.plugin_id
97
+ o.send(method_name) unless o.send(checker_name)
98
+ rescue Exception => e
99
+ log.warn "unexpected error while calling #{method_name} on output plugin dynamically created", plugin: o.class, plugin_id: o.plugin_id, error: e
100
+ log.warn_backtrace
101
+ end
102
+ end
103
+ end
104
+
105
+ def start
106
+ super
107
+ call_lifecycle_method(:start, :started?)
108
+ end
109
+
110
+ def after_start
111
+ super
112
+ call_lifecycle_method(:after_start, :after_started?)
113
+ end
114
+
115
+ def stop
116
+ super
117
+ call_lifecycle_method(:stop, :stopped?)
118
+ end
119
+
120
+ def before_shutdown
121
+ super
122
+ call_lifecycle_method(:before_shutdown, :before_shutdown?)
123
+ end
124
+
125
+ def shutdown
126
+ super
127
+ call_lifecycle_method(:shutdown, :shutdown?)
128
+ end
129
+
130
+ def after_shutdown
131
+ super
132
+ call_lifecycle_method(:after_shutdown, :after_shutdown?)
133
+ end
134
+
135
+ def close
136
+ super
137
+ call_lifecycle_method(:close, :closed?)
138
+ end
139
+
140
+ def terminate
141
+ super
142
+ call_lifecycle_method(:terminate, :terminated?)
143
+ end
144
+
145
+ def emit_sync(tag, es)
146
+ @counters_monitor.synchronize{ @emit_count += 1 }
147
+ begin
148
+ process(tag, es)
149
+ @counters_monitor.synchronize{ @emit_records += es.size }
150
+ rescue
151
+ @counters_monitor.synchronize{ @num_errors += 1 }
152
+ raise
153
+ end
154
+ end
155
+ alias :emit_events :emit_sync
156
+ end
157
+ end
158
+ end
@@ -14,68 +14,56 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
- require 'fluent/output'
17
+ require 'fluent/plugin/multi_output'
18
18
  require 'fluent/config/error'
19
19
  require 'fluent/event'
20
20
 
21
- module Fluent
21
+ module Fluent::Plugin
22
22
  class CopyOutput < MultiOutput
23
- Plugin.register_output('copy', self)
23
+ Fluent::Plugin.register_output('copy', self)
24
24
 
25
25
  desc 'If true, pass different record to each `store` plugin.'
26
26
  config_param :deep_copy, :bool, default: false
27
27
 
28
+ attr_reader :ignore_errors
29
+
28
30
  def initialize
29
31
  super
30
- @outputs = []
32
+ @ignore_errors = []
31
33
  end
32
34
 
33
- attr_reader :outputs
34
-
35
35
  def configure(conf)
36
36
  super
37
- conf.elements.select {|e|
38
- e.name == 'store'
39
- }.each {|e|
40
- type = e['@type'] || e['type']
41
- unless type
42
- raise ConfigError, "Missing 'type' parameter on <store> directive"
43
- end
44
- log.debug "adding store type=#{type.dump}"
45
37
 
46
- output = Plugin.new_output(type)
47
- output.router = router
48
- output.configure(e)
49
- @outputs << output
38
+ @stores.each { |store|
39
+ @ignore_errors << (store.arg == 'ignore_error')
50
40
  }
51
41
  end
52
42
 
53
- def start
54
- @outputs.each {|o|
55
- o.start
56
- }
43
+ def multi_workers_ready?
44
+ true
57
45
  end
58
46
 
59
- def shutdown
60
- @outputs.each {|o|
61
- o.shutdown
62
- }
63
- end
64
-
65
- def emit(tag, es, chain)
47
+ def process(tag, es)
66
48
  unless es.repeatable?
67
- m = MultiEventStream.new
49
+ m = Fluent::MultiEventStream.new
68
50
  es.each {|time,record|
69
51
  m.add(time, record)
70
52
  }
71
53
  es = m
72
54
  end
73
- if @deep_copy
74
- chain = CopyOutputChain.new(@outputs, tag, es, chain)
75
- else
76
- chain = OutputChain.new(@outputs, tag, es, chain)
55
+
56
+ outputs.each_with_index do |output, i|
57
+ begin
58
+ output.emit_events(tag, @deep_copy ? es.dup : es)
59
+ rescue => e
60
+ if @ignore_errors[i]
61
+ log.error "ignore emit error", error: e
62
+ else
63
+ raise e
64
+ end
65
+ end
77
66
  end
78
- chain.next
79
67
  end
80
68
  end
81
69
  end
@@ -16,93 +16,90 @@
16
16
 
17
17
  require 'tempfile'
18
18
 
19
- require 'fluent/output'
19
+ require 'fluent/plugin/output'
20
20
  require 'fluent/config/error'
21
- require 'fluent/plugin/exec_util'
22
21
 
23
- module Fluent
24
- class ExecOutput < TimeSlicedOutput
25
- Plugin.register_output('exec', self)
22
+ module Fluent::Plugin
23
+ class ExecOutput < Output
24
+ Fluent::Plugin.register_output('exec', self)
26
25
 
27
- def initialize
28
- super
29
- @localtime = false
30
- end
26
+ helpers :inject, :formatter, :compat_parameters, :child_process
31
27
 
32
- desc 'The command (program) to execute. The exec plugin passes the path of a TSV file as the last argumen'
28
+ desc 'The command (program) to execute. The exec plugin passes the path of a TSV file as the last argument'
33
29
  config_param :command, :string
34
- desc 'Specify the comma-separated keys when using the tsv format.'
35
- config_param :keys, default: [] do |val|
36
- val.split(',')
30
+
31
+ config_param :command_timeout, :time, default: 270 # 4min 30sec
32
+
33
+ config_section :format do
34
+ config_set_default :@type, 'tsv'
37
35
  end
38
- desc 'The name of the key to use as the event tag. This replaces the value in the event record.'
39
- config_param :tag_key, :string, default: nil
40
- desc 'The name of the key to use as the event time. This replaces the the value in the event record.'
41
- config_param :time_key, :string, default: nil
42
- desc 'The format for event time used when the time_key parameter is specified. The default is UNIX time (integer).'
43
- config_param :time_format, :string, default: nil
44
- desc "The format used to map the incoming events to the program input. (#{ExecUtil::SUPPORTED_FORMAT.keys.join(',')})"
45
- config_param :format, default: :tsv do |val|
46
- f = ExecUtil::SUPPORTED_FORMAT[val]
47
- raise ConfigError, "Unsupported format '#{val}'" unless f
48
- f
36
+
37
+ config_section :inject do
38
+ config_set_default :time_type, :string
39
+ config_set_default :localtime, false
49
40
  end
50
41
 
51
- def configure(conf)
52
- super
42
+ config_section :buffer do
43
+ config_set_default :delayed_commit_timeout, 300 # 5 min
44
+ end
53
45
 
54
- @formatter = case @format
55
- when :tsv
56
- if @keys.empty?
57
- raise ConfigError, "keys option is required on exec output for tsv format"
58
- end
59
- ExecUtil::TSVFormatter.new(@keys)
60
- when :json
61
- ExecUtil::JSONFormatter.new
62
- when :msgpack
63
- ExecUtil::MessagePackFormatter.new
64
- end
46
+ attr_reader :formatter # for tests
65
47
 
66
- if @time_key
67
- if @time_format
68
- tf = TimeFormatter.new(@time_format, @localtime, @timezone)
69
- @time_format_proc = tf.method(:format)
70
- else
71
- @time_format_proc = Proc.new { |time| time.to_s }
72
- end
73
- end
48
+ def configure(conf)
49
+ compat_parameters_convert(conf, :inject, :formatter, :buffer, default_chunk_key: 'time')
50
+ super
51
+ @formatter = formatter_create
74
52
  end
75
53
 
76
- def format(tag, time, record)
77
- out = ''
78
- if @time_key
79
- record[@time_key] = @time_format_proc.call(time)
80
- end
81
- if @tag_key
82
- record[@tag_key] = tag
83
- end
84
- @formatter.call(record, out)
85
- out
54
+ def multi_workers_ready?
55
+ true
86
56
  end
87
57
 
88
- def write(chunk)
89
- if chunk.respond_to?(:path)
90
- prog = "#{@command} #{chunk.path}"
58
+ NEWLINE = "\n"
59
+
60
+ def format(tag, time, record)
61
+ record = inject_values_to_record(tag, time, record)
62
+ if @formatter.formatter_type == :text_per_line
63
+ @formatter.format(tag, time, record).chomp + NEWLINE
91
64
  else
92
- tmpfile = Tempfile.new("fluent-plugin-exec-")
93
- tmpfile.binmode
94
- chunk.write_to(tmpfile)
95
- tmpfile.close
96
- prog = "#{@command} #{tmpfile.path}"
65
+ @formatter.format(tag, time, record)
97
66
  end
67
+ end
98
68
 
99
- system(prog)
100
- ecode = $?.to_i
101
- tmpfile.delete if tmpfile
102
-
103
- if ecode != 0
104
- raise "command returns #{ecode}: #{prog}"
105
- end
69
+ def try_write(chunk)
70
+ tmpfile = nil
71
+ prog = if chunk.respond_to?(:path)
72
+ "#{@command} #{chunk.path}"
73
+ else
74
+ tmpfile = Tempfile.new("fluent-plugin-out-exec-")
75
+ tmpfile.binmode
76
+ chunk.write_to(tmpfile)
77
+ tmpfile.close
78
+ "#{@command} #{tmpfile.path}"
79
+ end
80
+ chunk_id = chunk.unique_id
81
+ callback = ->(status){
82
+ begin
83
+ if tmpfile
84
+ tmpfile.delete rescue nil
85
+ end
86
+ if status && status.success?
87
+ commit_write(chunk_id)
88
+ elsif status
89
+ # #rollback_write will be done automatically if it isn't called at here.
90
+ # But it's after command_timeout, and this timeout should be longer than users expectation.
91
+ # So here, this plugin calls it explicitly.
92
+ rollback_write(chunk_id)
93
+ log.warn "command exits with error code", prog: prog, status: status.exitstatus, signal: status.termsig
94
+ else
95
+ rollback_write(chunk_id)
96
+ log.warn "command unexpectedly exits without exit status", prog: prog
97
+ end
98
+ rescue => e
99
+ log.error "unexpected error in child process callback", error: e
100
+ end
101
+ }
102
+ child_process_execute(:out_exec_process, prog, stderr: :connect, immediate: true, parallel: true, mode: [], wait_timeout: @command_timeout, on_exit_callback: callback)
106
103
  end
107
104
  end
108
105
  end