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
@@ -16,124 +16,318 @@
16
16
 
17
17
  require 'fileutils'
18
18
  require 'zlib'
19
+ require 'time'
20
+ require 'tempfile'
19
21
 
20
- require 'fluent/output'
22
+ require 'fluent/plugin/output'
21
23
  require 'fluent/config/error'
24
+ # TODO remove ...
25
+ require 'fluent/plugin/file_util'
22
26
 
23
- module Fluent
24
- class FileOutput < TimeSlicedOutput
25
- Plugin.register_output('file', self)
27
+ module Fluent::Plugin
28
+ class FileOutput < Output
29
+ Fluent::Plugin.register_output('file', self)
26
30
 
27
- SUPPORTED_COMPRESS = {
28
- 'gz' => :gz,
29
- 'gzip' => :gz,
31
+ helpers :formatter, :inject, :compat_parameters
32
+
33
+ SUPPORTED_COMPRESS = [:text, :gz, :gzip]
34
+ SUPPORTED_COMPRESS_MAP = {
35
+ text: nil,
36
+ gz: :gzip,
37
+ gzip: :gzip,
30
38
  }
31
39
 
40
+ FILE_PERMISSION = 0644
41
+ DIR_PERMISSION = 0755
42
+
43
+ DEFAULT_TIMEKEY = 60 * 60 * 24
44
+
32
45
  desc "The Path of the file."
33
46
  config_param :path, :string
34
- desc "The format of the file content. The default is out_file."
35
- config_param :format, :string, default: 'out_file'
47
+
48
+ desc "Specify to add file suffix for bare file path or not."
49
+ config_param :add_path_suffix, :bool, default: true
50
+ desc "The file suffix added to bare file path."
51
+ config_param :path_suffix, :string, default: '.log'
36
52
  desc "The flushed chunk is appended to existence file or not."
37
53
  config_param :append, :bool, default: false
38
54
  desc "Compress flushed file."
39
- config_param :compress, default: nil do |val|
40
- c = SUPPORTED_COMPRESS[val]
41
- unless c
42
- raise ConfigError, "Unsupported compression algorithm '#{val}'"
43
- end
44
- c
45
- end
46
- desc "Create symlink to temporary buffered file when buffer_type is file."
55
+ config_param :compress, :enum, list: SUPPORTED_COMPRESS, default: :text
56
+ desc "Execute compression again even when buffer chunk is already compressed."
57
+ config_param :recompress, :bool, default: false
58
+ desc "Create symlink to temporary buffered file when buffer_type is file (disabled on Windows)."
47
59
  config_param :symlink_path, :string, default: nil
48
60
 
49
- def initialize
50
- require 'zlib'
51
- require 'time'
52
- require 'fluent/plugin/file_util'
53
- super
61
+ config_section :format do
62
+ config_set_default :@type, 'out_file'
54
63
  end
55
64
 
56
- def configure(conf)
57
- if path = conf['path']
58
- @path = path
65
+ config_section :buffer do
66
+ config_set_default :@type, 'file'
67
+ config_set_default :chunk_keys, ['time']
68
+ config_set_default :timekey, DEFAULT_TIMEKEY
69
+ end
70
+
71
+ attr_reader :dir_perm
72
+ attr_accessor :last_written_path # for tests
73
+
74
+ module SymlinkBufferMixin
75
+ def output_plugin_for_symlink=(output_plugin)
76
+ @_output_plugin_for_symlink = output_plugin
59
77
  end
60
- unless @path
61
- raise ConfigError, "'path' parameter is required on file output"
78
+
79
+ def symlink_path=(path)
80
+ @_symlink_path = path
62
81
  end
63
82
 
64
- if pos = @path.index('*')
65
- @path_prefix = @path[0,pos]
66
- @path_suffix = @path[pos+1..-1]
67
- conf['buffer_path'] ||= "#{@path}"
68
- else
69
- @path_prefix = @path+"."
70
- @path_suffix = ".log"
71
- conf['buffer_path'] ||= "#{@path}.*"
83
+ def generate_chunk(metadata)
84
+ chunk = super
85
+ # "symlink" feature is to link from symlink_path to the latest file chunk. Records with latest
86
+ # timekey will be appended into that file chunk. On the other side, resumed file chunks might NOT
87
+ # have timekey, especially in the cases that resumed file chunks are generated by Fluentd v0.12.
88
+ # These chunks will be enqueued immediately, and will be flushed soon.
89
+ latest_metadata = metadata_list.select{|m| m.timekey }.sort_by(&:timekey).last
90
+ if chunk.metadata == latest_metadata
91
+ sym_path = @_output_plugin_for_symlink.extract_placeholders(@_symlink_path, chunk)
92
+ FileUtils.mkdir_p(File.dirname(sym_path), mode: @_output_plugin_for_symlink.dir_perm)
93
+ FileUtils.ln_sf(chunk.path, sym_path)
94
+ end
95
+ chunk
96
+ end
97
+ end
98
+
99
+ def configure(conf)
100
+ compat_parameters_convert(conf, :formatter, :buffer, :inject, default_chunk_key: "time")
101
+
102
+ configured_time_slice_format = conf['time_slice_format']
103
+
104
+ if conf.elements(name: 'buffer').empty?
105
+ conf.add_element('buffer', 'time')
106
+ end
107
+ buffer_conf = conf.elements(name: 'buffer').first
108
+ # Fluent::PluginId#configure is not called yet, so we can't use #plugin_root_dir here.
109
+ if !buffer_conf.has_key?('path') && !(conf['@id'] && system_config.root_dir)
110
+ # v0.14 file buffer handles path as directory if '*' is missing
111
+ # 'dummy_path' is not to raise configuration error for 'path' in file buffer plugin,
112
+ # but raise it in this plugin.
113
+ buffer_conf['path'] = conf['path'] || '/tmp/dummy_path'
72
114
  end
73
115
 
74
- test_path = generate_path(Time.now.strftime(@time_slice_format))
75
- unless ::Fluent::FileUtil.writable_p?(test_path)
76
- raise ConfigError, "out_file: `#{test_path}` is not writable"
116
+ if conf.has_key?('utc') || conf.has_key?('localtime')
117
+ param_name = conf.has_key?('utc') ? 'utc' : 'localtime'
118
+ log.warn "'#{param_name}' is deperecated for output plugin. This parameter is used for formatter plugin in compatibility layer. If you want to use same feature, use timekey_use_utc parameter in <buffer> directive instead"
77
119
  end
78
120
 
79
121
  super
80
122
 
81
- @formatter = Plugin.new_formatter(@format)
82
- @formatter.configure(conf)
123
+ @compress_method = SUPPORTED_COMPRESS_MAP[@compress]
124
+
125
+ if @path.include?('*') && !@buffer_config.timekey
126
+ raise Fluent::ConfigError, "path including '*' must be used with buffer chunk key 'time'"
127
+ end
128
+
129
+ path_suffix = @add_path_suffix ? @path_suffix : ''
130
+ path_timekey = if @chunk_key_time
131
+ @as_secondary ? @primary_instance.buffer_config.timekey : @buffer_config.timekey
132
+ else
133
+ nil
134
+ end
135
+ @path_template = generate_path_template(@path, path_timekey, @append, @compress_method, path_suffix: path_suffix, time_slice_format: configured_time_slice_format)
83
136
 
84
- @buffer.symlink_path = @symlink_path if @symlink_path
137
+ if @as_secondary
138
+ # When this plugin is configured as secondary & primary plugin has tag key, but this plugin may not have it.
139
+ # Increment placeholder can make another output file per chunk tag/keys even if original path doesn't include it.
140
+ placeholder_validators(:path, @path_template).select{|v| v.type == :time }.each do |v|
141
+ v.validate!
142
+ end
143
+ else
144
+ placeholder_validate!(:path, @path_template)
145
+
146
+ max_tag_index = get_placeholders_tag(@path_template).max || 1
147
+ max_tag_index = 1 if max_tag_index < 1
148
+ dummy_tag = (['a'] * max_tag_index).join('.')
149
+ dummy_record_keys = get_placeholders_keys(@path_template) || ['message']
150
+ dummy_record = Hash[dummy_record_keys.zip(['data'] * dummy_record_keys.size)]
151
+
152
+ test_chunk1 = chunk_for_test(dummy_tag, Fluent::Engine.now, dummy_record)
153
+ test_path = extract_placeholders(@path_template, test_chunk1)
154
+ unless ::Fluent::FileUtil.writable_p?(test_path)
155
+ raise Fluent::ConfigError, "out_file: `#{test_path}` is not writable"
156
+ end
157
+ end
158
+
159
+ @formatter = formatter_create
160
+
161
+ if @symlink_path && @buffer.respond_to?(:path)
162
+ if @as_secondary
163
+ raise Fluent::ConfigError, "symlink_path option is unavailable in <secondary>: consider to use secondary_file plugin"
164
+ end
165
+ if Fluent.windows?
166
+ log.warn "symlink_path is unavailable on Windows platform. disabled."
167
+ @symlink_path = nil
168
+ else
169
+ @buffer.extend SymlinkBufferMixin
170
+ @buffer.symlink_path = @symlink_path
171
+ @buffer.output_plugin_for_symlink = self
172
+ end
173
+ end
174
+
175
+ @dir_perm = system_config.dir_permission || DIR_PERMISSION
176
+ @file_perm = system_config.file_permission || FILE_PERMISSION
177
+ @need_lock = system_config.workers > 1
178
+ end
179
+
180
+ def multi_workers_ready?
181
+ true
85
182
  end
86
183
 
87
184
  def format(tag, time, record)
88
- @formatter.format(tag, time, record)
185
+ r = inject_values_to_record(tag, time, record)
186
+ @formatter.format(tag, time, r)
89
187
  end
90
188
 
91
189
  def write(chunk)
92
- path = generate_path(chunk.key)
93
- FileUtils.mkdir_p File.dirname(path), mode: DEFAULT_DIR_PERMISSION
190
+ path = extract_placeholders(@path_template, chunk)
191
+ FileUtils.mkdir_p File.dirname(path), mode: @dir_perm
192
+
193
+ writer = case
194
+ when @compress_method.nil?
195
+ method(:write_without_compression)
196
+ when @compress_method == :gzip
197
+ if @buffer.compress != :gzip || @recompress
198
+ method(:write_gzip_with_compression)
199
+ else
200
+ method(:write_gzip_from_gzipped_chunk)
201
+ end
202
+ else
203
+ raise "BUG: unknown compression method #{@compress_method}"
204
+ end
205
+
206
+ if @append
207
+ writer.call(path, chunk)
208
+ else
209
+ find_filepath_available(path, with_lock: @need_lock) do |actual_path|
210
+ writer.call(actual_path, chunk)
211
+ path = actual_path
212
+ end
213
+ end
214
+
215
+ @last_written_path = path
216
+ end
217
+
218
+ def write_without_compression(path, chunk)
219
+ File.open(path, "ab", @file_perm) do |f|
220
+ chunk.write_to(f)
221
+ end
222
+ end
223
+
224
+ def write_gzip_with_compression(path, chunk)
225
+ if @append
226
+ # This code will be removed after zlib/multithread bug is fixed.
227
+ # Use Tempfile to avoid broken gzip files: https://github.com/fluent/fluentd/issues/1903
228
+ Tempfile.create('out_file-gzip-append') { |temp|
229
+ begin
230
+ writer = Zlib::GzipWriter.new(temp)
231
+ chunk.write_to(writer, compressed: :text)
232
+ ensure
233
+ writer.finish # avoid zlib finalizer warning
234
+ end
235
+ temp.rewind
94
236
 
95
- case @compress
96
- when nil
97
- File.open(path, "a", DEFAULT_FILE_PERMISSION) {|f|
98
- chunk.write_to(f)
237
+ File.open(path, "ab", @file_perm) do |f|
238
+ IO.copy_stream(temp, f)
239
+ end
99
240
  }
100
- when :gz
101
- File.open(path, "a", DEFAULT_FILE_PERMISSION) {|f|
241
+ else
242
+ File.open(path, "ab", @file_perm) do |f|
102
243
  gz = Zlib::GzipWriter.new(f)
103
- chunk.write_to(gz)
244
+ chunk.write_to(gz, compressed: :text)
104
245
  gz.close
105
- }
246
+ end
106
247
  end
107
-
108
- return path # for test
109
248
  end
110
249
 
111
- def secondary_init(primary)
112
- # don't warn even if primary.class is not FileOutput
250
+ def write_gzip_from_gzipped_chunk(path, chunk)
251
+ File.open(path, "ab", @file_perm) do |f|
252
+ chunk.write_to(f, compressed: :gzip)
253
+ end
113
254
  end
114
255
 
115
- private
256
+ def timekey_to_timeformat(timekey)
257
+ case timekey
258
+ when nil then ''
259
+ when 0...60 then '%Y%m%d%H%M%S' # 60 exclusive
260
+ when 60...3600 then '%Y%m%d%H%M'
261
+ when 3600...86400 then '%Y%m%d%H'
262
+ else '%Y%m%d'
263
+ end
264
+ end
116
265
 
117
- def suffix
118
- case @compress
119
- when nil
120
- ''
121
- when :gz
122
- ".gz"
266
+ def compression_suffix(compress)
267
+ case compress
268
+ when :gzip then '.gz'
269
+ when nil then ''
270
+ else
271
+ raise ArgumentError, "unknown compression type #{compress}"
123
272
  end
124
273
  end
125
274
 
126
- def generate_path(time_string)
127
- if @append
128
- "#{@path_prefix}#{time_string}#{@path_suffix}#{suffix}"
275
+ # /path/to/dir/file.* -> /path/to/dir/file.%Y%m%d
276
+ # /path/to/dir/file.*.data -> /path/to/dir/file.%Y%m%d.data
277
+ # /path/to/dir/file -> /path/to/dir/file.%Y%m%d.log
278
+ # %Y%m%d -> %Y%m%d_** (non append)
279
+ # + .gz (gzipped)
280
+ ## TODO: remove time_slice_format when end of support of compat_parameters
281
+ def generate_path_template(original, timekey, append, compress, path_suffix: '', time_slice_format: nil)
282
+ comp_suffix = compression_suffix(compress)
283
+ index_placeholder = append ? '' : '_**'
284
+ if original.index('*')
285
+ raise "BUG: configuration error must be raised for path including '*' without timekey" unless timekey
286
+ time_placeholders_part = time_slice_format || timekey_to_timeformat(timekey)
287
+ original.gsub('*', time_placeholders_part + index_placeholder) + comp_suffix
129
288
  else
130
- path = nil
131
- i = 0
132
- begin
133
- path = "#{@path_prefix}#{time_string}_#{i}#{@path_suffix}#{suffix}"
134
- i += 1
135
- end while File.exist?(path)
136
- path
289
+ if timekey
290
+ if time_slice_format
291
+ "#{original}.#{time_slice_format}#{index_placeholder}#{path_suffix}#{comp_suffix}"
292
+ else
293
+ time_placeholders = timekey_to_timeformat(timekey)
294
+ if time_placeholders.scan(/../).any?{|ph| original.include?(ph) }
295
+ raise Fluent::ConfigError, "insufficient timestamp placeholders in path" if time_placeholders.scan(/../).any?{|ph| !original.include?(ph) }
296
+ "#{original}#{index_placeholder}#{path_suffix}#{comp_suffix}"
297
+ else
298
+ "#{original}.#{time_placeholders}#{index_placeholder}#{path_suffix}#{comp_suffix}"
299
+ end
300
+ end
301
+ else
302
+ "#{original}#{index_placeholder}#{path_suffix}#{comp_suffix}"
303
+ end
304
+ end
305
+ end
306
+
307
+ def find_filepath_available(path_with_placeholder, with_lock: false) # for non-append
308
+ raise "BUG: index placeholder not found in path: #{path_with_placeholder}" unless path_with_placeholder.index('_**')
309
+ i = 0
310
+ dir_path = locked = nil
311
+ while true
312
+ path = path_with_placeholder.sub('_**', "_#{i}")
313
+ i += 1
314
+ next if File.exist?(path)
315
+
316
+ if with_lock
317
+ dir_path = path + '.lock'
318
+ locked = Dir.mkdir(dir_path) rescue false
319
+ next unless locked
320
+ # ensure that other worker doesn't create a file (and release lock)
321
+ # between previous File.exist? and Dir.mkdir
322
+ next if File.exist?(path)
323
+ end
324
+
325
+ break
326
+ end
327
+ yield path
328
+ ensure
329
+ if dir_path && locked && Dir.exist?(dir_path)
330
+ Dir.rmdir(dir_path) rescue nil
137
331
  end
138
332
  end
139
333
  end