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,52 @@
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/input'
18
+
19
+ module Fluent::Plugin
20
+ class GCStatInput < Fluent::Plugin::Input
21
+ Fluent::Plugin.register_input('gc_stat', self)
22
+
23
+ helpers :timer
24
+
25
+ def initialize
26
+ super
27
+ end
28
+
29
+ config_param :emit_interval, :time, default: 60
30
+ config_param :tag, :string
31
+
32
+ def configure(conf)
33
+ super
34
+ end
35
+
36
+ def start
37
+ super
38
+
39
+ timer_execute(:in_gc_stat, @emit_interval, &method(:on_timer))
40
+ end
41
+
42
+ def shutdown
43
+ super
44
+ end
45
+
46
+ def on_timer
47
+ now = Fluent::EventTime.now
48
+ record = GC.stat
49
+ router.emit(@tag, now, record)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,422 @@
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 'uri'
18
+ require 'socket'
19
+ require 'json'
20
+
21
+ require 'cool.io'
22
+
23
+ require 'fluent/input'
24
+ require 'fluent/event'
25
+ require 'fluent/process'
26
+
27
+ module Fluent
28
+ class HttpInput < Input
29
+ Plugin.register_input('http', self)
30
+
31
+ include DetachMultiProcessMixin
32
+
33
+ require 'http/parser'
34
+
35
+ def initialize
36
+ require 'webrick/httputils'
37
+ super
38
+ end
39
+
40
+ 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
+ desc 'The port to listen to.'
43
+ config_param :port, :integer, default: 9880
44
+ desc 'The bind address to listen to.'
45
+ config_param :bind, :string, default: '0.0.0.0'
46
+ desc 'The size limit of the POSTed element. Default is 32MB.'
47
+ config_param :body_size_limit, :size, default: 32*1024*1024 # TODO default
48
+ desc 'The timeout limit for keeping the connection alive.'
49
+ config_param :keepalive_timeout, :time, default: 10 # TODO default
50
+ config_param :backlog, :integer, default: nil
51
+ desc 'Add HTTP_ prefix headers to the record.'
52
+ config_param :add_http_headers, :bool, default: false
53
+ desc 'Add REMOTE_ADDR header to the record.'
54
+ config_param :add_remote_addr, :bool, default: false
55
+ desc 'The format of the HTTP body.'
56
+ config_param :format, :string, default: 'default'
57
+ config_param :blocking_timeout, :time, default: 0.5
58
+ desc 'Set a white list of domains that can do CORS (Cross-Origin Resource Sharing)'
59
+ config_param :cors_allow_origins, :array, default: nil
60
+ desc 'Respond with empty gif image of 1x1 pixel.'
61
+ config_param :respond_with_empty_img, :bool, default: false
62
+
63
+ def configure(conf)
64
+ super
65
+
66
+ m = if @format == 'default'
67
+ method(:parse_params_default)
68
+ else
69
+ @parser = Plugin.new_parser(@format)
70
+ @parser.configure(conf)
71
+ method(:parse_params_with_parser)
72
+ end
73
+ (class << self; self; end).module_eval do
74
+ define_method(:parse_params, m)
75
+ end
76
+ end
77
+
78
+ class KeepaliveManager < Coolio::TimerWatcher
79
+ def initialize(timeout)
80
+ super(1, true)
81
+ @cons = {}
82
+ @timeout = timeout.to_i
83
+ end
84
+
85
+ def add(sock)
86
+ @cons[sock] = sock
87
+ end
88
+
89
+ def delete(sock)
90
+ @cons.delete(sock)
91
+ end
92
+
93
+ def on_timer
94
+ @cons.each_pair {|sock,val|
95
+ if sock.step_idle > @timeout
96
+ sock.close
97
+ end
98
+ }
99
+ end
100
+ end
101
+
102
+ def start
103
+ log.debug "listening http on #{@bind}:#{@port}"
104
+
105
+ socket_manager_path = ENV['SERVERENGINE_SOCKETMANAGER_PATH']
106
+ if Fluent.windows?
107
+ socket_manager_path = socket_manager_path.to_i
108
+ end
109
+ client = ServerEngine::SocketManager::Client.new(socket_manager_path)
110
+ lsock = client.listen_tcp(@bind, @port)
111
+
112
+ detach_multi_process do
113
+ super
114
+ @km = KeepaliveManager.new(@keepalive_timeout)
115
+ @lsock = Coolio::TCPServer.new(lsock, nil, Handler, @km, method(:on_request),
116
+ @body_size_limit, @format, log,
117
+ @cors_allow_origins)
118
+ @lsock.listen(@backlog) unless @backlog.nil?
119
+
120
+ @loop = Coolio::Loop.new
121
+ @loop.attach(@km)
122
+ @loop.attach(@lsock)
123
+
124
+ @thread = Thread.new(&method(:run))
125
+ end
126
+ end
127
+
128
+ def shutdown
129
+ @loop.watchers.each {|w| w.detach }
130
+ @loop.stop
131
+ @lsock.close
132
+ @thread.join
133
+
134
+ super
135
+ end
136
+
137
+ def run
138
+ @loop.run(@blocking_timeout)
139
+ rescue
140
+ log.error "unexpected error", error: $!.to_s
141
+ log.error_backtrace
142
+ end
143
+
144
+ def on_request(path_info, params)
145
+ begin
146
+ path = path_info[1..-1] # remove /
147
+ tag = path.split('/').join('.')
148
+ record_time, record = parse_params(params)
149
+
150
+ # Skip nil record
151
+ if record.nil?
152
+ if @respond_with_empty_img
153
+ return ["200 OK", {'Content-Type'=>'image/gif; charset=utf-8'}, EMPTY_GIF_IMAGE]
154
+ else
155
+ return ["200 OK", {'Content-Type'=>'text/plain'}, ""]
156
+ end
157
+ end
158
+
159
+ unless record.is_a?(Array)
160
+ if @add_http_headers
161
+ params.each_pair { |k,v|
162
+ if k.start_with?("HTTP_")
163
+ record[k] = v
164
+ end
165
+ }
166
+ end
167
+ if @add_remote_addr
168
+ record['REMOTE_ADDR'] = params['REMOTE_ADDR']
169
+ end
170
+ end
171
+ time = if param_time = params['time']
172
+ param_time = param_time.to_f
173
+ param_time.zero? ? Engine.now : Fluent::EventTime.from_time(Time.at(param_time))
174
+ else
175
+ record_time.nil? ? Engine.now : record_time
176
+ end
177
+ rescue
178
+ return ["400 Bad Request", {'Content-Type'=>'text/plain'}, "400 Bad Request\n#{$!}\n"]
179
+ end
180
+
181
+ # TODO server error
182
+ begin
183
+ # Support batched requests
184
+ if record.is_a?(Array)
185
+ mes = MultiEventStream.new
186
+ record.each do |single_record|
187
+ if @add_http_headers
188
+ params.each_pair { |k,v|
189
+ if k.start_with?("HTTP_")
190
+ single_record[k] = v
191
+ end
192
+ }
193
+ end
194
+ if @add_remote_addr
195
+ single_record['REMOTE_ADDR'] = params['REMOTE_ADDR']
196
+ end
197
+ single_time = single_record.delete("time") || time
198
+ mes.add(single_time, single_record)
199
+ end
200
+ router.emit_stream(tag, mes)
201
+ else
202
+ router.emit(tag, time, record)
203
+ end
204
+ rescue
205
+ return ["500 Internal Server Error", {'Content-Type'=>'text/plain'}, "500 Internal Server Error\n#{$!}\n"]
206
+ end
207
+
208
+ if @respond_with_empty_img
209
+ return ["200 OK", {'Content-Type'=>'image/gif; charset=utf-8'}, EMPTY_GIF_IMAGE]
210
+ else
211
+ return ["200 OK", {'Content-Type'=>'text/plain'}, ""]
212
+ end
213
+ end
214
+
215
+ private
216
+
217
+ def parse_params_default(params)
218
+ record = if msgpack = params['msgpack']
219
+ Engine.msgpack_factory.unpacker.feed(msgpack).read
220
+ elsif js = params['json']
221
+ JSON.parse(js)
222
+ else
223
+ raise "'json' or 'msgpack' parameter is required"
224
+ end
225
+ return nil, record
226
+ end
227
+
228
+ EVENT_RECORD_PARAMETER = '_event_record'
229
+
230
+ def parse_params_with_parser(params)
231
+ if content = params[EVENT_RECORD_PARAMETER]
232
+ @parser.parse(content) { |time, record|
233
+ raise "Received event is not #{@format}: #{content}" if record.nil?
234
+ return time, record
235
+ }
236
+ else
237
+ raise "'#{EVENT_RECORD_PARAMETER}' parameter is required"
238
+ end
239
+ end
240
+
241
+ class Handler < Coolio::Socket
242
+ attr_reader :content_type
243
+
244
+ def initialize(io, km, callback, body_size_limit, format, log, cors_allow_origins)
245
+ super(io)
246
+ @km = km
247
+ @callback = callback
248
+ @body_size_limit = body_size_limit
249
+ @next_close = false
250
+ @format = format
251
+ @log = log
252
+ @cors_allow_origins = cors_allow_origins
253
+ @idle = 0
254
+ @km.add(self)
255
+
256
+ @remote_port, @remote_addr = *Socket.unpack_sockaddr_in(io.getpeername) rescue nil
257
+ end
258
+
259
+ def step_idle
260
+ @idle += 1
261
+ end
262
+
263
+ def on_close
264
+ @km.delete(self)
265
+ end
266
+
267
+ def on_connect
268
+ @parser = Http::Parser.new(self)
269
+ end
270
+
271
+ def on_read(data)
272
+ @idle = 0
273
+ @parser << data
274
+ rescue
275
+ @log.warn "unexpected error", error: $!.to_s
276
+ @log.warn_backtrace
277
+ close
278
+ end
279
+
280
+ def on_message_begin
281
+ @body = ''
282
+ end
283
+
284
+ def on_headers_complete(headers)
285
+ expect = nil
286
+ size = nil
287
+
288
+ if @parser.http_version == [1, 1]
289
+ @keep_alive = true
290
+ else
291
+ @keep_alive = false
292
+ end
293
+ @env = {}
294
+ @content_type = ""
295
+ headers.each_pair {|k,v|
296
+ @env["HTTP_#{k.gsub('-','_').upcase}"] = v
297
+ case k
298
+ when /Expect/i
299
+ expect = v
300
+ when /Content-Length/i
301
+ size = v.to_i
302
+ when /Content-Type/i
303
+ @content_type = v
304
+ when /Connection/i
305
+ if v =~ /close/i
306
+ @keep_alive = false
307
+ elsif v =~ /Keep-alive/i
308
+ @keep_alive = true
309
+ end
310
+ when /Origin/i
311
+ @origin = v
312
+ when /X-Forwarded-For/i
313
+ @remote_addr = v.split(",").first
314
+ end
315
+ }
316
+ if expect
317
+ if expect == '100-continue'
318
+ if !size || size < @body_size_limit
319
+ send_response_nobody("100 Continue", {})
320
+ else
321
+ send_response_and_close("413 Request Entity Too Large", {}, "Too large")
322
+ end
323
+ else
324
+ send_response_and_close("417 Expectation Failed", {}, "")
325
+ end
326
+ end
327
+ end
328
+
329
+ def on_body(chunk)
330
+ if @body.bytesize + chunk.bytesize > @body_size_limit
331
+ unless closing?
332
+ send_response_and_close("413 Request Entity Too Large", {}, "Too large")
333
+ end
334
+ return
335
+ end
336
+ @body << chunk
337
+ end
338
+
339
+ def on_message_complete
340
+ return if closing?
341
+
342
+ # CORS check
343
+ # ==========
344
+ # For every incoming request, we check if we have some CORS
345
+ # restrictions and white listed origins through @cors_allow_origins.
346
+ unless @cors_allow_origins.nil?
347
+ unless @cors_allow_origins.include?(@origin)
348
+ send_response_and_close("403 Forbidden", {'Connection' => 'close'}, "")
349
+ return
350
+ end
351
+ end
352
+
353
+ @env['REMOTE_ADDR'] = @remote_addr if @remote_addr
354
+
355
+ uri = URI.parse(@parser.request_url)
356
+ params = WEBrick::HTTPUtils.parse_query(uri.query)
357
+
358
+ if @format != 'default'
359
+ params[EVENT_RECORD_PARAMETER] = @body
360
+ elsif @content_type =~ /^application\/x-www-form-urlencoded/
361
+ params.update WEBrick::HTTPUtils.parse_query(@body)
362
+ elsif @content_type =~ /^multipart\/form-data; boundary=(.+)/
363
+ boundary = WEBrick::HTTPUtils.dequote($1)
364
+ params.update WEBrick::HTTPUtils.parse_form_data(@body, boundary)
365
+ elsif @content_type =~ /^application\/json/
366
+ params['json'] = @body
367
+ end
368
+ path_info = uri.path
369
+
370
+ params.merge!(@env)
371
+ @env.clear
372
+
373
+ code, header, body = *@callback.call(path_info, params)
374
+ body = body.to_s
375
+
376
+ header['Access-Control-Allow-Origin'] = @origin if !@cors_allow_origins.nil? && @cors_allow_origins.include?(@origin)
377
+ if @keep_alive
378
+ header['Connection'] = 'Keep-Alive'
379
+ send_response(code, header, body)
380
+ else
381
+ send_response_and_close(code, header, body)
382
+ end
383
+ end
384
+
385
+ def on_write_complete
386
+ close if @next_close
387
+ end
388
+
389
+ def send_response_and_close(code, header, body)
390
+ send_response(code, header, body)
391
+ @next_close = true
392
+ end
393
+
394
+ def closing?
395
+ @next_close
396
+ end
397
+
398
+ def send_response(code, header, body)
399
+ header['Content-Length'] ||= body.bytesize
400
+ header['Content-Type'] ||= 'text/plain'
401
+
402
+ data = %[HTTP/1.1 #{code}\r\n]
403
+ header.each_pair {|k,v|
404
+ data << "#{k}: #{v}\r\n"
405
+ }
406
+ data << "\r\n"
407
+ write data
408
+
409
+ write body
410
+ end
411
+
412
+ def send_response_nobody(code, header)
413
+ data = %[HTTP/1.1 #{code}\r\n]
414
+ header.each_pair {|k,v|
415
+ data << "#{k}: #{v}\r\n"
416
+ }
417
+ data << "\r\n"
418
+ write data
419
+ end
420
+ end
421
+ end
422
+ end