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,13 +14,13 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
- require 'cool.io'
17
+ require 'fluent/plugin/input'
18
18
 
19
- require 'fluent/input'
19
+ module Fluent::Plugin
20
+ class GCStatInput < Fluent::Plugin::Input
21
+ Fluent::Plugin.register_input('gc_stat', self)
20
22
 
21
- module Fluent
22
- class GCStatInput < Input
23
- Plugin.register_input('gc_stat', self)
23
+ helpers :timer
24
24
 
25
25
  def initialize
26
26
  super
@@ -29,48 +29,26 @@ module Fluent
29
29
  config_param :emit_interval, :time, default: 60
30
30
  config_param :tag, :string
31
31
 
32
- class TimerWatcher < Coolio::TimerWatcher
33
- def initialize(interval, repeat, log, &callback)
34
- @callback = callback
35
- @log = log
36
- super(interval, repeat)
37
- end
38
-
39
- def on_timer
40
- @callback.call
41
- rescue
42
- # TODO log?
43
- @log.error $!.to_s
44
- @log.error_backtrace
45
- end
46
- end
47
-
48
32
  def configure(conf)
49
33
  super
50
34
  end
51
35
 
52
- def start
53
- @loop = Coolio::Loop.new
54
- @timer = TimerWatcher.new(@emit_interval, true, log, &method(:on_timer))
55
- @loop.attach(@timer)
56
- @thread = Thread.new(&method(:run))
36
+ def multi_workers_ready?
37
+ true
57
38
  end
58
39
 
59
- def shutdown
60
- @loop.watchers.each {|w| w.detach }
61
- @loop.stop
62
- @thread.join
40
+ def start
41
+ super
42
+
43
+ timer_execute(:in_gc_stat, @emit_interval, &method(:on_timer))
63
44
  end
64
45
 
65
- def run
66
- @loop.run
67
- rescue
68
- log.error "unexpected error", error: $!.to_s
69
- log.error_backtrace
46
+ def shutdown
47
+ super
70
48
  end
71
49
 
72
50
  def on_timer
73
- now = Engine.now
51
+ now = Fluent::EventTime.now
74
52
  record = GC.stat
75
53
  router.emit(@tag, now, record)
76
54
  end
@@ -14,28 +14,29 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'fluent/plugin/input'
18
+ require 'fluent/plugin/parser'
19
+ require 'fluent/event'
20
+
21
+ require 'http/parser'
22
+ require 'webrick/httputils'
17
23
  require 'uri'
18
24
  require 'socket'
19
25
  require 'json'
20
26
 
21
- require 'cool.io'
22
-
23
- require 'fluent/input'
24
- require 'fluent/event'
25
- require 'fluent/process'
27
+ module Fluent::Plugin
28
+ class InHttpParser < Parser
29
+ Fluent::Plugin.register_parser('in_http', self)
30
+ def parse(text)
31
+ # this plugin is dummy implementation not to raise error
32
+ yield nil, nil
33
+ end
34
+ end
26
35
 
27
- module Fluent
28
36
  class HttpInput < Input
29
- Plugin.register_input('http', self)
30
-
31
- include DetachMultiProcessMixin
32
-
33
- require 'http/parser'
37
+ Fluent::Plugin.register_input('http', self)
34
38
 
35
- def initialize
36
- require 'webrick/httputils'
37
- super
38
- end
39
+ helpers :parser, :compat_parameters, :event_loop, :server
39
40
 
40
41
  EMPTY_GIF_IMAGE = "GIF89a\u0001\u0000\u0001\u0000\x80\xFF\u0000\xFF\xFF\xFF\u0000\u0000\u0000,\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0002\u0002D\u0001\u0000;".force_encoding("UTF-8")
41
42
 
@@ -52,25 +53,42 @@ module Fluent
52
53
  config_param :add_http_headers, :bool, default: false
53
54
  desc 'Add REMOTE_ADDR header to the record.'
54
55
  config_param :add_remote_addr, :bool, default: false
55
- desc 'The format of the HTTP body.'
56
- config_param :format, :string, default: 'default'
57
56
  config_param :blocking_timeout, :time, default: 0.5
58
57
  desc 'Set a white list of domains that can do CORS (Cross-Origin Resource Sharing)'
59
58
  config_param :cors_allow_origins, :array, default: nil
60
59
  desc 'Respond with empty gif image of 1x1 pixel.'
61
60
  config_param :respond_with_empty_img, :bool, default: false
