fluentd 0.14.4-x86-mingw32

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 (328) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_TEMPLATE.md +6 -0
  3. data/.gitignore +26 -0
  4. data/.travis.yml +45 -0
  5. data/AUTHORS +2 -0
  6. data/CONTRIBUTING.md +35 -0
  7. data/COPYING +14 -0
  8. data/ChangeLog +276 -0
  9. data/Gemfile +9 -0
  10. data/README.md +51 -0
  11. data/Rakefile +53 -0
  12. data/Vagrantfile +17 -0
  13. data/appveyor.yml +41 -0
  14. data/bin/fluent-debug +5 -0
  15. data/example/copy_roundrobin.conf +39 -0
  16. data/example/filter_stdout.conf +22 -0
  17. data/example/in_forward.conf +11 -0
  18. data/example/in_http.conf +14 -0
  19. data/example/in_out_forward.conf +17 -0
  20. data/example/in_syslog.conf +15 -0
  21. data/example/in_tail.conf +14 -0
  22. data/example/in_tcp.conf +13 -0
  23. data/example/in_udp.conf +13 -0
  24. data/example/multi_filters.conf +61 -0
  25. data/example/out_buffered_null.conf +32 -0
  26. data/example/out_copy.conf +20 -0
  27. data/example/out_file.conf +13 -0
  28. data/example/out_forward.conf +35 -0
  29. data/example/out_forward_buf_file.conf +23 -0
  30. data/example/v0_12_filter.conf +78 -0
  31. data/example/v1_literal_example.conf +36 -0
  32. data/fluent.conf +139 -0
  33. data/fluentd.gemspec +51 -0
  34. data/lib/fluent/agent.rb +194 -0
  35. data/lib/fluent/command/bundler_injection.rb +45 -0
  36. data/lib/fluent/command/cat.rb +319 -0
  37. data/lib/fluent/command/debug.rb +102 -0
  38. data/lib/fluent/command/fluentd.rb +273 -0
  39. data/lib/fluent/compat/call_super_mixin.rb +67 -0
  40. data/lib/fluent/compat/exec_util.rb +129 -0
  41. data/lib/fluent/compat/file_util.rb +54 -0
  42. data/lib/fluent/compat/filter.rb +68 -0
  43. data/lib/fluent/compat/formatter.rb +111 -0
  44. data/lib/fluent/compat/formatter_utils.rb +85 -0
  45. data/lib/fluent/compat/handle_tag_and_time_mixin.rb +62 -0
  46. data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
  47. data/lib/fluent/compat/input.rb +49 -0
  48. data/lib/fluent/compat/output.rb +677 -0
  49. data/lib/fluent/compat/output_chain.rb +60 -0
  50. data/lib/fluent/compat/parser.rb +180 -0
  51. data/lib/fluent/compat/parser_utils.rb +40 -0
  52. data/lib/fluent/compat/propagate_default.rb +62 -0
  53. data/lib/fluent/compat/record_filter_mixin.rb +34 -0
  54. data/lib/fluent/compat/set_tag_key_mixin.rb +50 -0
  55. data/lib/fluent/compat/set_time_key_mixin.rb +69 -0
  56. data/lib/fluent/compat/socket_util.rb +165 -0
  57. data/lib/fluent/compat/string_util.rb +34 -0
  58. data/lib/fluent/compat/structured_format_mixin.rb +26 -0
  59. data/lib/fluent/compat/type_converter.rb +90 -0
  60. data/lib/fluent/config.rb +56 -0
  61. data/lib/fluent/config/basic_parser.rb +123 -0
  62. data/lib/fluent/config/configure_proxy.rb +366 -0
  63. data/lib/fluent/config/dsl.rb +149 -0
  64. data/lib/fluent/config/element.rb +218 -0
  65. data/lib/fluent/config/error.rb +26 -0
  66. data/lib/fluent/config/literal_parser.rb +251 -0
  67. data/lib/fluent/config/parser.rb +107 -0
  68. data/lib/fluent/config/section.rb +212 -0
  69. data/lib/fluent/config/types.rb +136 -0
  70. data/lib/fluent/config/v1_parser.rb +190 -0
  71. data/lib/fluent/configurable.rb +176 -0
  72. data/lib/fluent/daemon.rb +15 -0
  73. data/lib/fluent/engine.rb +220 -0
  74. data/lib/fluent/env.rb +27 -0
  75. data/lib/fluent/event.rb +287 -0
  76. data/lib/fluent/event_router.rb +259 -0
  77. data/lib/fluent/filter.rb +21 -0
  78. data/lib/fluent/formatter.rb +23 -0
  79. data/lib/fluent/input.rb +21 -0
  80. data/lib/fluent/label.rb +38 -0
  81. data/lib/fluent/load.rb +36 -0
  82. data/lib/fluent/log.rb +445 -0
  83. data/lib/fluent/match.rb +141 -0
  84. data/lib/fluent/mixin.rb +31 -0
  85. data/lib/fluent/msgpack_factory.rb +62 -0
  86. data/lib/fluent/output.rb +26 -0
  87. data/lib/fluent/output_chain.rb +23 -0
  88. data/lib/fluent/parser.rb +23 -0
  89. data/lib/fluent/plugin.rb +161 -0
  90. data/lib/fluent/plugin/bare_output.rb +63 -0
  91. data/lib/fluent/plugin/base.rb +130 -0
  92. data/lib/fluent/plugin/buf_file.rb +154 -0
  93. data/lib/fluent/plugin/buf_memory.rb +34 -0
  94. data/lib/fluent/plugin/buffer.rb +603 -0
  95. data/lib/fluent/plugin/buffer/chunk.rb +160 -0
  96. data/lib/fluent/plugin/buffer/file_chunk.rb +323 -0
  97. data/lib/fluent/plugin/buffer/memory_chunk.rb +90 -0
  98. data/lib/fluent/plugin/exec_util.rb +22 -0
  99. data/lib/fluent/plugin/file_util.rb +22 -0
  100. data/lib/fluent/plugin/file_wrapper.rb +120 -0
  101. data/lib/fluent/plugin/filter.rb +93 -0
  102. data/lib/fluent/plugin/filter_grep.rb +75 -0
  103. data/lib/fluent/plugin/filter_record_transformer.rb +342 -0
  104. data/lib/fluent/plugin/filter_stdout.rb +53 -0
  105. data/lib/fluent/plugin/formatter.rb +45 -0
  106. data/lib/fluent/plugin/formatter_csv.rb +47 -0
  107. data/lib/fluent/plugin/formatter_hash.rb +29 -0
  108. data/lib/fluent/plugin/formatter_json.rb +44 -0
  109. data/lib/fluent/plugin/formatter_ltsv.rb +41 -0
  110. data/lib/fluent/plugin/formatter_msgpack.rb +29 -0
  111. data/lib/fluent/plugin/formatter_out_file.rb +78 -0
  112. data/lib/fluent/plugin/formatter_single_value.rb +34 -0
  113. data/lib/fluent/plugin/formatter_stdout.rb +74 -0
  114. data/lib/fluent/plugin/in_debug_agent.rb +64 -0
  115. data/lib/fluent/plugin/in_dummy.rb +135 -0
  116. data/lib/fluent/plugin/in_exec.rb +149 -0
  117. data/lib/fluent/plugin/in_forward.rb +366 -0
  118. data/lib/fluent/plugin/in_gc_stat.rb +52 -0
  119. data/lib/fluent/plugin/in_http.rb +422 -0
  120. data/lib/fluent/plugin/in_monitor_agent.rb +401 -0
  121. data/lib/fluent/plugin/in_object_space.rb +90 -0
  122. data/lib/fluent/plugin/in_syslog.rb +204 -0
  123. data/lib/fluent/plugin/in_tail.rb +838 -0
  124. data/lib/fluent/plugin/in_tcp.rb +41 -0
  125. data/lib/fluent/plugin/in_udp.rb +37 -0
  126. data/lib/fluent/plugin/in_unix.rb +201 -0
  127. data/lib/fluent/plugin/input.rb +33 -0
  128. data/lib/fluent/plugin/multi_output.rb +95 -0
  129. data/lib/fluent/plugin/out_buffered_null.rb +59 -0
  130. data/lib/fluent/plugin/out_buffered_stdout.rb +70 -0
  131. data/lib/fluent/plugin/out_copy.rb +42 -0
  132. data/lib/fluent/plugin/out_exec.rb +114 -0
  133. data/lib/fluent/plugin/out_exec_filter.rb +393 -0
  134. data/lib/fluent/plugin/out_file.rb +167 -0
  135. data/lib/fluent/plugin/out_forward.rb +646 -0
  136. data/lib/fluent/plugin/out_null.rb +27 -0
  137. data/lib/fluent/plugin/out_relabel.rb +28 -0
  138. data/lib/fluent/plugin/out_roundrobin.rb +80 -0
  139. data/lib/fluent/plugin/out_stdout.rb +48 -0
  140. data/lib/fluent/plugin/out_stream.rb +130 -0
  141. data/lib/fluent/plugin/output.rb +1020 -0
  142. data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
  143. data/lib/fluent/plugin/parser.rb +175 -0
  144. data/lib/fluent/plugin/parser_apache.rb +28 -0
  145. data/lib/fluent/plugin/parser_apache2.rb +84 -0
  146. data/lib/fluent/plugin/parser_apache_error.rb +26 -0
  147. data/lib/fluent/plugin/parser_csv.rb +33 -0
  148. data/lib/fluent/plugin/parser_json.rb +79 -0
  149. data/lib/fluent/plugin/parser_ltsv.rb +50 -0
  150. data/lib/fluent/plugin/parser_multiline.rb +104 -0
  151. data/lib/fluent/plugin/parser_nginx.rb +28 -0
  152. data/lib/fluent/plugin/parser_none.rb +36 -0
  153. data/lib/fluent/plugin/parser_regexp.rb +73 -0
  154. data/lib/fluent/plugin/parser_syslog.rb +82 -0
  155. data/lib/fluent/plugin/parser_tsv.rb +37 -0
  156. data/lib/fluent/plugin/socket_util.rb +22 -0
  157. data/lib/fluent/plugin/storage.rb +84 -0
  158. data/lib/fluent/plugin/storage_local.rb +132 -0
  159. data/lib/fluent/plugin/string_util.rb +22 -0
  160. data/lib/fluent/plugin_helper.rb +42 -0
  161. data/lib/fluent/plugin_helper/child_process.rb +298 -0
  162. data/lib/fluent/plugin_helper/compat_parameters.rb +224 -0
  163. data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
  164. data/lib/fluent/plugin_helper/event_loop.rb +118 -0
  165. data/lib/fluent/plugin_helper/formatter.rb +149 -0
  166. data/lib/fluent/plugin_helper/inject.rb +125 -0
  167. data/lib/fluent/plugin_helper/parser.rb +147 -0
  168. data/lib/fluent/plugin_helper/retry_state.rb +177 -0
  169. data/lib/fluent/plugin_helper/storage.rb +331 -0
  170. data/lib/fluent/plugin_helper/thread.rb +147 -0
  171. data/lib/fluent/plugin_helper/timer.rb +90 -0
  172. data/lib/fluent/plugin_id.rb +63 -0
  173. data/lib/fluent/process.rb +504 -0
  174. data/lib/fluent/registry.rb +99 -0
  175. data/lib/fluent/root_agent.rb +314 -0
  176. data/lib/fluent/rpc.rb +94 -0
  177. data/lib/fluent/supervisor.rb +680 -0
  178. data/lib/fluent/system_config.rb +122 -0
  179. data/lib/fluent/test.rb +56 -0
  180. data/lib/fluent/test/base.rb +85 -0
  181. data/lib/fluent/test/driver/base.rb +179 -0
  182. data/lib/fluent/test/driver/base_owned.rb +70 -0
  183. data/lib/fluent/test/driver/base_owner.rb +125 -0
  184. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  185. data/lib/fluent/test/driver/filter.rb +57 -0
  186. data/lib/fluent/test/driver/formatter.rb +30 -0
  187. data/lib/fluent/test/driver/input.rb +31 -0
  188. data/lib/fluent/test/driver/multi_output.rb +52 -0
  189. data/lib/fluent/test/driver/output.rb +76 -0
  190. data/lib/fluent/test/driver/parser.rb +30 -0
  191. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  192. data/lib/fluent/test/filter_test.rb +77 -0
  193. data/lib/fluent/test/formatter_test.rb +65 -0
  194. data/lib/fluent/test/helpers.rb +79 -0
  195. data/lib/fluent/test/input_test.rb +172 -0
  196. data/lib/fluent/test/log.rb +73 -0
  197. data/lib/fluent/test/output_test.rb +156 -0
  198. data/lib/fluent/test/parser_test.rb +70 -0
  199. data/lib/fluent/time.rb +175 -0
  200. data/lib/fluent/timezone.rb +133 -0
  201. data/lib/fluent/unique_id.rb +39 -0
  202. data/lib/fluent/version.rb +21 -0
  203. data/lib/fluent/winsvc.rb +71 -0
  204. data/test/compat/test_calls_super.rb +166 -0
  205. data/test/compat/test_parser.rb +82 -0
  206. data/test/config/assertions.rb +42 -0
  207. data/test/config/test_config_parser.rb +507 -0
  208. data/test/config/test_configurable.rb +1194 -0
  209. data/test/config/test_configure_proxy.rb +386 -0
  210. data/test/config/test_dsl.rb +415 -0
  211. data/test/config/test_element.rb +403 -0
  212. data/test/config/test_literal_parser.rb +297 -0
  213. data/test/config/test_section.rb +184 -0
  214. data/test/config/test_system_config.rb +120 -0
  215. data/test/config/test_types.rb +171 -0
  216. data/test/helper.rb +119 -0
  217. data/test/plugin/data/2010/01/20100102-030405.log +0 -0
  218. data/test/plugin/data/2010/01/20100102-030406.log +0 -0
  219. data/test/plugin/data/2010/01/20100102.log +0 -0
  220. data/test/plugin/data/log/bar +0 -0
  221. data/test/plugin/data/log/foo/bar.log +0 -0
  222. data/test/plugin/data/log/test.log +0 -0
  223. data/test/plugin/test_bare_output.rb +118 -0
  224. data/test/plugin/test_base.rb +75 -0
  225. data/test/plugin/test_buf_file.rb +571 -0
  226. data/test/plugin/test_buf_memory.rb +42 -0
  227. data/test/plugin/test_buffer.rb +1200 -0
  228. data/test/plugin/test_buffer_chunk.rb +168 -0
  229. data/test/plugin/test_buffer_file_chunk.rb +771 -0
  230. data/test/plugin/test_buffer_memory_chunk.rb +265 -0
  231. data/test/plugin/test_file_util.rb +96 -0
  232. data/test/plugin/test_filter.rb +353 -0
  233. data/test/plugin/test_filter_grep.rb +119 -0
  234. data/test/plugin/test_filter_record_transformer.rb +600 -0
  235. data/test/plugin/test_filter_stdout.rb +211 -0
  236. data/test/plugin/test_formatter_csv.rb +94 -0
  237. data/test/plugin/test_formatter_json.rb +30 -0
  238. data/test/plugin/test_formatter_ltsv.rb +52 -0
  239. data/test/plugin/test_formatter_msgpack.rb +28 -0
  240. data/test/plugin/test_formatter_out_file.rb +95 -0
  241. data/test/plugin/test_formatter_single_value.rb +38 -0
  242. data/test/plugin/test_in_debug_agent.rb +28 -0
  243. data/test/plugin/test_in_dummy.rb +188 -0
  244. data/test/plugin/test_in_exec.rb +133 -0
  245. data/test/plugin/test_in_forward.rb +635 -0
  246. data/test/plugin/test_in_gc_stat.rb +39 -0
  247. data/test/plugin/test_in_http.rb +442 -0
  248. data/test/plugin/test_in_monitor_agent.rb +329 -0
  249. data/test/plugin/test_in_object_space.rb +64 -0
  250. data/test/plugin/test_in_syslog.rb +205 -0
  251. data/test/plugin/test_in_tail.rb +1001 -0
  252. data/test/plugin/test_in_tcp.rb +102 -0
  253. data/test/plugin/test_in_udp.rb +121 -0
  254. data/test/plugin/test_in_unix.rb +126 -0
  255. data/test/plugin/test_input.rb +122 -0
  256. data/test/plugin/test_multi_output.rb +180 -0
  257. data/test/plugin/test_out_buffered_null.rb +79 -0
  258. data/test/plugin/test_out_buffered_stdout.rb +122 -0
  259. data/test/plugin/test_out_copy.rb +160 -0
  260. data/test/plugin/test_out_exec.rb +155 -0
  261. data/test/plugin/test_out_exec_filter.rb +262 -0
  262. data/test/plugin/test_out_file.rb +383 -0
  263. data/test/plugin/test_out_forward.rb +590 -0
  264. data/test/plugin/test_out_null.rb +29 -0
  265. data/test/plugin/test_out_relabel.rb +28 -0
  266. data/test/plugin/test_out_roundrobin.rb +146 -0
  267. data/test/plugin/test_out_stdout.rb +92 -0
  268. data/test/plugin/test_out_stream.rb +93 -0
  269. data/test/plugin/test_output.rb +568 -0
  270. data/test/plugin/test_output_as_buffered.rb +1604 -0
  271. data/test/plugin/test_output_as_buffered_overflow.rb +250 -0
  272. data/test/plugin/test_output_as_buffered_retries.rb +839 -0
  273. data/test/plugin/test_output_as_buffered_secondary.rb +817 -0
  274. data/test/plugin/test_output_as_standard.rb +374 -0
  275. data/test/plugin/test_owned_by.rb +35 -0
  276. data/test/plugin/test_parser_apache.rb +42 -0
  277. data/test/plugin/test_parser_apache2.rb +38 -0
  278. data/test/plugin/test_parser_apache_error.rb +45 -0
  279. data/test/plugin/test_parser_base.rb +32 -0
  280. data/test/plugin/test_parser_csv.rb +104 -0
  281. data/test/plugin/test_parser_json.rb +107 -0
  282. data/test/plugin/test_parser_labeled_tsv.rb +129 -0
  283. data/test/plugin/test_parser_multiline.rb +100 -0
  284. data/test/plugin/test_parser_nginx.rb +48 -0
  285. data/test/plugin/test_parser_none.rb +53 -0
  286. data/test/plugin/test_parser_regexp.rb +277 -0
  287. data/test/plugin/test_parser_syslog.rb +66 -0
  288. data/test/plugin/test_parser_time.rb +46 -0
  289. data/test/plugin/test_parser_tsv.rb +121 -0
  290. data/test/plugin/test_storage.rb +167 -0
  291. data/test/plugin/test_storage_local.rb +8 -0
  292. data/test/plugin/test_string_util.rb +26 -0
  293. data/test/plugin_helper/test_child_process.rb +608 -0
  294. data/test/plugin_helper/test_compat_parameters.rb +242 -0
  295. data/test/plugin_helper/test_event_emitter.rb +51 -0
  296. data/test/plugin_helper/test_event_loop.rb +52 -0
  297. data/test/plugin_helper/test_formatter.rb +252 -0
  298. data/test/plugin_helper/test_inject.rb +487 -0
  299. data/test/plugin_helper/test_parser.rb +263 -0
  300. data/test/plugin_helper/test_retry_state.rb +399 -0
  301. data/test/plugin_helper/test_storage.rb +521 -0
  302. data/test/plugin_helper/test_thread.rb +164 -0
  303. data/test/plugin_helper/test_timer.rb +131 -0
  304. data/test/scripts/exec_script.rb +32 -0
  305. data/test/scripts/fluent/plugin/formatter_known.rb +8 -0
  306. data/test/scripts/fluent/plugin/out_test.rb +81 -0
  307. data/test/scripts/fluent/plugin/out_test2.rb +80 -0
  308. data/test/scripts/fluent/plugin/parser_known.rb +4 -0
  309. data/test/test_config.rb +179 -0
  310. data/test/test_configdsl.rb +148 -0
  311. data/test/test_event.rb +329 -0
  312. data/test/test_event_router.rb +331 -0
  313. data/test/test_event_time.rb +184 -0
  314. data/test/test_filter.rb +121 -0
  315. data/test/test_formatter.rb +319 -0
  316. data/test/test_input.rb +31 -0
  317. data/test/test_log.rb +572 -0
  318. data/test/test_match.rb +137 -0
  319. data/test/test_mixin.rb +351 -0
  320. data/test/test_output.rb +214 -0
  321. data/test/test_plugin_classes.rb +136 -0
  322. data/test/test_plugin_helper.rb +81 -0
  323. data/test/test_process.rb +48 -0
  324. data/test/test_root_agent.rb +278 -0
  325. data/test/test_supervisor.rb +339 -0
  326. data/test/test_time_formatter.rb +186 -0
  327. data/test/test_unique_id.rb +47 -0
  328. metadata +823 -0
