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
@@ -13,142 +13,143 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
-
17
- require 'yajl'
18
-
19
- require 'fluent/output'
16
+ require 'fluent/plugin/output'
20
17
  require 'fluent/env'
21
- require 'fluent/time'
22
- require 'fluent/timezone'
23
- require 'fluent/plugin/exec_util'
24
18
  require 'fluent/config/error'
25
19
 
26
- module Fluent
27
- class ExecFilterOutput < BufferedOutput
28
- Plugin.register_output('exec_filter', self)
20
+ require 'yajl'
29
21
 
30
- def initialize
31
- super
32
- require 'fluent/timezone'
33
- end
22
+ module Fluent::Plugin
23
+ class ExecFilterOutput < Output
24
+ Fluent::Plugin.register_output('exec_filter', self)
25
+
26
+ helpers :compat_parameters, :inject, :formatter, :parser, :extract, :child_process, :event_emitter
34
27
 
35
28
  desc 'The command (program) to execute.'
36
29
  config_param :command, :string
37
30
 
38
- config_param :remove_prefix, :string, default: nil
39
- config_param :add_prefix, :string, default: nil
31
+ config_param :remove_prefix, :string, default: nil, deprecated: "use @label instead for event routing"
32
+ config_param :add_prefix, :string, default: nil, deprecated: "use @label instead for event routing"
33
+
34
+ config_section :inject do
35
+ config_set_default :time_type, :unixtime
36
+ end
40
37
 
41
- desc "The format used to map the incoming event to the program input.(#{ExecUtil::SUPPORTED_FORMAT.keys.join(',')})"
42
- config_param :in_format, default: :tsv do |val|
43
- f = ExecUtil::SUPPORTED_FORMAT[val]
44
- raise ConfigError, "Unsupported in_format '#{val}'" unless f
45
- f
38
+ config_section :format do
39
+ config_set_default :@type, 'tsv'
40
+ config_set_default :localtime, true
46
41
  end
47
- desc 'Specify comma-separated values for tsv format.'
48
- config_param :in_keys, default: [] do |val|
49
- val.split(',')
42
+
43
+ config_section :parse do
44
+ config_set_default :@type, 'tsv'
45
+ config_set_default :time_key, nil
46
+ config_set_default :time_format, nil
47
+ config_set_default :localtime, true
48
+ config_set_default :estimate_current_event, false
50
49
  end
51
- desc 'The name of the key to use as the event tag.'
52
- config_param :in_tag_key, default: nil
53
- desc 'The name of the key to use as the event time.'
54
- config_param :in_time_key, default: nil
55
- desc 'The format for event time used when the in_time_key parameter is specified.(Defauls is UNIX time)'
56
- config_param :in_time_format, default: nil
57
-
58
- desc "The format used to process the program output.(#{ExecUtil::SUPPORTED_FORMAT.keys.join(',')})"
59
- config_param :out_format, default: :tsv do |val|
60
- f = ExecUtil::SUPPORTED_FORMAT[val]
61
- raise ConfigError, "Unsupported out_format '#{val}'" unless f
62
- f
50
+
51
+ config_section :extract do
52
+ config_set_default :time_type, :float
63
53
  end
64
- desc 'Specify comma-separated values for tsv format.'
65
- config_param :out_keys, default: [] do |val| # for tsv format
66
- val.split(',')
54
+
55
+ config_section :buffer do
56
+ config_set_default :flush_mode, :interval
57
+ config_set_default :flush_interval, 1
67
58
  end
68
- desc 'The name of the key to use as the event tag.'
69
- config_param :out_tag_key, default: nil
70
- desc 'The name of the key to use as the event time.'
71
- config_param :out_time_key, default: nil
72
- desc 'The format for event time used when the in_time_key parameter is specified.(Defauls is UNIX time)'
73
- config_param :out_time_format, default: nil
74
59
 
75
60
  config_param :tag, :string, default: nil
76
61
 
77
- config_param :time_key, :string, default: nil
78
- config_param :time_format, :string, default: nil
62
+ config_param :tag_key, :string, default: nil, deprecated: "use 'tag_key' in <inject>/<extract> instead"
63
+ config_param :time_key, :string, default: nil, deprecated: "use 'time_key' in <inject>/<extract> instead"
64
+ config_param :time_format, :string, default: nil, deprecated: "use 'time_format' in <inject>/<extract> instead"
65
+
66
+ desc 'The default block size to read if parser requires partial read.'
67
+ config_param :read_block_size, :size, default: 10240 # 10k
79
68
 