62
61
 
62
+ config_section :parse do
63
+ config_set_default :@type, 'in_http'
64
+ end
65
+
66
+ EVENT_RECORD_PARAMETER = '_event_record'
67
+
63
68
  def configure(conf)
69
+ compat_parameters_convert(conf, :parser)
70
+
64
71
  super
65
72
 
66
- m = if @format == 'default'
73
+ m = if @parser_configs.first['@type'] == 'in_http'
74
+ @parser_msgpack = parser_create(usage: 'parser_in_http_msgpack', type: 'msgpack')
75
+ @parser_msgpack.estimate_current_event = false
76
+ @parser_json = parser_create(usage: 'parser_in_http_json', type: 'json')
77
+ @parser_json.estimate_current_event = false
78
+ @format_name = 'default'
79
+ @parser_time_key = if parser_config = conf.elements('parse').first
80
+ parser_config['time_key'] || 'time'
81
+ else
82
+ 'time'
83
+ end
67
84
  method(:parse_params_default)
68
85
  else
69
- @parser = Plugin.new_parser(@format)
70
- @parser.configure(conf)
86
+ @parser = parser_create
87
+ @format_name = @parser_configs.first['@type']
88
+ @parser_time_key = @parser.time_key
71
89
  method(:parse_params_with_parser)
72
90
  end
73
- (class << self; self; end).module_eval do
91
+ self.singleton_class.module_eval do
74
92
  define_method(:parse_params, m)
75
93
  end
76
94
  end
@@ -99,39 +117,27 @@ module Fluent
99
117
  end
100
118
  end
101
119
 
102
- def start
103
- log.debug "listening http on #{@bind}:#{@port}"
104
- lsock = TCPServer.new(@bind, @port)
105
-
106
- detach_multi_process do
107
- super
108
- @km = KeepaliveManager.new(@keepalive_timeout)
109
- #@lsock = Coolio::TCPServer.new(@bind, @port, Handler, @km, method(:on_request), @body_size_limit)
110
- @lsock = Coolio::TCPServer.new(lsock, nil, Handler, @km, method(:on_request),
111
- @body_size_limit, @format, log,
112
- @cors_allow_origins)
113
- @lsock.listen(@backlog) unless @backlog.nil?
114
-
115
- @loop = Coolio::Loop.new
116
- @loop.attach(@km)
117
- @loop.attach(@lsock)
118
-
119
- @thread = Thread.new(&method(:run))
120
- end
120
+ def multi_workers_ready?
121
+ true
121
122
  end
122
123
 
123
- def shutdown
124
- @loop.watchers.each {|w| w.detach }
125
- @loop.stop
126
- @lsock.close
127
- @thread.join
124
+ def start
125
+ @_event_loop_run_timeout = @blocking_timeout
126
+
127
+ super
128
+
129
+ log.debug "listening http", bind: @bind, port: @port
130
+
131
+ @km = KeepaliveManager.new(@keepalive_timeout)
132
+ event_loop_attach(@km)
133
+
134
+ server_create_connection(:in_http, @port, bind: @bind, backlog: @backlog, &method(:on_server_connect))
135
+ @float_time_parser = Fluent::NumericTimeParser.new(:float)
128
136
  end
129
137
 
130
- def run
131
- @loop.run(@blocking_timeout)
132
- rescue
133
- log.error "unexpected error", error: $!.to_s
134
- log.error_backtrace
138
+ def close
139
+ server_wait_until_stop
140
+ super
135
141
  end
136
142
 
137
143
  def on_request(path_info, params)
@@ -142,10 +148,11 @@ module Fluent
142
148
 
143
149
  # Skip nil record
144
150
  if record.nil?
151
+ log.debug { "incoming event is invalid: path=#{path_info} params=#{params.to_json}" }
145
152
  if @respond_with_empty_img
146
- return ["200 OK", {'Content-type'=>'image/gif; charset=utf-8'}, EMPTY_GIF_IMAGE]
153
+ return ["200 OK", {'Content-Type'=>'image/gif; charset=utf-8'}, EMPTY_GIF_IMAGE]
147
154
  else
148
- return ["200 OK", {'Content-type'=>'text/plain'}, ""]
155
+ return ["200 OK", {'Content-Type'=>'text/plain'}, ""]
149
156
  end
150
157
  end
151
158
 
@@ -162,20 +169,20 @@ module Fluent
162
169
  end
163
170
  end
164
171
  time = if param_time = params['time']
