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
@@ -0,0 +1,250 @@
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 'socket'
18
+ require 'ipaddr'
19
+ require 'openssl'
20
+
21
+ require_relative 'socket_option'
22
+
23
+ module Fluent
24
+ module PluginHelper
25
+ module Socket
26
+ # stop : [-]
27
+ # shutdown : [-]
28
+ # close : [-]
29
+ # terminate: [-]
30
+
31
+ include Fluent::PluginHelper::SocketOption
32
+
33
+ TLS_DEFAULT_VERSION = :'TLSv1_2'
34
+ TLS_SUPPORTED_VERSIONS = [:'TLSv1_1', :'TLSv1_2']
35
+ ### follow httpclient configuration by nahi
36
+ # OpenSSL 0.9.8 default: "ALL:!ADH:!LOW:!EXP:!MD5:+SSLv2:@STRENGTH"
37
+ CIPHERS_DEFAULT = "ALL:!aNULL:!eNULL:!SSLv2" # OpenSSL >1.0.0 default
38
+
39
+ attr_reader :_sockets # for tests
40
+
41
+ # TODO: implement connection pool for specified host
42
+
43
+ def socket_create(proto, host, port, **kwargs, &block)
44
+ case proto
45
+ when :tcp
46
+ socket_create_tcp(host, port, **kwargs, &block)
47
+ when :udp
48
+ socket_create_udp(host, port, **kwargs, &block)
49
+ when :tls
50
+ socket_create_tls(host, port, **kwargs, &block)
51
+ when :unix
52
+ raise "not implemented yet"
53
+ else
54
+ raise ArgumentError, "invalid protocol: #{proto}"
55
+ end
56
+ end
57
+
58
+ def socket_create_tcp(host, port, resolve_name: false, connect_timeout: nil, **kwargs, &block)
59
+ sock = if connect_timeout
60
+ s = ::Socket.tcp(host, port, connect_timeout: connect_timeout)
61
+ s.autoclose = false # avoid GC triggered close
62
+ WrappedSocket::TCP.for_fd(s.fileno)
63
+ else
64
+ WrappedSocket::TCP.new(host, port)
65
+ end
66
+ socket_option_set(sock, resolve_name: resolve_name, **kwargs)
67
+ if block
68
+ begin
69
+ block.call(sock)
70
+ ensure
71
+ sock.close_write rescue nil
72
+ sock.close rescue nil
73
+ end
74
+ else
75
+ sock
76
+ end
77
+ end
78
+
79
+ def socket_create_udp(host, port, resolve_name: false, connect: false, **kwargs, &block)
80
+ family = IPAddr.new(IPSocket.getaddress(host)).ipv4? ? ::Socket::AF_INET : ::Socket::AF_INET6
81
+ sock = WrappedSocket::UDP.new(family)
82
+ socket_option_set(sock, resolve_name: resolve_name, **kwargs)
83
+ sock.connect(host, port) if connect
84
+ if block
85
+ begin
86
+ block.call(sock)
87
+ ensure
88
+ sock.close rescue nil
89
+ end
90
+ else
91
+ sock
92
+ end
93
+ end
94
+
95
+ def socket_create_tls(
96
+ host, port,
97
+ version: TLS_DEFAULT_VERSION, ciphers: CIPHERS_DEFAULT, insecure: false, verify_fqdn: true, fqdn: nil,
98
+ enable_system_cert_store: true, allow_self_signed_cert: false, cert_paths: nil,
99
+ cert_path: nil, private_key_path: nil, private_key_passphrase: nil, **kwargs, &block)
100
+
101
+ host_is_ipaddress = IPAddr.new(host) rescue false
102
+ fqdn ||= host unless host_is_ipaddress
103
+
104
+ context = OpenSSL::SSL::SSLContext.new(version)
105
+
106
+ if insecure
107
+ log.trace "setting TLS verify_mode NONE"
108
+ context.verify_mode = OpenSSL::SSL::VERIFY_NONE
109
+ else
110
+ cert_store = OpenSSL::X509::Store.new
111
+ if allow_self_signed_cert && OpenSSL::X509.const_defined?('V_FLAG_CHECK_SS_SIGNATURE')
112
+ cert_store.flags = OpenSSL::X509::V_FLAG_CHECK_SS_SIGNATURE
113
+ end
114
+ begin
115
+ if enable_system_cert_store
116
+ log.trace "loading system default certificate store"
117
+ cert_store.set_default_paths
118
+ end
119
+ rescue OpenSSL::X509::StoreError
120
+ log.warn "failed to load system default certificate store", error: e
121
+ end
122
+ if cert_paths
123
+ if cert_paths.respond_to?(:each)
124
+ cert_paths.each do |cert_path|
125
+ log.trace "adding CA cert", path: cert_path
126
+ cert_store.add_file(cert_path)
127
+ end
128
+ else
129
+ cert_path = cert_paths
130
+ log.trace "adding CA cert", path: cert_path
131
+ cert_store.add_file(cert_path)
132
+ end
133
+ end
134
+
135
+ log.trace "setting TLS context", mode: "peer", ciphers: ciphers
136
+ context.set_params({})
137
+ context.ciphers = ciphers
138
+ context.verify_mode = OpenSSL::SSL::VERIFY_PEER
139
+ context.cert_store = cert_store
140
+ context.verify_hostname = true if verify_fqdn && fqdn && context.respond_to?(:verify_hostname=)
141
+ context.cert = OpenSSL::X509::Certificate.new(File.read(cert_path)) if cert_path
142
+ context.key = OpenSSL::PKey::read(File.read(private_key_path), private_key_passphrase) if private_key_path
143
+ end
144
+
145
+ tcpsock = socket_create_tcp(host, port, **kwargs)
146
+ sock = WrappedSocket::TLS.new(tcpsock, context)
147
+ sock.sync_close = true
148
+ sock.hostname = fqdn if verify_fqdn && fqdn && sock.respond_to?(:hostname=)
149
+
150
+ log.trace "entering TLS handshake"
151
+ sock.connect
152
+
153
+ begin
154
+ if verify_fqdn
155
+ log.trace "checking peer's certificate", subject: sock.peer_cert.subject
156
+ sock.post_connection_check(fqdn)
157
+ verify = sock.verify_result
158
+ if verify != OpenSSL::X509::V_OK
159
+ err_name = Socket.tls_verify_result_name(verify)
160
+ log.warn "BUG: failed to verify certification while connecting (but not raised, why?)", host: host, fqdn: fqdn, error: err_name
161
+ raise RuntimeError, "BUG: failed to verify certification and to handle it correctly while connecting host #{host} as #{fqdn}"
162
+ end
163
+ end
164
+ rescue OpenSSL::SSL::SSLError => e
165
+ log.warn "failed to verify certification while connecting tls session", host: host, fqdn: fqdn, error: e
166
+ raise
167
+ end
168
+
169
+ if block
170
+ begin
171
+ block.call(sock)
172
+ ensure
173
+ sock.close rescue nil
174
+ end
175
+ else
176
+ sock
177
+ end
178
+ end
179
+
180
+ def self.tls_verify_result_name(code)
181
+ case code
182
+ when OpenSSL::X509::V_OK then 'V_OK'
183
+ when OpenSSL::X509::V_ERR_AKID_SKID_MISMATCH then 'V_ERR_AKID_SKID_MISMATCH'
184
+ when OpenSSL::X509::V_ERR_APPLICATION_VERIFICATION then 'V_ERR_APPLICATION_VERIFICATION'
185
+ when OpenSSL::X509::V_ERR_CERT_CHAIN_TOO_LONG then 'V_ERR_CERT_CHAIN_TOO_LONG'
186
+ when OpenSSL::X509::V_ERR_CERT_HAS_EXPIRED then 'V_ERR_CERT_HAS_EXPIRED'
187
+ when OpenSSL::X509::V_ERR_CERT_NOT_YET_VALID then 'V_ERR_CERT_NOT_YET_VALID'
188
+ when OpenSSL::X509::V_ERR_CERT_REJECTED then 'V_ERR_CERT_REJECTED'
189
+ when OpenSSL::X509::V_ERR_CERT_REVOKED then 'V_ERR_CERT_REVOKED'
190
+ when OpenSSL::X509::V_ERR_CERT_SIGNATURE_FAILURE then 'V_ERR_CERT_SIGNATURE_FAILURE'
191
+ when OpenSSL::X509::V_ERR_CERT_UNTRUSTED then 'V_ERR_CERT_UNTRUSTED'
192
+ when OpenSSL::X509::V_ERR_CRL_HAS_EXPIRED then 'V_ERR_CRL_HAS_EXPIRED'
193
+ when OpenSSL::X509::V_ERR_CRL_NOT_YET_VALID then 'V_ERR_CRL_NOT_YET_VALID'
194
+ when OpenSSL::X509::V_ERR_CRL_SIGNATURE_FAILURE then 'V_ERR_CRL_SIGNATURE_FAILURE'
195
+ when OpenSSL::X509::V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT then 'V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT'
196
+ when OpenSSL::X509::V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD then 'V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD'
197
+ when OpenSSL::X509::V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD then 'V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD'
198
+ when OpenSSL::X509::V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD then 'V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD'
199
+ when OpenSSL::X509::V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD then 'V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD'
200
+ when OpenSSL::X509::V_ERR_INVALID_CA then 'V_ERR_INVALID_CA'
201
+ when OpenSSL::X509::V_ERR_INVALID_PURPOSE then 'V_ERR_INVALID_PURPOSE'
202
+ when OpenSSL::X509::V_ERR_KEYUSAGE_NO_CERTSIGN then 'V_ERR_KEYUSAGE_NO_CERTSIGN'
203
+ when OpenSSL::X509::V_ERR_OUT_OF_MEM then 'V_ERR_OUT_OF_MEM'
204
+ when OpenSSL::X509::V_ERR_PATH_LENGTH_EXCEEDED then 'V_ERR_PATH_LENGTH_EXCEEDED'
205
+ when OpenSSL::X509::V_ERR_SELF_SIGNED_CERT_IN_CHAIN then 'V_ERR_SELF_SIGNED_CERT_IN_CHAIN'
206
+ when OpenSSL::X509::V_ERR_SUBJECT_ISSUER_MISMATCH then 'V_ERR_SUBJECT_ISSUER_MISMATCH'
207
+ when OpenSSL::X509::V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY then 'V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY'
208
+ when OpenSSL::X509::V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE then 'V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY'
209
+ when OpenSSL::X509::V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE then 'V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE'
210
+ when OpenSSL::X509::V_ERR_UNABLE_TO_GET_CRL then 'V_ERR_UNABLE_TO_GET_CRL'
211
+ when OpenSSL::X509::V_ERR_UNABLE_TO_GET_ISSUER_CERT then 'V_ERR_UNABLE_TO_GET_ISSUER_CERT'
212
+ when OpenSSL::X509::V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY then 'V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY'
213
+ when OpenSSL::X509::V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE then 'V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE'
214
+ end
215
+ end
216
+
217
+ # socket_create_socks ?
218
+
219
+ module WrappedSocket
220
+ class TCP < ::TCPSocket
221
+ def remote_addr; peeraddr[3]; end
222
+ def remote_host; peeraddr[2]; end
223
+ def remote_port; peeraddr[1]; end
224
+ end
225
+ class UDP < ::UDPSocket
226
+ def remote_addr; peeraddr[3]; end
227
+ def remote_host; peeraddr[2]; end
228
+ def remote_port; peeraddr[1]; end
229
+ end
230
+ class TLS < OpenSSL::SSL::SSLSocket
231
+ def remote_addr; peeraddr[3]; end
232
+ def remote_host; peeraddr[2]; end
233
+ def remote_port; peeraddr[1]; end
234
+ end
235
+ end
236
+
237
+ def initialize
238
+ super
239
+ # @_sockets = [] # for keepalived sockets / connection pool
240
+ end
241
+
242
+ # def close
243
+ # @_sockets.each do |sock|
244
+ # sock.close
245
+ # end
246
+ # super
247
+ # end
248
+ end
249
+ end
250
+ end
@@ -0,0 +1,80 @@
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 'socket'
18
+ require 'fcntl'
19
+
20
+ # this module is only for Socket/Server plugin helpers
21
+ module Fluent
22
+ module PluginHelper
23
+ module SocketOption
24
+ FORMAT_STRUCT_LINGER = 'I!I!' # { int l_onoff; int l_linger; }
25
+ FORMAT_STRUCT_TIMEVAL = 'L!L!' # { time_t tv_sec; suseconds_t tv_usec; }
26
+
27
+ def socket_option_validate!(protocol, resolve_name: nil, linger_timeout: nil, recv_timeout: nil, send_timeout: nil, receive_buffer_size: nil, send_keepalive_packet: nil)
28
+ unless resolve_name.nil?
29
+ if protocol != :tcp && protocol != :udp && protocol != :tls
30
+ raise ArgumentError, "BUG: resolve_name in available for tcp/udp/tls"
31
+ end
32
+ end
33
+ if linger_timeout
34
+ if protocol != :tcp && protocol != :tls
35
+ raise ArgumentError, "BUG: linger_timeout is available for tcp/tls"
36
+ end
37
+ end
38
+ if send_keepalive_packet
39
+ if protocol != :tcp
40
+ raise ArgumentError, "BUG: send_keepalive_packet is available for tcp"
41
+ end
42
+ end
43
+ end
44
+
45
+ def socket_option_set(sock, resolve_name: nil, nonblock: false, linger_timeout: nil, recv_timeout: nil, send_timeout: nil, receive_buffer_size: nil, send_keepalive_packet: nil)
46
+ unless resolve_name.nil?
47
+ sock.do_not_reverse_lookup = !resolve_name
48
+ end
49
+ if nonblock
50
+ sock.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
51
+ end
52
+ if linger_timeout
53
+ optval = [1, linger_timeout.to_i].pack(FORMAT_STRUCT_LINGER)
54
+ socket_option_set_one(sock, :SO_LINGER, optval)
55
+ end
56
+ if recv_timeout
57
+ optval = [recv_timeout.to_i, 0].pack(FORMAT_STRUCT_TIMEVAL)
58
+ socket_option_set_one(sock, :SO_RCVTIMEO, optval)
59
+ end
60
+ if send_timeout
61
+ optval = [send_timeout.to_i, 0].pack(FORMAT_STRUCT_TIMEVAL)
62
+ socket_option_set_one(sock, :SO_SNDTIMEO, optval)
63
+ end
64
+ if receive_buffer_size
65
+ socket_option_set_one(sock, :SO_RCVBUF, receive_buffer_size.to_i)
66
+ end
67
+ if send_keepalive_packet
68
+ socket_option_set_one(sock, :SO_KEEPALIVE, true)
69
+ end
70
+ sock
71
+ end
72
+
73
+ def socket_option_set_one(sock, option, value)
74
+ sock.setsockopt(::Socket::SOL_SOCKET, option, value)
75
+ rescue => e
76
+ log.warn "failed to set socket option", sock: sock.class, option: option, value: value, error: e
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,349 @@
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 'forwardable'
18
+
19
+ require 'fluent/plugin'
20
+ require 'fluent/plugin/storage'
21
+ require 'fluent/plugin_helper/timer'
22
+ require 'fluent/config/element'
23
+ require 'fluent/configurable'
24
+
25
+ module Fluent
26
+ module PluginHelper
27
+ module Storage
28
+ include Fluent::PluginHelper::Timer
29
+
30
+ StorageState = Struct.new(:storage, :running)
31
+
32
+ def storage_create(usage: '', type: nil, conf: nil, default_type: nil)
33
+ if conf && conf.respond_to?(:arg) && !conf.arg.empty?
34
+ usage = conf.arg
35
+ end
36
+ if !usage.empty? && usage !~ /^[a-zA-Z][-_.a-zA-Z0-9]*$/
37
+ raise Fluent::ConfigError, "Argument in <storage ARG> uses invalid characters: '#{usage}'"
38
+ end
39
+
40
+ s = @_storages[usage]
41
+ if s && s.running
42
+ return s.storage
43
+ elsif s
44
+ # storage is already created, but not loaded / started
45
+ else # !s
46
+ type = if type
47
+ type
48
+ elsif conf && conf.respond_to?(:[])
49
+ raise Fluent::ConfigError, "@type is required in <storage>" unless conf['@type']
50
+ conf['@type']
51
+ elsif default_type
52
+ default_type
53
+ else
54
+ raise ArgumentError, "BUG: both type and conf are not specified"
55
+ end
56
+ storage = Plugin.new_storage(type, parent: self)
57
+ config = case conf
58
+ when Fluent::Config::Element
59
+ conf
60
+ when Hash
61
+ # in code, programmer may use symbols as keys, but Element needs strings
62
+ conf = Hash[conf.map{|k,v| [k.to_s, v]}]
63
+ Fluent::Config::Element.new('storage', usage, conf, [])
64
+ when nil
65
+ Fluent::Config::Element.new('storage', usage, {'@type' => type}, [])
66
+ else
67
+ raise ArgumentError, "BUG: conf must be a Element, Hash (or unspecified), but '#{conf.class}'"
68
+ end
69
+ storage.configure(config)
70
+ if @_storages_started
71
+ storage.start
72
+ end
73
+ s = @_storages[usage] = StorageState.new(wrap_instance(storage), false)
74
+ end
75
+
76
+ s.storage
77
+ end
78
+
79
+ module StorageParams
80
+ include Fluent::Configurable
81
+ # minimum section definition to instantiate storage plugin instances
82
+ config_section :storage, required: false, multi: true, param_name: :storage_configs, init: true do
83
+ config_argument :usage, :string, default: ''
84
+ config_param :@type, :string, default: Fluent::Plugin::Storage::DEFAULT_TYPE
85
+ end
86
+ end
87
+
88
+ def self.included(mod)
89
+ mod.include StorageParams
90
+ end
91
+
92
+ attr_reader :_storages # for tests
93
+
94
+ def initialize
95
+ super
96
+ @_storages_started = false
97
+ @_storages = {} # usage => storage_state
98
+ end
99
+
100
+ def configure(conf)
101
+ super
102
+
103
+ @storage_configs.each do |section|
104
+ if !section.usage.empty? && section.usage !~ /^[a-zA-Z][-_.a-zA-Z0-9]*$/
105
+ raise Fluent::ConfigError, "Argument in <storage ARG> uses invalid characters: '#{section.usage}'"
106
+ end
107
+ if @_storages[section.usage]
108
+ raise Fluent::ConfigError, "duplicated storages configured: #{section.usage}"
109
+ end
110
+ storage = Plugin.new_storage(section[:@type], parent: self)
111
+ storage.configure(section.corresponding_config_element)
112
+ @_storages[section.usage] = StorageState.new(wrap_instance(storage), false)
113
+ end
114
+ end
115
+
116
+ def start
117
+ super
118
+
119
+ @_storages_started = true
120
+ @_storages.each_pair do |usage, s|
121
+ s.storage.start
122
+ s.storage.load
123
+
124
+ if s.storage.autosave && !s.storage.persistent
125
+ timer_execute(:storage_autosave, s.storage.autosave_interval, repeat: true) do
126
+ begin
127
+ s.storage.save
128
+ rescue => e
129
+ log.error "plugin storage failed to save its data", usage: usage, type: type, error: e
130
+ end
131
+ end
132
+ end
133
+ s.running = true
134
+ end
135
+ end
136
+
137
+ def storage_operate(method_name, &block)
138
+ @_storages.each_pair do |usage, s|
139
+ begin
140
+ block.call(s) if block_given?
141
+ s.storage.send(method_name)
142
+ rescue => e
143
+ log.error "unexpected error while #{method_name}", usage: usage, storage: s.storage, error: e
144
+ end
145
+ end
146
+ end
147
+
148
+ def stop
149
+ super
150
+ # timer stops automatically in super
151
+ storage_operate(:stop)
152
+ end
153
+
154
+ def before_shutdown
155
+ storage_operate(:before_shutdown)
156
+ super
157
+ end
158
+
159
+ def shutdown
160
+ storage_operate(:shutdown) do |s|
161
+ s.storage.save if s.storage.save_at_shutdown
162
+ end
163
+ super
164
+ end
165
+
166
+ def after_shutdown
167
+ storage_operate(:after_shutdown)
168
+ super
169
+ end
170
+
171
+ def close
172
+ storage_operate(:close){|s| s.running = false }
173
+ super
174
+ end
175
+
176
+ def terminate
177
+ storage_operate(:terminate)
178
+ @_storages = {}
179
+ super
180
+ end
181
+
182
+ def wrap_instance(storage)
183
+ if storage.persistent && storage.persistent_always?
184
+ storage
185
+ elsif storage.persistent
186
+ PersistentWrapper.new(storage)
187
+ elsif !storage.synchronized?
188
+ SynchronizeWrapper.new(storage)
189
+ else
190
+ storage
191
+ end
192
+ end
193
+
194
+ class PersistentWrapper
195
+ # PersistentWrapper always provides synchronized operations
196
+ extend Forwardable
197
+
198
+ def initialize(storage)
199
+ @storage = storage
200
+ @monitor = Monitor.new
201
+ end
202
+
203
+ def_delegators :@storage, :autosave_interval, :save_at_shutdown
204
+ def_delegators :@storage, :start, :stop, :before_shutdown, :shutdown, :after_shutdown, :close, :terminate
205
+ def_delegators :@storage, :started?, :stopped?, :before_shutdown?, :shutdown?, :after_shutdown?, :closed?, :terminated?
206
+
207
+ def method_missing(name, *args)
208
+ @monitor.synchronize{ @storage.__send__(name, *args) }
209
+ end
210
+
211
+ def persistent_always?
212
+ true
213
+ end
214
+
215
+ def persistent
216
+ true
217
+ end
218
+
219
+ def autosave
220
+ false
221
+ end
222
+
223
+ def synchronized?
224
+ true
225
+ end
226
+
227
+ def implementation
228
+ @storage
229
+ end
230
+
231
+ def load
232
+ @monitor.synchronize do
233
+ @storage.load
234
+ end
235
+ end
236
+
237
+ def save
238
+ @monitor.synchronize do
239
+ @storage.save
240
+ end
241
+ end
242
+
243
+ def get(key)
244
+ @monitor.synchronize do
245
+ @storage.load
246
+ @storage.get(key)
247
+ end
248
+ end
249
+
250
+ def fetch(key, defval)
251
+ @monitor.synchronize do
252
+ @storage.load
253
+ @storage.fetch(key, defval)
254
+ end
255
+ end
256
+
257
+ def put(key, value)
258
+ @monitor.synchronize do
259
+ @storage.load
260
+ @storage.put(key, value)
261
+ @storage.save
262
+ value
263
+ end
264
+ end
265
+
266
+ def delete(key)
267
+ @monitor.synchronize do
268
+ @storage.load
269
+ val = @storage.delete(key)
270
+ @storage.save
271
+ val
272
+ end
273
+ end
274
+
275
+ def update(key, &block)
276
+ @monitor.synchronize do
277
+ @storage.load
278
+ v = block.call(@storage.get(key))
279
+ @storage.put(key, v)
280
+ @storage.save
281
+ v
282
+ end
283
+ end
284
+ end
285
+
286
+ class SynchronizeWrapper
287
+ extend Forwardable
288
+
289
+ def initialize(storage)
290
+ @storage = storage
291
+ @monitor = Monitor.new
292
+ end
293
+
294
+ def_delegators :@storage, :persistent, :autosave, :autosave_interval, :save_at_shutdown
295
+ def_delegators :@storage, :persistent_always?
296
+ def_delegators :@storage, :start, :stop, :before_shutdown, :shutdown, :after_shutdown, :close, :terminate
297
+ def_delegators :@storage, :started?, :stopped?, :before_shutdown?, :shutdown?, :after_shutdown?, :closed?, :terminated?
298
+
299
+ def method_missing(name, *args)
300
+ @monitor.synchronize{ @storage.__send__(name, *args) }
301
+ end
302
+
303
+ def synchronized?
304
+ true
305
+ end
306
+
307
+ def implementation
308
+ @storage
309
+ end
310
+
311
+ def load
312
+ @monitor.synchronize do
313
+ @storage.load
314
+ end
315
+ end
316
+
317
+ def save
318
+ @monitor.synchronize do
319
+ @storage.save
320
+ end
321
+ end
322
+
323
+ def get(key)
324
+ @monitor.synchronize{ @storage.get(key) }
325
+ end
326
+
327
+ def fetch(key, defval)
328
+ @monitor.synchronize{ @storage.fetch(key, defval) }
329
+ end
330
+
331
+ def put(key, value)
332
+ @monitor.synchronize{ @storage.put(key, value) }
333
+ end
334
+
335
+ def delete(key)
336
+ @monitor.synchronize{ @storage.delete(key) }
337
+ end
338
+
339
+ def update(key, &block)
340
+ @monitor.synchronize do
341
+ v = block.call(@storage.get(key))
342
+ @storage.put(key, v)
343
+ v
344
+ end
345
+ end
346
+ end
347
+ end
348
+ end
349
+ end