80
- desc 'If true, use localtime with in_time_format.'
81
- config_param :localtime, :bool, default: true
82
- desc 'If true, use timezone with in_time_format.'
83
- config_param :timezone, :string, default: nil
84
69
  desc 'The number of spawned process for command.'
85
70
  config_param :num_children, :integer, default: 1
86
71
 
87
- desc 'Respawn command when command exit.'
72
+ desc 'Respawn command when command exit. ["none", "inf" or positive integer for times to respawn (default: none)]'
88
73
  # nil, 'none' or 0: no respawn, 'inf' or -1: infinite times, positive integer: try to respawn specified times only
89
74
  config_param :child_respawn, :string, default: nil
90
75
 
91
76
  # 0: output logs for all of messages to emit
92
77
  config_param :suppress_error_log_interval, :time, default: 0
93
78
 
94
- config_set_default :flush_interval, 1
95
-
96
- def configure(conf)
97
- if tag_key = conf['tag_key']
98
- # TODO obsoleted?
99
- @in_tag_key = tag_key
100
- @out_tag_key = tag_key
101
- end
102
-
103
- if time_key = conf['time_key']
104
- # TODO obsoleted?
105
- @in_time_key = time_key
106
- @out_time_key = time_key
79
+ attr_reader :formatter, :parser # for tests
80
+
81
+ KEYS_FOR_IN_AND_OUT = {
82
+ 'tag_key' => ['in_tag_key', 'out_tag_key'],
83
+ 'time_key' => ['in_time_key', 'out_time_key'],
84
+ 'time_format' => ['in_time_format', 'out_time_format'],
85
+ }
86
+ COMPAT_INJECT_PARAMS = {
87
+ 'in_tag_key' => 'tag_key',
88
+ 'in_time_key' => 'time_key',
89
+ 'in_time_format' => 'time_format',
90
+ }
91
+ COMPAT_FORMAT_PARAMS = {
92
+ 'in_format' => '@type',
93
+ 'in_keys' => 'keys',
94
+ }
95
+ COMPAT_PARSE_PARAMS = {
96
+ 'out_format' => '@type',
97
+ 'out_keys' => 'keys',
98
+ 'out_stream_buffer_size' => 'stream_buffer_size',
99
+ }
100
+ COMPAT_EXTRACT_PARAMS = {
101
+ 'out_tag_key' => 'tag_key',
102
+ 'out_time_key' => 'time_key',
103
+ 'out_time_format' => 'time_format',
104
+ }
105
+
106
+ def exec_filter_compat_parameters_copy_to_subsection!(conf, subsection_name, params)
107
+ return unless conf.elements(subsection_name).empty?
108
+ return unless params.keys.any?{|k| conf.has_key?(k) }
109
+ hash = {}
110
+ params.each_pair do |compat, current|
111
+ hash[current] = conf[compat] if conf.has_key?(compat)
107
112
  end
113
+ conf.elements << Fluent::Config::Element.new(subsection_name, '', hash, [])
114
+ end
108
115
 
109
- if time_format = conf['time_format']
110
- # TODO obsoleted?
111
- @in_time_format = time_format
112
- @out_time_format = time_format
116
+ def exec_filter_compat_parameters_convert!(conf)
117
+ KEYS_FOR_IN_AND_OUT.each_pair do |inout, keys|
118
+ if conf.has_key?(inout)
119
+ keys.each do |k|
120
+ conf[k] = conf[inout]
121
+ end
122
+ end
113
123
  end
124
+ exec_filter_compat_parameters_copy_to_subsection!(conf, 'inject', COMPAT_INJECT_PARAMS)
125
+ exec_filter_compat_parameters_copy_to_subsection!(conf, 'format', COMPAT_FORMAT_PARAMS)
126
+ exec_filter_compat_parameters_copy_to_subsection!(conf, 'parse', COMPAT_PARSE_PARAMS)
127
+ exec_filter_compat_parameters_copy_to_subsection!(conf, 'extract', COMPAT_EXTRACT_PARAMS)
128
+ end
114
129
 
115
- super
130
+ def configure(conf)
131
+ exec_filter_compat_parameters_convert!(conf)
132
+ compat_parameters_convert(conf, :buffer)
116
133
 
117
- if localtime = conf['localtime']
118
- @localtime = true
119
- elsif utc = conf['utc']
120
- @localtime = false
134
+ if inject_section = conf.elements('inject').first
135
+ if inject_section.has_key?('time_format')
136
+ inject_section['time_type'] ||= 'string'
137
+ end
121
138
  end