165
- param_time = param_time.to_i
166
- param_time.zero? ? Engine.now : param_time
172
+ param_time = param_time.to_f
173
+ param_time.zero? ? Fluent::Engine.now : @float_time_parser.parse(param_time)
167
174
  else
168
- record_time.nil? ? Engine.now : record_time
175
+ record_time.nil? ? Fluent::Engine.now : record_time
169
176
  end
170
177
  rescue
171
- return ["400 Bad Request", {'Content-type'=>'text/plain'}, "400 Bad Request\n#{$!}\n"]
178
+ return ["400 Bad Request", {'Content-Type'=>'text/plain'}, "400 Bad Request\n#{$!}\n"]
172
179
  end
173
180
 
174
181
  # TODO server error
175
182
  begin
176
183
  # Support batched requests
177
184
  if record.is_a?(Array)
178
- mes = MultiEventStream.new
185
+ mes = Fluent::MultiEventStream.new
179
186
  record.each do |single_record|
180
187
  if @add_http_headers
181
188
  params.each_pair { |k,v|
@@ -187,7 +194,18 @@ module Fluent
187
194
  if @add_remote_addr
188
195
  single_record['REMOTE_ADDR'] = params['REMOTE_ADDR']
189
196
  end
190
- single_time = single_record.delete("time") || time
197
+
198
+ if defined? @parser
199
+ single_time = @parser.parse_time(single_record)
200
+ single_time, single_record = @parser.convert_values(single_time, single_record)
201
+ else
202
+ single_time = if t = single_record.delete(@parser_time_key)
203
+ Fluent::EventTime.from_time(Time.at(t))
204
+ else
205
+ time
206
+ end
207
+ end
208
+
191
209
  mes.add(single_time, single_record)
192
210
  end
193
211
  router.emit_stream(tag, mes)
@@ -195,35 +213,52 @@ module Fluent
195
213
  router.emit(tag, time, record)
196
214
  end
197
215
  rescue
198
- return ["500 Internal Server Error", {'Content-type'=>'text/plain'}, "500 Internal Server Error\n#{$!}\n"]
216
+ return ["500 Internal Server Error", {'Content-Type'=>'text/plain'}, "500 Internal Server Error\n#{$!}\n"]
199
217
  end
200
218
 
201
219
  if @respond_with_empty_img
202
- return ["200 OK", {'Content-type'=>'image/gif; charset=utf-8'}, EMPTY_GIF_IMAGE]
220
+ return ["200 OK", {'Content-Type'=>'image/gif; charset=utf-8'}, EMPTY_GIF_IMAGE]
203
221
  else
204
- return ["200 OK", {'Content-type'=>'text/plain'}, ""]
222
+ return ["200 OK", {'Content-Type'=>'text/plain'}, ""]
205
223
  end
206
224
  end
207
225
 
208
226
  private
209
227
 
210
- def parse_params_default(params)
211
- record = if msgpack = params['msgpack']
212
- Engine.msgpack_factory.unpacker.feed(msgpack).read
213
- elsif js = params['json']
214
- JSON.parse(js)
215
- else
216
- raise "'json' or 'msgpack' parameter is required"
217
- end
218
- return nil, record
228
+ def on_server_connect(conn)
229
+ handler = Handler.new(conn, @km, method(:on_request), @body_size_limit, @format_name, log, @cors_allow_origins)
230
+
231
+ conn.on(:data) do |data|
232
+ handler.on_read(data)
233
+ end
234
+
235
+ conn.on(:write_complete) do |_|
236
+ handler.on_write_complete
237
+ end
238
+
239
+ conn.on(:close) do |_|
240
+ handler.on_close
241
+ end
219
242
  end
220
243
 
221
- EVENT_RECORD_PARAMETER = '_event_record'
244
+ def parse_params_default(params)
245
+ if msgpack = params['msgpack']
246
+ @parser_msgpack.parse(msgpack) do |_time, record|
247
+ return nil, record
248
+ end
249
+ elsif js = params['json']
250
+ @parser_json.parse(js) do |_time, record|
251
+ return nil, record
252
+ end
253
+ else
254
+ raise "'json' or 'msgpack' parameter is required"
255
+ end
256
+ end
222
257
 
223
258
  def parse_params_with_parser(params)
224
259
  if content = params[EVENT_RECORD_PARAMETER]
225
260
  @parser.parse(content) { |time, record|
226
- raise "Received event is not #{@format}: #{content}" if record.nil?
261
+ raise "Received event is not #{@format_name}: #{content}" if record.nil?
227
262
  return time, record
228
263
  }
229
264
  else
@@ -231,20 +266,23 @@ module Fluent
231
266
  end
232
267
  end
233
268
 
234
- class Handler < Coolio::Socket
235
- def initialize(io, km, callback, body_size_limit, format, log, cors_allow_origins)
236
- super(io)
269
+ class Handler
270
+ attr_reader :content_type
271
+
272
+ def initialize(io, km, callback, body_size_limit, format_name, log, cors_allow_origins)
273
+ @io = io
237
274
  @km = km
238
275
  @callback = callback
239
276
  @body_size_limit = body_size_limit
240
277
  @next_close = false
241
- @format = format
278
+ @format_name = format_name
242
279
  @log = log
243
280
  @cors_allow_origins = cors_allow_origins
244
281
  @idle = 0
245
282
  @km.add(self)
246
283
 
247
- @remote_port, @remote_addr = *Socket.unpack_sockaddr_in(io.getpeername) rescue nil
284
+ @remote_port, @remote_addr = io.remote_port, io.remote_addr
285
+ @parser = Http::Parser.new(self)
248
286
  end
249
287
 
250
288
  def step_idle
@@ -255,17 +293,13 @@ module Fluent
255
293
  @km.delete(self)
256
294
  end
257
295
 
258
- def on_connect
259
- @parser = Http::Parser.new(self)
260
- end
261
-
262
296
  def on_read(data)
263
297
  @idle = 0
264
298
  @parser << data
265
299
  rescue
266
300
  @log.warn "unexpected error", error: $!.to_s
267
301
  @log.warn_backtrace
268
- close
302
+ @io.close
269
303
  end
270
304
 
271
305
  def on_message_begin
@@ -283,6 +317,7 @@ module Fluent
283
317
  end
284
318
  @env = {}
285
319
  @content_type = ""
320
+ @content_encoding = ""
286
321
  headers.each_pair {|k,v|
287
322
  @env["HTTP_#{k.gsub('-','_').upcase}"] = v
288
323
  case k
@@ -292,6 +327,8 @@ module Fluent
292
327
  size = v.to_i
293
328
  when /Content-Type/i
294
329
  @content_type = v
330
+ when /Content-Encoding/i
331
+ @content_encoding = v
295
332
  when /Connection/i
296
333
  if v =~ /close/i
297
334
  @keep_alive = false
@@ -304,6 +341,10 @@ module Fluent
304
341
  # For multiple X-Forwarded-For headers. Use first header value.
305
342
  v = v.first if v.is_a?(Array)
306
343
  @remote_addr = v.split(",").first
344
+ when /Access-Control-Request-Method/i
345
+ @access_control_request_method = v
346
+ when /Access-Control-Request-Headers/i
347
+ @access_control_request_headers = v
307
348
  end
308
349
  }
309
350
  if expect
@@ -329,26 +370,76 @@ module Fluent
329
370
  @body << chunk
330
371
  end
331
372
 
373
+ # Web browsers can send an OPTIONS request before performing POST
374
+ # to check if cross-origin requests are supported.
375
+ def handle_options_request
376
+ # Is CORS enabled in the first place?
377
+ if @cors_allow_origins.nil?
378
+ return send_response_and_close("403 Forbidden", {}, "")
379
+ end
380
+
381
+ # in_http does not support HTTP methods except POST
382
+ if @access_control_request_method != 'POST'
383
+ return send_response_and_close("403 Forbidden", {}, "")
384
+ end
385
+
386
+ header = {
387
+ "Access-Control-Allow-Methods" => "POST",
388
+ "Access-Control-Allow-Headers" => @access_control_request_headers || "",
389
+ }
390
+
391
+ # Check the origin and send back a CORS response
392
+ if @cors_allow_origins.include?('*')
393
+ header["Access-Control-Allow-Origin"] = "*"
394
+ send_response_and_close("200 OK", header, "")
395
+ elsif include_cors_allow_origin
396
+ header["Access-Control-Allow-Origin"] = @origin
397
+ send_response_and_close("200 OK", header, "")
398
+ else
399
+ send_response_and_close("403 Forbidden", {}, "")
400
+ end
401
+ end
402
+
332
403
  def on_message_complete
333
404
  return if closing?
334
405
 
406
+ if @parser.http_method == 'OPTIONS'
407
+ return handle_options_request()
408
+ end
409
+
335
410
  # CORS check
336
411
  # ==========
337
412
  # For every incoming request, we check if we have some CORS
338
413
  # restrictions and white listed origins through @cors_allow_origins.
339
414
  unless @cors_allow_origins.nil?
340
- unless @cors_allow_origins.include?(@origin)
415
+ unless @cors_allow_origins.include?('*') or include_cors_allow_origin
341
416
  send_response_and_close("403 Forbidden", {'Connection' => 'close'}, "")
342
417
  return
343
418
  end
344
419
  end
345
420
 
421
+ # Content Encoding
422
+ # =================
423
+ # Decode payload according to the "Content-Encoding" header.
424
+ # For now, we only support 'gzip' and 'deflate'.
425
+ begin
426
+ if @content_encoding == 'gzip'
427
+ @body = Zlib::GzipReader.new(StringIO.new(@body)).read
428
+ elsif @content_encoding == 'deflate'
429
+ @body = Zlib::Inflate.inflate(@body)
430
+ end
431
+ rescue
432
+ @log.warn 'fails to decode payload', error: $!.to_s
433
+ send_response_and_close("400 Bad Request", {}, "")
434
+ return
435
+ end
436
+
346
437
  @env['REMOTE_ADDR'] = @remote_addr if @remote_addr
347
438
 
348
439
  uri = URI.parse(@parser.request_url)
349
440
  params = WEBrick::HTTPUtils.parse_query(uri.query)
350
441
 
351
- if @format != 'default'
442
+ if @format_name != 'default'
352
443
  params[EVENT_RECORD_PARAMETER] = @body
353
444
  elsif @content_type =~ /^application\/x-www-form-urlencoded/
354
445
  params.update WEBrick::HTTPUtils.parse_query(@body)
@@ -368,7 +459,14 @@ module Fluent
368
459
  code, header, body = *@callback.call(path_info, params)
369
460
  body = body.to_s
370
461
 
371
- header['Access-Control-Allow-Origin'] = @origin if !@cors_allow_origins.nil? && @cors_allow_origins.include?(@origin)
462
+ unless @cors_allow_origins.nil?
463
+ if @cors_allow_origins.include?('*')
464
+ header['Access-Control-Allow-Origin'] = '*'
465
+ elsif include_cors_allow_origin
466
+ header['Access-Control-Allow-Origin'] = @origin
467
+ end
468
+ end
469
+
372
470
  if @keep_alive
373
471
  header['Connection'] = 'Keep-Alive'
374
472
  send_response(code, header, body)
@@ -377,8 +475,12 @@ module Fluent
377
475
  end
378
476
  end
379
477
 
478
+ def close
479
+ @io.close
480
+ end
481
+
380
482
  def on_write_complete
381
- close if @next_close
483
+ @io.close if @next_close
382
484
  end
383
485
 
384
486
  def send_response_and_close(code, header, body)
@@ -391,17 +493,17 @@ module Fluent
391
493
  end
392
494
 
393
495
  def send_response(code, header, body)
394
- header['Content-length'] ||= body.bytesize
395
- header['Content-type'] ||= 'text/plain'
496
+ header['Content-Length'] ||= body.bytesize
497
+ header['Content-Type'] ||= 'text/plain'
396
498
 
397
499
  data = %[HTTP/1.1 #{code}\r\n]
398
500
  header.each_pair {|k,v|
399
501
  data << "#{k}: #{v}\r\n"
400
502
  }
401
503
  data << "\r\n"
402
- write data
504
+ @io.write(data)
403
505
 
404
- write body
506
+ @io.write(body)
405
507
  end
406
508
 
407
509
  def send_response_nobody(code, header)
@@ -410,7 +512,18 @@ module Fluent
410
512
  data << "#{k}: #{v}\r\n"
411
513
  }
412
514
  data << "\r\n"
413
- write data
515
+ @io.write(data)
516
+ end
517
+
518
+ def include_cors_allow_origin
519
+ if @cors_allow_origins.include?(@origin)
520
+ return true
521
+ end
522
+ filtered_cors_allow_origins = @cors_allow_origins.select {|origin| origin != ""}
523
+ return filtered_cors_allow_origins.find do |origin|
524
+ (start_str,end_str) = origin.split("*",2)
525
+ @origin.start_with?(start_str) and @origin.end_with?(end_str)
526
+ end != nil
414
527
  end
415
528
  end
416
529
  end