@@ -0,0 +1,70 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'fluent/plugin/output'
18
+
19
+ module Fluent::Plugin
20
+ class BufferedStdoutOutput < Output
21
+ Fluent::Plugin.register_output('buffered_stdout', self)
22
+
23
+ helpers :formatter, :inject, :compat_parameters
24
+
25
+ config_section :buffer do
26
+ config_set_default :chunk_keys, ['tag']
27
+ config_set_default :flush_at_shutdown, true
28
+ config_set_default :chunk_limit_size, 10 * 1024
29
+ end
30
+
31
+ DEFAULT_FORMAT_TYPE = 'json'
32
+
33
+ config_section :format do
34
+ config_set_default :@type, DEFAULT_FORMAT_TYPE
35
+ end
36
+
37
+ attr_accessor :delayed
38
+
39
+ def initialize
40
+ super
41
+ @delayed = false
42
+ end
43
+
44
+ def prefer_delayed_commit
45
+ @delayed
46
+ end
47
+
48
+ def configure(conf)
49
+ if conf['output_type'] && !conf['format']
50
+ conf['format'] = conf['output_type']
51
+ end
52
+ compat_parameters_convert(conf, :inject, :formatter)
53
+ super
54
+ @formatter = formatter_create(conf: conf.elements('format').first, default_type: DEFAULT_FORMAT_TYPE)
55
+ end
56
+
57
+ def write(chunk)
58
+ chunk.write_to($log)
59
+ end
60
+
61
+ def try_write(chunk)
62
+ chunk.write_to($log)
63
+ end
64
+
65
+ def format(tag, time, record)
66
+ record = inject_values_to_record(tag, time, record)
67
+ "#{Time.at(time).localtime} #{tag}: #{@formatter.format(tag, time, record).chomp}\n"
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,42 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'fluent/plugin/multi_output'
18
+ require 'fluent/config/error'
19
+ require 'fluent/event'
20
+
21
+ module Fluent::Plugin
22
+ class CopyOutput < MultiOutput
23
+ Fluent::Plugin.register_output('copy', self)
24
+
25
+ desc 'If true, pass different record to each `store` plugin.'
26
+ config_param :deep_copy, :bool, default: false
27
+
28
+ def process(tag, es)
29
+ unless es.repeatable?
30
+ m = Fluent::MultiEventStream.new
31
+ es.each {|time,record|
32
+ m.add(time, record)
33
+ }
34
+ es = m
35
+ end
36
+
37
+ outputs.each do |output|
38
+ output.emit_events(tag, @deep_copy ? es.dup : es)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,114 @@
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 'tempfile'
18
+
19
+ require 'fluent/plugin/output'
20
+ require 'fluent/config/error'
21
+ require 'fluent/plugin/exec_util'
22
+ require 'fluent/mixin' # for TimeFormatter
23
+
24
+ module Fluent::Plugin
25
+ class ExecOutput < Output
26
+ Fluent::Plugin.register_output('exec', self)
27
+
28
+ helpers :compat_parameters
29
+
30
+ desc 'The command (program) to execute. The exec plugin passes the path of a TSV file as the last argumen'
31
+ config_param :command, :string
32
+ desc 'Specify the comma-separated keys when using the tsv format.'
33
+ config_param :keys, default: [] do |val|
34
+ val.split(',')
35
+ end
36
+ desc 'The name of the key to use as the event tag. This replaces the value in the event record.'
37
+ config_param :tag_key, :string, default: nil
38
+ desc 'The name of the key to use as the event time. This replaces the the value in the event record.'
39
+ config_param :time_key, :string, default: nil
40
+ desc 'The format for event time used when the time_key parameter is specified. The default is UNIX time (integer).'
41
+ config_param :time_format, :string, default: nil
42
+ desc "The format used to map the incoming events to the program input. (#{Fluent::ExecUtil::SUPPORTED_FORMAT.keys.join(',')})"
43
+ config_param :format, default: :tsv, skip_accessor: true do |val|
44
+ f = Fluent::ExecUtil::SUPPORTED_FORMAT[val]
45
+ raise ConfigError, "Unsupported format '#{val}'" unless f
46
+ f
47
+ end
48
+ config_param :localtime, :bool, default: false
49
+ config_param :timezone, :string, default: nil
50
+
51
+ def compat_parameters_default_chunk_key
52
+ 'time'
53
+ end
54
+
55
+ def configure(conf)
56
+ compat_parameters_convert(conf, :buffer, default_chunk_key: 'time')
57
+
58
+ super
59
+
60
+ @formatter = case @format
61
+ when :tsv
62
+ if @keys.empty?
63
+ raise Fluent::ConfigError, "keys option is required on exec output for tsv format"
64
+ end
65
+ Fluent::ExecUtil::TSVFormatter.new(@keys)
66
+ when :json
67
+ Fluent::ExecUtil::JSONFormatter.new
68
+ when :msgpack
69
+ Fluent::ExecUtil::MessagePackFormatter.new
70
+ end
71
+
72
+ if @time_key
73
+ if @time_format
74
+ tf = Fluent::TimeFormatter.new(@time_format, @localtime, @timezone)
75
+ @time_format_proc = tf.method(:format)
76
+ else
77
+ @time_format_proc = Proc.new { |time| time.to_s }
78
+ end
79
+ end
80
+ end
81
+
82
+ def format(tag, time, record)
83
+ out = ''
84
+ if @time_key
85
+ record[@time_key] = @time_format_proc.call(time)
86
+ end
87
+ if @tag_key
88
+ record[@tag_key] = tag
89
+ end
90
+ @formatter.call(record, out)
91
+ out
92
+ end
93
+
94
+ def write(chunk)
95
+ if chunk.respond_to?(:path)
96
+ prog = "#{@command} #{chunk.path}"
97
+ else
98
+ tmpfile = Tempfile.new("fluent-plugin-exec-")
99
+ tmpfile.binmode
100
+ chunk.write_to(tmpfile)
101
+ tmpfile.close
102
+ prog = "#{@command} #{tmpfile.path}"
103
+ end
104
+
105
+ system(prog)
106
+ ecode = $?.to_i
107
+ tmpfile.delete if tmpfile
108
+
109
+ if ecode != 0
110
+ raise "command returns #{ecode}: #{prog}"
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,393 @@
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 'yajl'
18
+
19
+ require 'fluent/output'
20
+ require 'fluent/env'
21
+ require 'fluent/time'
22
+ require 'fluent/timezone'
23
+ require 'fluent/plugin/exec_util'
24
+ require 'fluent/config/error'
25
+
26
+ module Fluent
27
+ class ExecFilterOutput < BufferedOutput
28
+ Plugin.register_output('exec_filter', self)
29
+
30
+ def initialize
31
+ super
32
+ require 'fluent/timezone'
33
+ end
34
+
35
+ desc 'The command (program) to execute.'
36
+ config_param :command, :string
37
+
38
+ config_param :remove_prefix, :string, default: nil
39
+ config_param :add_prefix, :string, default: nil
40
+
41
+ desc "The format used to map the incoming event to the program input.(#{Fluent::ExecUtil::SUPPORTED_FORMAT.keys.join(',')})"
42
+ config_param :in_format, default: :tsv do |val|
43
+ f = Fluent::ExecUtil::SUPPORTED_FORMAT[val]
44
+ raise ConfigError, "Unsupported in_format '#{val}'" unless f
45
+ f
46
+ end
47
+ desc 'Specify comma-separated values for tsv format.'
48
+ config_param :in_keys, default: [] do |val|
49
+ val.split(',')
50
+ 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.(#{Fluent::ExecUtil::SUPPORTED_FORMAT.keys.join(',')})"
59
+ config_param :out_format, default: :tsv do |val|
60
+ f = Fluent::ExecUtil::SUPPORTED_FORMAT[val]
61
+ raise ConfigError, "Unsupported out_format '#{val}'" unless f
62
+ f
63
+ end
64
+ desc 'Specify comma-separated values for tsv format.'
65
+ config_param :out_keys, default: [] do |val| # for tsv format
66
+ val.split(',')
67
+ 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
+
75
+ config_param :tag, :string, default: nil
76
+
77
+ config_param :time_key, :string, default: nil
78
+ config_param :time_format, :string, default: nil
79
+
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
+ desc 'The number of spawned process for command.'
85
+ config_param :num_children, :integer, default: 1
86
+
87
+ desc 'Respawn command when command exit.'
88
+ # nil, 'none' or 0: no respawn, 'inf' or -1: infinite times, positive integer: try to respawn specified times only
89
+ config_param :child_respawn, :string, default: nil
90
+
91
+ # 0: output logs for all of messages to emit
92
+ config_param :suppress_error_log_interval, :time, default: 0
93
+
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
107
+ end
108
+
109
+ if time_format = conf['time_format']
110
+ # TODO obsoleted?
111
+ @in_time_format = time_format
112
+ @out_time_format = time_format
113
+ end
114
+
115
+ super
116
+
117
+ if conf['localtime']
118
+ @localtime = true
119
+ elsif conf['utc']
120
+ @localtime = false
121
+ end
122
+
123
+ if conf['timezone']
124
+ @timezone = conf['timezone']
125
+ Fluent::Timezone.validate!(@timezone)
126
+ end
127
+
128
+ if !@tag && !@out_tag_key
129
+ raise ConfigError, "'tag' or 'out_tag_key' option is required on exec_filter output"
130
+ end
131
+
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}"
141
+ end
142
+
143
+ if @out_time_key
144
+ if f = @out_time_format
145
+ @time_parse_proc =
146
+ begin
147
+ strptime = Strptime.new(f)
148
+ Proc.new { |str| Fluent::EventTime.from_time(strptime.exec(str)) }
149
+ rescue
150
+ Proc.new {|str| Fluent::EventTime.from_time(Time.strptime(str, f)) }
151
+ end
152
+ else
153
+ @time_parse_proc = Proc.new {|str| Fluent::EventTime.from_time(Time.at(str.to_f)) }
154
+ end
155
+ elsif @out_time_format
156
+ log.warn "out_time_format effects nothing when out_time_key is not specified: #{conf}"
157
+ end
158
+
159
+ if @remove_prefix
160
+ @removed_prefix_string = @remove_prefix + '.'
161
+ @removed_length = @removed_prefix_string.length
162
+ end
163
+ if @add_prefix
164
+ @added_prefix_string = @add_prefix + '.'
165
+ end
166
+
167
+ case @in_format
168
+ when :tsv
169
+ if @in_keys.empty?
170
+ raise ConfigError, "in_keys option is required on exec_filter output for tsv in_format"
171
+ end
172
+ @formatter = Fluent::ExecUtil::TSVFormatter.new(@in_keys)
173
+ when :json
174
+ @formatter = Fluent::ExecUtil::JSONFormatter.new
175
+ when :msgpack
176
+ @formatter = Fluent::ExecUtil::MessagePackFormatter.new
177
+ end
178
+
179
+ case @out_format
180
+ when :tsv
181
+ if @out_keys.empty?
182
+ raise ConfigError, "out_keys option is required on exec_filter output for tsv in_format"
183
+ end
184
+ @parser = Fluent::ExecUtil::TSVParser.new(@out_keys, method(:on_message))
185
+ when :json
186
+ @parser = Fluent::ExecUtil::JSONParser.new(method(:on_message))
187
+ when :msgpack
188
+ @parser = Fluent::ExecUtil::MessagePackParser.new(method(:on_message))
189
+ end
190
+
191
+ @respawns = if @child_respawn.nil? or @child_respawn == 'none' or @child_respawn == '0'
192
+ 0
193
+ elsif @child_respawn == 'inf' or @child_respawn == '-1'
194
+ -1
195
+ elsif @child_respawn =~ /^\d+$/
196
+ @child_respawn.to_i
197
+ else
198
+ raise ConfigError, "child_respawn option argument invalid: none(or 0), inf(or -1) or positive number"
199
+ end
200
+
201
+ @suppress_error_log_interval ||= 0
202
+ @next_log_time = Time.now.to_i
203
+ end
204
+
205
+ def start
206
+ super
207
+
208
+ @children = []
209
+ @rr = 0
210
+ begin
211
+ @num_children.times do
212
+ c = ChildProcess.new(@parser, @respawns, log)
213
+ c.start(@command)
214
+ @children << c
215
+ end
216
+ rescue
217
+ shutdown
218
+ raise
219
+ end
220
+ end
221
+
222
+ def before_shutdown
223
+ log.debug "out_exec_filter#before_shutdown called"
224
+ @children.each {|c|
225
+ c.finished = true
226
+ }
227
+ sleep 0.5 # TODO wait time before killing child process
228
+
229
+ super
230
+ end
231
+
232
+ def shutdown
233
+ @children.reject! {|c|
234
+ c.shutdown
235
+ true
236
+ }
237
+
238
+ super
239
+ end
240
+
241
+ def format_stream(tag, es)
242
+ if @remove_prefix
243
+ if (tag[0, @removed_length] == @removed_prefix_string and tag.length > @removed_length) or tag == @removed_prefix
244
+ tag = tag[@removed_length..-1] || ''
245
+ end
246
+ end
247
+
248
+ out = ''
249
+
250
+ es.each {|time,record|
251
+ if @in_time_key
252
+ record[@in_time_key] = @time_format_proc.call(time)
253
+ end
254
+ if @in_tag_key
255
+ record[@in_tag_key] = tag
256
+ end
257
+ @formatter.call(record, out)
258
+ }
259
+
260
+ out
261
+ end
262
+
263
+ def write(chunk)
264
+ r = @rr = (@rr + 1) % @children.length
265
+ @children[r].write chunk
266
+ end
267
+
268
+ class ChildProcess
269
+ attr_accessor :finished
270
+
271
+ def initialize(parser, respawns=0, log = $log)
272
+ @pid = nil
273
+ @thread = nil
274
+ @parser = parser
275
+ @respawns = respawns
276
+ @mutex = Mutex.new
277
+ @finished = nil
278
+ @log = log
279
+ end
280
+
281
+ def start(command)
282
+ @command = command
283
+ @mutex.synchronize do
284
+ @io = IO.popen(command, "r+")
285
+ @pid = @io.pid
286
+ @io.sync = true
287
+ @thread = Thread.new(&method(:run))
288
+ end
289
+ @finished = false
290
+ end
291
+
292
+ def kill_child(join_wait)
293
+ begin
294
+ signal = Fluent.windows? ? :KILL : :TERM
295
+ Process.kill(signal, @pid)
296
+ rescue #Errno::ECHILD, Errno::ESRCH, Errno::EPERM
297
+ # Errno::ESRCH 'No such process', ignore
298
+ # child process killed by signal chained from fluentd process
299
+ end
300
+ if @thread.join(join_wait)
301
+ # @thread successfully shutdown
302
+ return
303
+ end
304
+ begin
305
+ Process.kill(:KILL, @pid)
306
+ rescue #Errno::ECHILD, Errno::ESRCH, Errno::EPERM
307
+ # ignore if successfully killed by :TERM
308
+ end
309
+ @thread.join
310
+ end
311
+
312
+ def shutdown
313
+ @finished = true
314
+ @mutex.synchronize do
315
+ kill_child(60) # TODO wait time
316
+ end
317
+ end
318
+
319
+ def write(chunk)
320
+ begin
321
+ chunk.write_to(@io)
322
+ rescue Errno::EPIPE => e
323
+ # Broken pipe (child process unexpectedly exited)
324
+ @log.warn "exec_filter Broken pipe, child process maybe exited.", command: @command
325
+ if try_respawn
326
+ retry # retry chunk#write_to with child respawned
327
+ else
328
+ raise e # to retry #write with other ChildProcess instance (when num_children > 1)
329
+ end
330
+ end
331
+ end
332
+
333
+ def try_respawn
334
+ return false if @respawns == 0
335
+ @mutex.synchronize do
336
+ return false if @respawns == 0
337
+
338
+ kill_child(5) # TODO wait time
339
+
340
+ @io = IO.popen(@command, "r+")
341
+ @pid = @io.pid
342
+ @io.sync = true
343
+ @thread = Thread.new(&method(:run))
344
+
345
+ @respawns -= 1 if @respawns > 0
346
+ end
347
+ @log.warn "exec_filter child process successfully respawned.", command: @command, respawns: @respawns
348
+ true
349
+ end
350
+
351
+ def run
352
+ @parser.call(@io)
353
+ rescue
354
+ @log.error "exec_filter thread unexpectedly failed with an error.", command: @command, error: $!.to_s
355
+ @log.warn_backtrace $!.backtrace
356
+ ensure
357
+ _pid, stat = Process.waitpid2(@pid)
358
+ unless @finished
359
+ @log.error "exec_filter process unexpectedly exited.", command: @command, ecode: stat.to_i
360
+ unless @respawns == 0
361
+ @log.warn "exec_filter child process will respawn for next input data (respawns #{@respawns})."
362
+ end
363
+ end
364
+ end
365
+ end
366
+
367
+ def on_message(record)
368
+ if val = record.delete(@out_time_key)
369
+ time = @time_parse_proc.call(val)
370
+ else
371
+ time = Engine.now
372
+ end
373
+
374
+ if val = record.delete(@out_tag_key)
375
+ tag = if @add_prefix
376
+ @added_prefix_string + val
377
+ else
378
+ val
379
+ end
380
+ else
381
+ tag = @tag
382
+ end
383
+
384
+ router.emit(tag, time, record)
385
+ rescue
386
+ if @suppress_error_log_interval == 0 || Time.now.to_i > @next_log_time
387
+ log.error "exec_filter failed to emit", error: $!, record: Yajl.dump(record)
388
+ log.warn_backtrace $!.backtrace
389
+ @next_log_time = Time.now.to_i + @suppress_error_log_interval
390
+ end
391
+ end
392
+ end
393
+ end