122
-
123
- if conf['timezone']
124
- @timezone = conf['timezone']
125
- Fluent::Timezone.validate!(@timezone)
139
+ if extract_section = conf.elements('extract').first
140
+ if extract_section.has_key?('time_format')
141
+ extract_section['time_type'] ||= 'string'
142
+ end
126
143
  end
127
144
 
128
- if !@tag && !@out_tag_key
129
- raise ConfigError, "'tag' or 'out_tag_key' option is required on exec_filter output"
130
- end
145
+ super
131
146
 
132
- if @in_time_key
133
- if f = @in_time_format
134
- tf = TimeFormatter.new(f, @localtime, @timezone)
135
- @time_format_proc = tf.method(:format)
136
- else
137
- @time_format_proc = Proc.new {|time| time.to_s }
138
- end
139
- elsif @in_time_format
140
- log.warn "in_time_format effects nothing when in_time_key is not specified: #{conf}"
147
+ if !@tag && (!@extract_config || !@extract_config.tag_key)
148
+ raise Fluent::ConfigError, "'tag' or '<extract> tag_key </extract>' option is required on exec_filter output"
141
149
  end
142
150
 
143
- if @out_time_key
144
- if f = @out_time_format
145
- @time_parse_proc = Proc.new {|str| Time.strptime(str, f).to_i }
146
- else
147
- @time_parse_proc = Proc.new {|str| str.to_i }
148
- end
149
- elsif @out_time_format
150
- log.warn "out_time_format effects nothing when out_time_key is not specified: #{conf}"
151
- end
151
+ @formatter = formatter_create
152
+ @parser = parser_create
152
153
 
153
154
  if @remove_prefix
154
155
  @removed_prefix_string = @remove_prefix + '.'
@@ -158,30 +159,6 @@ module Fluent
158
159
  @added_prefix_string = @add_prefix + '.'
159
160
  end
160
161
 
161
- case @in_format
162
- when :tsv
163
- if @in_keys.empty?
164
- raise ConfigError, "in_keys option is required on exec_filter output for tsv in_format"
165
- end
166
- @formatter = ExecUtil::TSVFormatter.new(@in_keys)
167
- when :json
168
- @formatter = ExecUtil::JSONFormatter.new
169
- when :msgpack
170
- @formatter = ExecUtil::MessagePackFormatter.new
171
- end
172
-
173
- case @out_format
174
- when :tsv
175
- if @out_keys.empty?
176
- raise ConfigError, "out_keys option is required on exec_filter output for tsv in_format"
177
- end
178
- @parser = ExecUtil::TSVParser.new(@out_keys, method(:on_message))
179
- when :json
180
- @parser = ExecUtil::JSONParser.new(method(:on_message))
181
- when :msgpack
182
- @parser = ExecUtil::MessagePackParser.new(method(:on_message))
183
- end
184
-
185
162
  @respawns = if @child_respawn.nil? or @child_respawn == 'none' or @child_respawn == '0'
186
163
  0
187
164
  elsif @child_respawn == 'inf' or @child_respawn == '-1'
@@ -196,190 +173,146 @@ module Fluent
196
173
  @next_log_time = Time.now.to_i
197
174
  end
198
175
 
176
+ def multi_workers_ready?
177
+ true
178
+ end
179
+
180
+ ExecutedProcess = Struct.new(:mutex, :pid, :respawns, :readio, :writeio)
181
+
199
182
  def start
200
183
  super
201
184
 
185
+ @children_mutex = Mutex.new
202
186
  @children = []
203
187
  @rr = 0
204
- begin
205
- @num_children.times do
206
- c = ChildProcess.new(@parser, @respawns, log)
207
- c.start(@command)
208
- @children << c
209
- end
210
- rescue
211
- shutdown
212
- raise
213
- end
214
- end
215
-
216
- def before_shutdown
217
- super
218
- log.debug "out_exec_filter#before_shutdown called"
219
- @children.each {|c|
220
- c.finished = true
221
- }
222
- sleep 0.5 # TODO wait time before killing child process
223
- end
224
188
 
225
- def shutdown
226
- super
227
-
228
- @children.reject! {|c|
229
- c.shutdown
230
- true
189
+ exit_callback = ->(status){
190
+ c = @children.select{|child| child.pid == status.pid }.first
191
+ if c
192
+ unless self.stopped?
193
+ log.warn "child process exits with error code", code: status.to_i, status: status.exitstatus, signal: status.termsig
194
+ end
195
+ c.mutex.synchronize do
196
+ (c.writeio && c.writeio.close) rescue nil
197
+ (c.readio && c.readio.close) rescue nil
198
+ c.pid = c.readio = c.writeio = nil
199
+ end
200
+ end
231
201
  }
232
- end
233
-
234
- def format_stream(tag, es)
235
- if @remove_prefix
236
- if (tag[0, @removed_length] == @removed_prefix_string and tag.length > @removed_length) or tag == @removed_prefix
237
- tag = tag[@removed_length..-1] || ''
202
+ child_process_callback = ->(index, readio, writeio){
203
+ pid = child_process_id
204
+ c = @children[index]
205
+ writeio.sync = true
206
+ c.mutex.synchronize do
207
+ c.pid = pid
208
+ c.respawns = @respawns
209
+ c.readio = readio
210
+ c.writeio = writeio
238
211
  end
239
- end
240
212
 
241
- out = ''
242
-
243
- es.each {|time,record|
244
- if @in_time_key
245
- record[@in_time_key] = @time_format_proc.call(time)
246
- end
247
- if @in_tag_key
248
- record[@in_tag_key] = tag
213
+ run(readio)
214
+ }
215
+ execute_child_process = ->(index){
216
+ child_process_execute("out_exec_filter_child#{index}".to_sym, @command, on_exit_callback: exit_callback) do |readio, writeio|
217
+ child_process_callback.call(index, readio, writeio)
249
218
  end
250
- @formatter.call(record, out)
251
219
  }
252
220
 
253
- out
254
- end
255
-
256
- def write(chunk)
257
- r = @rr = (@rr + 1) % @children.length
258
- @children[r].write chunk
259
- end
260
-
261
- class ChildProcess
262
- attr_accessor :finished
263
-
264
- def initialize(parser, respawns=0, log = $log)
265
- @pid = nil
266
- @thread = nil
267
- @parser = parser
268
- @respawns = respawns
269
- @mutex = Mutex.new
270
- @finished = nil
271
- @log = log
272
- end
273
-
274
- def start(command)
275
- @command = command
276
- @mutex.synchronize do
277
- @io = IO.popen(command, "r+")
278
- @pid = @io.pid
279
- @io.sync = true
280
- @thread = Thread.new(&method(:run))
221
+ @children_mutex.synchronize do
222
+ @num_children.times do |i|
223
+ @children << ExecutedProcess.new(Mutex.new, nil, 0, nil, nil)
224
+ execute_child_process.call(i)
281
225
  end
282
- @finished = false
283
226
  end
284
227
 
285
- def kill_child(join_wait)
286
- begin
287
- Process.kill(:TERM, @pid)
288
- rescue #Errno::ECHILD, Errno::ESRCH, Errno::EPERM
289
- # Errno::ESRCH 'No such process', ignore
290
- # child process killed by signal chained from fluentd process
291
- end
292
- if @thread.join(join_wait)
293
- # @thread successfully shutdown
294
- return
295
- end
296
- begin
297
- Process.kill(:KILL, @pid)
298
- rescue #Errno::ECHILD, Errno::ESRCH, Errno::EPERM
299
- # ignore if successfully killed by :TERM
228
+ if @respawns != 0
229
+ thread_create(:out_exec_filter_respawn_monitor) do
230
+ while thread_current_running?
231
+ @children.each_with_index do |c, i|
232
+ if c.mutex && c.mutex.synchronize{ c.pid.nil? && c.respawns != 0 }
233
+ respawns = c.mutex.synchronize do
234
+ c.respawns -= 1 if c.respawns > 0
235
+ c.respawns
236
+ end
237
+ log.info "respawning child process", num: i, respawn_counter: respawns
238
+ execute_child_process.call(i)
239
+ end
240
+ end
241
+ sleep 0.2
242
+ end
300
243
  end
301
- @thread.join
302
244
  end
245
+ end
303
246
 
304
- def shutdown
305
- @finished = true
306
- @mutex.synchronize do
307
- kill_child(60) # TODO wait time
308
- end
309
- end
247
+ def terminate
248
+ @children = []
249
+ super
250
+ end
310
251
 
311
- def write(chunk)
312
- begin
313
- chunk.write_to(@io)
314
- rescue Errno::EPIPE => e
315
- # Broken pipe (child process unexpectedly exited)
316
- @log.warn "exec_filter Broken pipe, child process maybe exited.", command: @command
317
- if try_respawn
318
- retry # retry chunk#write_to with child respawned
319
- else
320
- raise e # to retry #write with other ChildProcess instance (when num_children > 1)
321
- end
252
+ def tag_remove_prefix(tag)
253
+ if @remove_prefix
254
+ if (tag[0, @removed_length] == @removed_prefix_string and tag.length > @removed_length) or tag == @removed_prefix_string
255
+ tag = tag[@removed_length..-1] || ''
322
256
  end
323
257
  end
258
+ tag
259
+ end
324
260
 
325
- def try_respawn
326
- return false if @respawns == 0
327
- @mutex.synchronize do
328
- return false if @respawns == 0
329
-
330
- kill_child(5) # TODO wait time
331
-
332
- @io = IO.popen(@command, "r+")
333
- @pid = @io.pid
334
- @io.sync = true
335
- @thread = Thread.new(&method(:run))
261
+ NEWLINE = "\n"
336
262
 
337
- @respawns -= 1 if @respawns > 0
338
- end
339
- @log.warn "exec_filter child process successfully respawned.", command: @command, respawns: @respawns
340
- true
263
+ def format(tag, time, record)
264
+ tag = tag_remove_prefix(tag)
265
+ record = inject_values_to_record(tag, time, record)
266
+ if @formatter.formatter_type == :text_per_line
267
+ @formatter.format(tag, time, record).chomp + NEWLINE
268
+ else
269
+ @formatter.format(tag, time, record)
341
270
  end
271
+ end
342
272
 
343
- def run
344
- @parser.call(@io)
345
- rescue
346
- @log.error "exec_filter thread unexpectedly failed with an error.", command: @command, error: $!.to_s
347
- @log.warn_backtrace $!.backtrace
348
- ensure
349
- pid, stat = Process.waitpid2(@pid)
350
- unless @finished
351
- @log.error "exec_filter process unexpectedly exited.", command: @command, ecode: stat.to_i
352
- unless @respawns == 0
353
- @log.warn "exec_filter child process will respawn for next input data (respawns #{@respawns})."
354
- end
273
+ def write(chunk)
274
+ try_times = 0
275
+ while true
276
+ r = @rr = (@rr + 1) % @children.length
277
+ if @children[r].pid && writeio = @children[r].writeio
278
+ chunk.write_to(writeio)
279
+ break
355
280
  end
281
+ try_times += 1
282
+ raise "no healthy child processes exist" if try_times >= @children.length
356
283
  end
357
284
  end
358
285
 
359
- def on_message(record)
360
- if val = record.delete(@out_time_key)
361
- time = @time_parse_proc.call(val)
362
- else
363
- time = Engine.now
364
- end
365
-
366
- if val = record.delete(@out_tag_key)
367
- tag = if @add_prefix
368
- @added_prefix_string + val
369
- else
370
- val
371
- end
286
+ def run(io)
287
+ case
288
+ when @parser.implement?(:parse_io)
289
+ @parser.parse_io(io, &method(:on_record))
290
+ when @parser.implement?(:parse_partial_data)
291
+ until io.eof?
292
+ @parser.parse_partial_data(io.readpartial(@read_block_size), &method(:on_record))
293
+ end
294
+ when @parser.parser_type == :text_per_line
295
+ io.each_line do |line|
296
+ @parser.parse(line.chomp, &method(:on_record))
297
+ end
372
298
  else
373
- tag = @tag
299
+ @parser.parse(io.read, &method(:on_record))
374
300
  end
301
+ end
375
302
 
303
+ def on_record(time, record)
304
+ tag = extract_tag_from_record(record)
305
+ tag = @added_prefix_string + tag if tag && @add_prefix
306
+ tag ||= @tag
307
+ time ||= extract_time_from_record(record) || Fluent::EventTime.now
376
308
  router.emit(tag, time, record)
377
- rescue
309
+ rescue => e
378
310
  if @suppress_error_log_interval == 0 || Time.now.to_i > @next_log_time
379
- log.error "exec_filter failed to emit", error: $!.to_s, error_class: $!.class.to_s, record: Yajl.dump(record)
380
- log.warn_backtrace $!.backtrace
311
+ log.error "exec_filter failed to emit", record: Yajl.dump(record), error: e
312
+ log.error_backtrace e.backtrace
381
313
  @next_log_time = Time.now.to_i + @suppress_error_log_interval
382
314
  end
315
+ router.emit_error_event(tag, time, record, e) if tag && time && record
383
316
  end
384
317
  end
385
318
  end