fluentd 1.20.0-aarch64-mingw-ucrt

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +116 -0
  3. data/ADOPTERS.md +5 -0
  4. data/AGENTS.md +46 -0
  5. data/AUTHORS +2 -0
  6. data/CHANGELOG.md +3324 -0
  7. data/CONTRIBUTING.md +45 -0
  8. data/GOVERNANCE.md +55 -0
  9. data/GithubWorkflow.md +78 -0
  10. data/LICENSE +202 -0
  11. data/MAINTAINERS.md +19 -0
  12. data/README.md +73 -0
  13. data/Rakefile +89 -0
  14. data/SECURITY.md +47 -0
  15. data/bin/fluent-binlog-reader +7 -0
  16. data/bin/fluent-ca-generate +6 -0
  17. data/bin/fluent-cap-ctl +7 -0
  18. data/bin/fluent-cat +5 -0
  19. data/bin/fluent-ctl +7 -0
  20. data/bin/fluent-debug +5 -0
  21. data/bin/fluent-gem +9 -0
  22. data/bin/fluent-plugin-config-format +5 -0
  23. data/bin/fluent-plugin-generate +5 -0
  24. data/bin/fluentd +15 -0
  25. data/code-of-conduct.md +3 -0
  26. data/docs/SECURITY_AUDIT.pdf +0 -0
  27. data/example/copy_roundrobin.conf +39 -0
  28. data/example/counter.conf +18 -0
  29. data/example/filter_stdout.conf +22 -0
  30. data/example/in_forward.conf +14 -0
  31. data/example/in_forward_client.conf +37 -0
  32. data/example/in_forward_shared_key.conf +15 -0
  33. data/example/in_forward_tls.conf +14 -0
  34. data/example/in_forward_users.conf +24 -0
  35. data/example/in_forward_workers.conf +21 -0
  36. data/example/in_http.conf +16 -0
  37. data/example/in_out_forward.conf +17 -0
  38. data/example/in_sample_blocks.conf +17 -0
  39. data/example/in_sample_with_compression.conf +23 -0
  40. data/example/in_syslog.conf +15 -0
  41. data/example/in_tail.conf +14 -0
  42. data/example/in_tcp.conf +13 -0
  43. data/example/in_udp.conf +13 -0
  44. data/example/logevents.conf +25 -0
  45. data/example/multi_filters.conf +61 -0
  46. data/example/out_copy.conf +20 -0
  47. data/example/out_exec_filter.conf +42 -0
  48. data/example/out_file.conf +13 -0
  49. data/example/out_forward.conf +35 -0
  50. data/example/out_forward_buf_file.conf +23 -0
  51. data/example/out_forward_client.conf +109 -0
  52. data/example/out_forward_heartbeat_none.conf +16 -0
  53. data/example/out_forward_sd.conf +17 -0
  54. data/example/out_forward_shared_key.conf +36 -0
  55. data/example/out_forward_tls.conf +18 -0
  56. data/example/out_forward_users.conf +65 -0
  57. data/example/out_null.conf +36 -0
  58. data/example/sd.yaml +8 -0
  59. data/example/secondary_file.conf +42 -0
  60. data/example/suppress_config_dump.conf +7 -0
  61. data/example/v0_12_filter.conf +78 -0
  62. data/example/v1_literal_example.conf +36 -0
  63. data/example/worker_section.conf +36 -0
  64. data/fluent.conf +139 -0
  65. data/lib/fluent/agent.rb +168 -0
  66. data/lib/fluent/capability.rb +87 -0
  67. data/lib/fluent/clock.rb +66 -0
  68. data/lib/fluent/command/binlog_reader.rb +244 -0
  69. data/lib/fluent/command/bundler_injection.rb +45 -0
  70. data/lib/fluent/command/ca_generate.rb +184 -0
  71. data/lib/fluent/command/cap_ctl.rb +174 -0
  72. data/lib/fluent/command/cat.rb +365 -0
  73. data/lib/fluent/command/ctl.rb +180 -0
  74. data/lib/fluent/command/debug.rb +103 -0
  75. data/lib/fluent/command/fluentd.rb +385 -0
  76. data/lib/fluent/command/plugin_config_formatter.rb +308 -0
  77. data/lib/fluent/command/plugin_generator.rb +365 -0
  78. data/lib/fluent/compat/call_super_mixin.rb +76 -0
  79. data/lib/fluent/compat/detach_process_mixin.rb +33 -0
  80. data/lib/fluent/compat/exec_util.rb +144 -0
  81. data/lib/fluent/compat/file_util.rb +54 -0
  82. data/lib/fluent/compat/filter.rb +68 -0
  83. data/lib/fluent/compat/formatter.rb +117 -0
  84. data/lib/fluent/compat/formatter_utils.rb +85 -0
  85. data/lib/fluent/compat/handle_tag_and_time_mixin.rb +62 -0
  86. data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
  87. data/lib/fluent/compat/input.rb +49 -0
  88. data/lib/fluent/compat/output.rb +721 -0
  89. data/lib/fluent/compat/output_chain.rb +60 -0
  90. data/lib/fluent/compat/parser.rb +310 -0
  91. data/lib/fluent/compat/parser_utils.rb +40 -0
  92. data/lib/fluent/compat/propagate_default.rb +62 -0
  93. data/lib/fluent/compat/record_filter_mixin.rb +34 -0
  94. data/lib/fluent/compat/set_tag_key_mixin.rb +50 -0
  95. data/lib/fluent/compat/set_time_key_mixin.rb +69 -0
  96. data/lib/fluent/compat/socket_util.rb +165 -0
  97. data/lib/fluent/compat/string_util.rb +34 -0
  98. data/lib/fluent/compat/structured_format_mixin.rb +26 -0
  99. data/lib/fluent/compat/type_converter.rb +90 -0
  100. data/lib/fluent/config/basic_parser.rb +122 -0
  101. data/lib/fluent/config/configure_proxy.rb +424 -0
  102. data/lib/fluent/config/dsl.rb +152 -0
  103. data/lib/fluent/config/element.rb +265 -0
  104. data/lib/fluent/config/error.rb +44 -0
  105. data/lib/fluent/config/literal_parser.rb +305 -0
  106. data/lib/fluent/config/parser.rb +119 -0
  107. data/lib/fluent/config/section.rb +272 -0
  108. data/lib/fluent/config/types.rb +257 -0
  109. data/lib/fluent/config/v1_parser.rb +200 -0
  110. data/lib/fluent/config/yaml_parser/fluent_value.rb +47 -0
  111. data/lib/fluent/config/yaml_parser/loader.rb +124 -0
  112. data/lib/fluent/config/yaml_parser/parser.rb +179 -0
  113. data/lib/fluent/config/yaml_parser/section_builder.rb +107 -0
  114. data/lib/fluent/config/yaml_parser.rb +56 -0
  115. data/lib/fluent/config.rb +89 -0
  116. data/lib/fluent/configurable.rb +202 -0
  117. data/lib/fluent/counter/base_socket.rb +44 -0
  118. data/lib/fluent/counter/client.rb +297 -0
  119. data/lib/fluent/counter/error.rb +86 -0
  120. data/lib/fluent/counter/mutex_hash.rb +163 -0
  121. data/lib/fluent/counter/server.rb +273 -0
  122. data/lib/fluent/counter/store.rb +205 -0
  123. data/lib/fluent/counter/validator.rb +145 -0
  124. data/lib/fluent/counter.rb +23 -0
  125. data/lib/fluent/daemon.rb +14 -0
  126. data/lib/fluent/daemonizer.rb +88 -0
  127. data/lib/fluent/engine.rb +269 -0
  128. data/lib/fluent/env.rb +45 -0
  129. data/lib/fluent/error.rb +37 -0
  130. data/lib/fluent/event.rb +369 -0
  131. data/lib/fluent/event_router.rb +315 -0
  132. data/lib/fluent/ext_monitor_require.rb +28 -0
  133. data/lib/fluent/file_wrapper.rb +137 -0
  134. data/lib/fluent/filter.rb +21 -0
  135. data/lib/fluent/fluent_log_event_router.rb +139 -0
  136. data/lib/fluent/formatter.rb +23 -0
  137. data/lib/fluent/input.rb +21 -0
  138. data/lib/fluent/label.rb +46 -0
  139. data/lib/fluent/load.rb +33 -0
  140. data/lib/fluent/log/console_adapter.rb +66 -0
  141. data/lib/fluent/log.rb +775 -0
  142. data/lib/fluent/match.rb +187 -0
  143. data/lib/fluent/mixin.rb +31 -0
  144. data/lib/fluent/msgpack_factory.rb +111 -0
  145. data/lib/fluent/oj_options.rb +61 -0
  146. data/lib/fluent/output.rb +29 -0
  147. data/lib/fluent/output_chain.rb +23 -0
  148. data/lib/fluent/parser.rb +23 -0
  149. data/lib/fluent/plugin/bare_output.rb +88 -0
  150. data/lib/fluent/plugin/base.rb +219 -0
  151. data/lib/fluent/plugin/buf_file.rb +256 -0
  152. data/lib/fluent/plugin/buf_file_single.rb +272 -0
  153. data/lib/fluent/plugin/buf_memory.rb +34 -0
  154. data/lib/fluent/plugin/buffer/chunk.rb +313 -0
  155. data/lib/fluent/plugin/buffer/file_chunk.rb +432 -0
  156. data/lib/fluent/plugin/buffer/file_single_chunk.rb +325 -0
  157. data/lib/fluent/plugin/buffer/memory_chunk.rb +91 -0
  158. data/lib/fluent/plugin/buffer.rb +1063 -0
  159. data/lib/fluent/plugin/compressable.rb +87 -0
  160. data/lib/fluent/plugin/exec_util.rb +22 -0
  161. data/lib/fluent/plugin/extractor.rb +132 -0
  162. data/lib/fluent/plugin/file_util.rb +22 -0
  163. data/lib/fluent/plugin/filter.rb +119 -0
  164. data/lib/fluent/plugin/filter_grep.rb +189 -0
  165. data/lib/fluent/plugin/filter_parser.rb +124 -0
  166. data/lib/fluent/plugin/filter_record_transformer.rb +325 -0
  167. data/lib/fluent/plugin/filter_stdout.rb +53 -0
  168. data/lib/fluent/plugin/formatter.rb +75 -0
  169. data/lib/fluent/plugin/formatter_csv.rb +92 -0
  170. data/lib/fluent/plugin/formatter_hash.rb +35 -0
  171. data/lib/fluent/plugin/formatter_json.rb +62 -0
  172. data/lib/fluent/plugin/formatter_ltsv.rb +44 -0
  173. data/lib/fluent/plugin/formatter_msgpack.rb +33 -0
  174. data/lib/fluent/plugin/formatter_out_file.rb +55 -0
  175. data/lib/fluent/plugin/formatter_single_value.rb +36 -0
  176. data/lib/fluent/plugin/formatter_stdout.rb +76 -0
  177. data/lib/fluent/plugin/formatter_tsv.rb +40 -0
  178. data/lib/fluent/plugin/in_debug_agent.rb +71 -0
  179. data/lib/fluent/plugin/in_dummy.rb +18 -0
  180. data/lib/fluent/plugin/in_exec.rb +124 -0
  181. data/lib/fluent/plugin/in_forward.rb +489 -0
  182. data/lib/fluent/plugin/in_gc_stat.rb +72 -0
  183. data/lib/fluent/plugin/in_http.rb +737 -0
  184. data/lib/fluent/plugin/in_monitor_agent.rb +406 -0
  185. data/lib/fluent/plugin/in_object_space.rb +93 -0
  186. data/lib/fluent/plugin/in_sample.rb +148 -0
  187. data/lib/fluent/plugin/in_syslog.rb +346 -0
  188. data/lib/fluent/plugin/in_tail/compatibility.rb +111 -0
  189. data/lib/fluent/plugin/in_tail/dir_watcher.rb +713 -0
  190. data/lib/fluent/plugin/in_tail/group_watch.rb +204 -0
  191. data/lib/fluent/plugin/in_tail/io_handler.rb +391 -0
  192. data/lib/fluent/plugin/in_tail/line_feeder.rb +230 -0
  193. data/lib/fluent/plugin/in_tail/position_file.rb +269 -0
  194. data/lib/fluent/plugin/in_tail/stat_watcher.rb +52 -0
  195. data/lib/fluent/plugin/in_tail/tail_watcher.rb +276 -0
  196. data/lib/fluent/plugin/in_tail/worker_pool.rb +298 -0
  197. data/lib/fluent/plugin/in_tail.rb +917 -0
  198. data/lib/fluent/plugin/in_tcp.rb +230 -0
  199. data/lib/fluent/plugin/in_udp.rb +101 -0
  200. data/lib/fluent/plugin/in_unix.rb +197 -0
  201. data/lib/fluent/plugin/input.rb +71 -0
  202. data/lib/fluent/plugin/metrics.rb +119 -0
  203. data/lib/fluent/plugin/metrics_local.rb +96 -0
  204. data/lib/fluent/plugin/multi_output.rb +179 -0
  205. data/lib/fluent/plugin/out_buffer.rb +40 -0
  206. data/lib/fluent/plugin/out_copy.rb +120 -0
  207. data/lib/fluent/plugin/out_exec.rb +105 -0
  208. data/lib/fluent/plugin/out_exec_filter.rb +319 -0
  209. data/lib/fluent/plugin/out_file.rb +371 -0
  210. data/lib/fluent/plugin/out_forward/ack_handler.rb +176 -0
  211. data/lib/fluent/plugin/out_forward/connection_manager.rb +131 -0
  212. data/lib/fluent/plugin/out_forward/error.rb +28 -0
  213. data/lib/fluent/plugin/out_forward/failure_detector.rb +84 -0
  214. data/lib/fluent/plugin/out_forward/handshake_protocol.rb +125 -0
  215. data/lib/fluent/plugin/out_forward/load_balancer.rb +114 -0
  216. data/lib/fluent/plugin/out_forward/socket_cache.rb +177 -0
  217. data/lib/fluent/plugin/out_forward.rb +865 -0
  218. data/lib/fluent/plugin/out_http.rb +419 -0
  219. data/lib/fluent/plugin/out_null.rb +74 -0
  220. data/lib/fluent/plugin/out_relabel.rb +32 -0
  221. data/lib/fluent/plugin/out_roundrobin.rb +84 -0
  222. data/lib/fluent/plugin/out_secondary_file.rb +148 -0
  223. data/lib/fluent/plugin/out_stdout.rb +81 -0
  224. data/lib/fluent/plugin/out_stream.rb +130 -0
  225. data/lib/fluent/plugin/output.rb +1688 -0
  226. data/lib/fluent/plugin/owned_by_mixin.rb +41 -0
  227. data/lib/fluent/plugin/parser.rb +274 -0
  228. data/lib/fluent/plugin/parser_apache.rb +28 -0
  229. data/lib/fluent/plugin/parser_apache2.rb +88 -0
  230. data/lib/fluent/plugin/parser_apache_error.rb +26 -0
  231. data/lib/fluent/plugin/parser_csv.rb +124 -0
  232. data/lib/fluent/plugin/parser_json.rb +118 -0
  233. data/lib/fluent/plugin/parser_ltsv.rb +49 -0
  234. data/lib/fluent/plugin/parser_msgpack.rb +72 -0
  235. data/lib/fluent/plugin/parser_multiline.rb +152 -0
  236. data/lib/fluent/plugin/parser_nginx.rb +28 -0
  237. data/lib/fluent/plugin/parser_none.rb +36 -0
  238. data/lib/fluent/plugin/parser_regexp.rb +68 -0
  239. data/lib/fluent/plugin/parser_syslog.rb +543 -0
  240. data/lib/fluent/plugin/parser_tsv.rb +47 -0
  241. data/lib/fluent/plugin/sd_file.rb +157 -0
  242. data/lib/fluent/plugin/sd_srv.rb +135 -0
  243. data/lib/fluent/plugin/sd_static.rb +58 -0
  244. data/lib/fluent/plugin/service_discovery.rb +65 -0
  245. data/lib/fluent/plugin/socket_util.rb +22 -0
  246. data/lib/fluent/plugin/storage.rb +84 -0
  247. data/lib/fluent/plugin/storage_local.rb +166 -0
  248. data/lib/fluent/plugin/string_util.rb +22 -0
  249. data/lib/fluent/plugin.rb +206 -0
  250. data/lib/fluent/plugin_helper/cert_option.rb +199 -0
  251. data/lib/fluent/plugin_helper/child_process.rb +369 -0
  252. data/lib/fluent/plugin_helper/compat_parameters.rb +343 -0
  253. data/lib/fluent/plugin_helper/counter.rb +51 -0
  254. data/lib/fluent/plugin_helper/event_emitter.rb +112 -0
  255. data/lib/fluent/plugin_helper/event_loop.rb +170 -0
  256. data/lib/fluent/plugin_helper/extract.rb +104 -0
  257. data/lib/fluent/plugin_helper/formatter.rb +147 -0
  258. data/lib/fluent/plugin_helper/http_server/app.rb +81 -0
  259. data/lib/fluent/plugin_helper/http_server/methods.rb +35 -0
  260. data/lib/fluent/plugin_helper/http_server/request.rb +53 -0
  261. data/lib/fluent/plugin_helper/http_server/router.rb +54 -0
  262. data/lib/fluent/plugin_helper/http_server/server.rb +116 -0
  263. data/lib/fluent/plugin_helper/http_server/ssl_context_builder.rb +41 -0
  264. data/lib/fluent/plugin_helper/http_server.rb +129 -0
  265. data/lib/fluent/plugin_helper/inject.rb +154 -0
  266. data/lib/fluent/plugin_helper/metrics.rb +136 -0
  267. data/lib/fluent/plugin_helper/parser.rb +147 -0
  268. data/lib/fluent/plugin_helper/record_accessor.rb +207 -0
  269. data/lib/fluent/plugin_helper/retry_state.rb +219 -0
  270. data/lib/fluent/plugin_helper/server.rb +840 -0
  271. data/lib/fluent/plugin_helper/service_discovery/manager.rb +146 -0
  272. data/lib/fluent/plugin_helper/service_discovery/round_robin_balancer.rb +43 -0
  273. data/lib/fluent/plugin_helper/service_discovery.rb +125 -0
  274. data/lib/fluent/plugin_helper/socket.rb +288 -0
  275. data/lib/fluent/plugin_helper/socket_option.rb +98 -0
  276. data/lib/fluent/plugin_helper/storage.rb +349 -0
  277. data/lib/fluent/plugin_helper/thread.rb +180 -0
  278. data/lib/fluent/plugin_helper/timer.rb +92 -0
  279. data/lib/fluent/plugin_helper.rb +75 -0
  280. data/lib/fluent/plugin_id.rb +93 -0
  281. data/lib/fluent/process.rb +22 -0
  282. data/lib/fluent/registry.rb +117 -0
  283. data/lib/fluent/root_agent.rb +468 -0
  284. data/lib/fluent/rpc.rb +95 -0
  285. data/lib/fluent/source_only_buffer_agent.rb +102 -0
  286. data/lib/fluent/static_config_analysis.rb +195 -0
  287. data/lib/fluent/supervisor.rb +1347 -0
  288. data/lib/fluent/system_config.rb +213 -0
  289. data/lib/fluent/test/base.rb +83 -0
  290. data/lib/fluent/test/driver/base.rb +231 -0
  291. data/lib/fluent/test/driver/base_owned.rb +83 -0
  292. data/lib/fluent/test/driver/base_owner.rb +135 -0
  293. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  294. data/lib/fluent/test/driver/filter.rb +61 -0
  295. data/lib/fluent/test/driver/formatter.rb +30 -0
  296. data/lib/fluent/test/driver/input.rb +31 -0
  297. data/lib/fluent/test/driver/multi_output.rb +53 -0
  298. data/lib/fluent/test/driver/output.rb +102 -0
  299. data/lib/fluent/test/driver/parser.rb +30 -0
  300. data/lib/fluent/test/driver/storage.rb +30 -0
  301. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  302. data/lib/fluent/test/filter_test.rb +77 -0
  303. data/lib/fluent/test/formatter_test.rb +65 -0
  304. data/lib/fluent/test/helpers.rb +138 -0
  305. data/lib/fluent/test/input_test.rb +174 -0
  306. data/lib/fluent/test/log.rb +79 -0
  307. data/lib/fluent/test/output_test.rb +156 -0
  308. data/lib/fluent/test/parser_test.rb +70 -0
  309. data/lib/fluent/test/startup_shutdown.rb +44 -0
  310. data/lib/fluent/test.rb +61 -0
  311. data/lib/fluent/time.rb +513 -0
  312. data/lib/fluent/timezone.rb +171 -0
  313. data/lib/fluent/tls.rb +105 -0
  314. data/lib/fluent/unique_id.rb +39 -0
  315. data/lib/fluent/variable_store.rb +40 -0
  316. data/lib/fluent/version.rb +21 -0
  317. data/lib/fluent/win32api.rb +38 -0
  318. data/lib/fluent/winsvc.rb +130 -0
  319. data/templates/new_gem/.gitignore +8 -0
  320. data/templates/new_gem/Gemfile +3 -0
  321. data/templates/new_gem/README.md.erb +43 -0
  322. data/templates/new_gem/Rakefile +13 -0
  323. data/templates/new_gem/fluent-plugin.gemspec.erb +28 -0
  324. data/templates/new_gem/lib/fluent/plugin/filter.rb.erb +14 -0
  325. data/templates/new_gem/lib/fluent/plugin/formatter.rb.erb +14 -0
  326. data/templates/new_gem/lib/fluent/plugin/input.rb.erb +11 -0
  327. data/templates/new_gem/lib/fluent/plugin/output.rb.erb +11 -0
  328. data/templates/new_gem/lib/fluent/plugin/parser.rb.erb +15 -0
  329. data/templates/new_gem/lib/fluent/plugin/storage.rb.erb +40 -0
  330. data/templates/new_gem/test/helper.rb.erb +7 -0
  331. data/templates/new_gem/test/plugin/test_filter.rb.erb +18 -0
  332. data/templates/new_gem/test/plugin/test_formatter.rb.erb +18 -0
  333. data/templates/new_gem/test/plugin/test_input.rb.erb +18 -0
  334. data/templates/new_gem/test/plugin/test_output.rb.erb +18 -0
  335. data/templates/new_gem/test/plugin/test_parser.rb.erb +18 -0
  336. data/templates/new_gem/test/plugin/test_storage.rb.erb +18 -0
  337. data/templates/plugin_config_formatter/param.md-compact.erb +25 -0
  338. data/templates/plugin_config_formatter/param.md-table.erb +10 -0
  339. data/templates/plugin_config_formatter/param.md.erb +34 -0
  340. data/templates/plugin_config_formatter/section.md.erb +12 -0
  341. metadata +996 -0
@@ -0,0 +1,204 @@
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 TailInput < Fluent::Plugin::Input
21
+ module GroupWatchParams
22
+ include Fluent::Configurable
23
+
24
+ DEFAULT_KEY = /.*/
25
+ DEFAULT_LIMIT = -1
26
+ REGEXP_JOIN = "_"
27
+
28
+ config_section :group, param_name: :group, required: false, multi: false do
29
+ desc 'Regex for extracting group\'s metadata'
30
+ config_param :pattern,
31
+ :regexp,
32
+ default: /^\/var\/log\/containers\/(?<podname>[a-z0-9]([-a-z0-9]*[a-z0-9])?(\/[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)_(?<namespace>[^_]+)_(?<container>.+)-(?<docker_id>[a-z0-9]{64})\.log$/
33
+
34
+ desc 'Period of time in which the group_line_limit is applied'
35
+ config_param :rate_period, :time, default: 5
36
+
37
+ config_section :rule, param_name: :rule, required: true, multi: true do
38
+ desc 'Key-value pairs for grouping'
39
+ config_param :match, :hash, value_type: :regexp, default: { namespace: [DEFAULT_KEY], podname: [DEFAULT_KEY] }
40
+ desc 'Maximum number of log lines allowed per group over a period of rate_period'
41
+ config_param :limit, :integer, default: DEFAULT_LIMIT
42
+ end
43
+ end
44
+ end
45
+
46
+ module GroupWatch
47
+ def self.included(mod)
48
+ mod.include GroupWatchParams
49
+ end
50
+
51
+ attr_reader :group_watchers, :default_group_key
52
+
53
+ def initialize
54
+ super
55
+ @group_watchers = {}
56
+ @group_keys = nil
57
+ @default_group_key = nil
58
+ end
59
+
60
+ def configure(conf)
61
+ super
62
+
63
+ unless @group.nil?
64
+ ## Ensuring correct time period syntax
65
+ @group.rule.each { |rule|
66
+ raise "Metadata Group Limit >= DEFAULT_LIMIT" unless rule.limit >= GroupWatchParams::DEFAULT_LIMIT
67
+ }
68
+
69
+ @group_keys = Regexp.compile(@group.pattern).named_captures.keys
70
+ @default_group_key = ([GroupWatchParams::DEFAULT_KEY] * @group_keys.length).join(GroupWatchParams::REGEXP_JOIN)
71
+
72
+ ## Ensures that "specific" rules (with larger number of `rule.match` keys)
73
+ ## have a higher priority against "generic" rules (with less number of `rule.match` keys).
74
+ ## This will be helpful when a file satisfies more than one rule.
75
+ @group.rule.sort_by! { |rule| -rule.match.length() }
76
+ construct_groupwatchers
77
+ @group_watchers[@default_group_key] ||= GroupWatcher.new(@group.rate_period, GroupWatchParams::DEFAULT_LIMIT)
78
+ end
79
+ end
80
+
81
+ def add_path_to_group_watcher(path, watcher)
82
+ return nil if @group.nil?
83
+ group_watcher = find_group_from_metadata(path)
84
+ group_watcher.add(path, watcher)
85
+ group_watcher
86
+ end
87
+
88
+ def construct_group_key(named_captures)
89
+ match_rule = []
90
+ @group_keys.each { |key|
91
+ match_rule.append(named_captures.fetch(key, GroupWatchParams::DEFAULT_KEY))
92
+ }
93
+ match_rule = match_rule.join(GroupWatchParams::REGEXP_JOIN)
94
+
95
+ match_rule
96
+ end
97
+
98
+ def construct_groupwatchers
99
+ @group.rule.each { |rule|
100
+ match_rule = construct_group_key(rule.match)
101
+ @group_watchers[match_rule] ||= GroupWatcher.new(@group.rate_period, rule.limit)
102
+ }
103
+ end
104
+
105
+ def find_group(metadata)
106
+ metadata_key = construct_group_key(metadata)
107
+ gw_key = @group_watchers.keys.find { |regexp| metadata_key.match?(regexp) && regexp != @default_group_key }
108
+ gw_key ||= @default_group_key
109
+
110
+ @group_watchers[gw_key]
111
+ end
112
+
113
+ def find_group_from_metadata(path)
114
+ begin
115
+ metadata = @group.pattern.match(path).named_captures
116
+ group_watcher = find_group(metadata)
117
+ rescue
118
+ log.warn "Cannot find group from metadata, Adding file in the default group"
119
+ group_watcher = @group_watchers[@default_group_key]
120
+ end
121
+
122
+ group_watcher
123
+ end
124
+ end
125
+
126
+ class GroupWatcher
127
+ attr_accessor :current_paths, :limit, :number_lines_read, :start_reading_time, :rate_period
128
+
129
+ FileCounter = Struct.new(
130
+ :number_lines_read,
131
+ :start_reading_time,
132
+ :watchers,
133
+ )
134
+
135
+ def initialize(rate_period = 60, limit = -1)
136
+ @current_paths = {}
137
+ @rate_period = rate_period
138
+ @limit = limit
139
+ end
140
+
141
+ def add(path, watcher)
142
+ (@current_paths[path] ||= FileCounter.new(0, nil, Set.new)).watchers << watcher
143
+ end
144
+
145
+ def include?(path)
146
+ @current_paths.key?(path)
147
+ end
148
+
149
+ def size
150
+ @current_paths.size
151
+ end
152
+
153
+ def delete(path, watcher)
154
+ counter = @current_paths[path]
155
+ return unless counter
156
+ counter.watchers.delete(watcher)
157
+ @current_paths.delete(path) if counter.watchers.empty?
158
+ end
159
+
160
+ def update_reading_time(path)
161
+ @current_paths[path].start_reading_time ||= Fluent::Clock.now
162
+ end
163
+
164
+ def update_lines_read(path, value)
165
+ @current_paths[path].number_lines_read += value
166
+ end
167
+
168
+ def reset_counter(path)
169
+ @current_paths[path].start_reading_time = nil
170
+ @current_paths[path].number_lines_read = 0
171
+ end
172
+
173
+ def time_spent_reading(path)
174
+ Fluent::Clock.now - @current_paths[path].start_reading_time
175
+ end
176
+
177
+ def limit_time_period_reached?(path)
178
+ time_spent_reading(path) < @rate_period
179
+ end
180
+
181
+ def limit_lines_reached?(path)
182
+ return true unless include?(path)
183
+ return true if @limit == 0
184
+
185
+ return false if @limit < 0
186
+ # Give every path at least one line. With more paths than the limit, the integer division
187
+ # leaves no allotment, and a path that has not started reading yet has no start time to compare.
188
+ return false if @current_paths[path].number_lines_read < [@limit / size, 1].max
189
+
190
+ # update_reading_time(path)
191
+ if limit_time_period_reached?(path) # Exceeds limit
192
+ true
193
+ else # Does not exceed limit
194
+ reset_counter(path)
195
+ false
196
+ end
197
+ end
198
+
199
+ def to_s
200
+ super + " current_paths: #{@current_paths} rate_period: #{@rate_period} limit: #{@limit}"
201
+ end
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,391 @@
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
+ require 'fluent/clock'
19
+ require 'fluent/file_wrapper'
20
+
21
+ module Fluent::Plugin
22
+ class TailInput < Fluent::Plugin::Input
23
+ class TailWatcher
24
+ class FIFO
25
+ def initialize(encoding, log, max_line_size=nil, encoding_to_convert=nil)
26
+ @buffer = ''.force_encoding(encoding)
27
+ @eol = "\n".encode(encoding).freeze
28
+ @encoding_to_convert = encoding_to_convert
29
+ @max_line_size = max_line_size
30
+ @skip_current_line = false
31
+ @skipping_current_line_bytesize = 0
32
+ @log = log
33
+ end
34
+
35
+ attr_reader :buffer, :max_line_size
36
+
37
+ def <<(chunk)
38
+ @buffer << chunk
39
+ end
40
+
41
+ def convert(s)
42
+ if @encoding_to_convert
43
+ s.encode!(@encoding_to_convert)
44
+ else
45
+ s
46
+ end
47
+ rescue
48
+ s.encode!(@encoding_to_convert, :invalid => :replace, :undef => :replace)
49
+ end
50
+
51
+ def read_lines(lines)
52
+ idx = @buffer.index(@eol)
53
+ has_skipped_line = false
54
+
55
+ until idx.nil?
56
+ # Using freeze and slice is faster than slice!
57
+ # See https://github.com/fluent/fluentd/pull/2527
58
+ @buffer.freeze
59
+ slice_position = idx + 1
60
+ rbuf = @buffer.slice(0, slice_position)
61
+ @buffer = @buffer.slice(slice_position, @buffer.size - slice_position)
62
+ idx = @buffer.index(@eol)
63
+
64
+ is_long_line = @max_line_size && (
65
+ @skip_current_line || rbuf.bytesize > @max_line_size
66
+ )
67
+
68
+ if is_long_line
69
+ @log.warn "received line length is longer than #{@max_line_size}"
70
+ if @skip_current_line
71
+ @log.debug("The continuing line is finished. Finally discarded data: ") { convert(rbuf).chomp }
72
+ else
73
+ @log.debug("skipped line: ") { convert(rbuf).chomp }
74
+ end
75
+ has_skipped_line = true
76
+ @skip_current_line = false
77
+ @skipping_current_line_bytesize = 0
78
+ next
79
+ end
80
+
81
+ lines << convert(rbuf)
82
+ end
83
+
84
+ is_long_current_line = @max_line_size && (
85
+ @skip_current_line || @buffer.bytesize > @max_line_size
86
+ )
87
+
88
+ if is_long_current_line
89
+ @log.debug(
90
+ "The continuing current line length is longer than #{@max_line_size}." +
91
+ " The received data will be discarded until this line is finished." +
92
+ " Discarded data: "
93
+ ) { convert(@buffer).chomp }
94
+ @skip_current_line = true
95
+ @skipping_current_line_bytesize += @buffer.bytesize
96
+ @buffer.clear
97
+ end
98
+
99
+ return has_skipped_line
100
+ end
101
+
102
+ def reading_bytesize
103
+ return @skipping_current_line_bytesize if @skip_current_line
104
+ @buffer.bytesize
105
+ end
106
+ end
107
+
108
+ class IOHandler
109
+ BYTES_TO_READ = 64 * 1024
110
+ SHUTDOWN_TIMEOUT = 5
111
+ ASYNC_PENDING = :async_pending
112
+
113
+ attr_accessor :shutdown_timeout
114
+
115
+ def initialize(watcher, path:, read_lines_limit:, read_bytes_limit_per_second:, max_line_size: nil, log:, open_on_every_update:, encoding: Encoding::ASCII_8BIT, encoding_to_convert: nil, metrics:, &receive_lines)
116
+ @watcher = watcher
117
+ @path = path
118
+ @read_lines_limit = read_lines_limit
119
+ @read_bytes_limit_per_second = read_bytes_limit_per_second
120
+ @receive_lines = receive_lines
121
+ @open_on_every_update = open_on_every_update
122
+ @encoding = encoding
123
+ @fifo = FIFO.new(encoding, log, max_line_size, encoding_to_convert)
124
+ @lines = []
125
+ @io = nil
126
+ @notify_mutex = Mutex.new
127
+ @log = log
128
+ @start_reading_time = nil
129
+ @number_bytes_read = 0
130
+ @shutdown_start_time = nil
131
+ @shutdown_timeout = SHUTDOWN_TIMEOUT
132
+ @shutdown_mutex = Mutex.new
133
+ @eof = false
134
+ @metrics = metrics
135
+ @async_pending = false
136
+ @notify_pending = false
137
+ @pending_position = nil
138
+ @pending_read_more = false
139
+
140
+ @log.info "following tail of #{@path}"
141
+ end
142
+
143
+ def group_watcher
144
+ @watcher.group_watcher
145
+ end
146
+
147
+ def on_notify
148
+ @notify_mutex.synchronize { handle_notify }
149
+ end
150
+
151
+ def ready_to_shutdown(shutdown_start_time = nil)
152
+ @shutdown_mutex.synchronize {
153
+ @shutdown_start_time =
154
+ shutdown_start_time || Fluent::Clock.now
155
+ }
156
+ end
157
+
158
+ def close
159
+ if @io && !@io.closed?
160
+ @io.close
161
+ @io = nil
162
+ @metrics.closed.inc
163
+ end
164
+ end
165
+
166
+ def opened?
167
+ !!@io
168
+ end
169
+
170
+ def eof?
171
+ @eof
172
+ end
173
+
174
+ def drained?
175
+ @eof && @lines.empty? && !@async_pending
176
+ end
177
+
178
+ def pending?
179
+ @async_pending
180
+ end
181
+
182
+ # Completes a receive callback that returned ASYNC_PENDING. The caller
183
+ # must invoke TailWatcher#on_notify when this returns true.
184
+ def complete_async(success)
185
+ @notify_mutex.synchronize do
186
+ raise 'no asynchronous receive is pending' unless @async_pending
187
+
188
+ begin
189
+ if success
190
+ @watcher.pe.update_pos(@pending_position)
191
+ @lines.clear
192
+ end
193
+ should_notify = (success && @pending_read_more) || @notify_pending
194
+ @pending_read_more = false if success
195
+ should_notify
196
+ rescue => error
197
+ @log.error error.to_s
198
+ @log.error_backtrace
199
+ @notify_pending
200
+ ensure
201
+ @async_pending = false
202
+ @notify_pending = false
203
+ @pending_position = nil
204
+ end
205
+ end
206
+ end
207
+
208
+ private
209
+
210
+ def limit_bytes_per_second_reached?
211
+ return false if @read_bytes_limit_per_second < 0 # not enabled by conf
212
+ return false if @number_bytes_read < @read_bytes_limit_per_second
213
+
214
+ @start_reading_time ||= Fluent::Clock.now
215
+ time_spent_reading = Fluent::Clock.now - @start_reading_time
216
+ @log.debug("time_spent_reading: #{time_spent_reading} #{ @watcher.path}")
217
+
218
+ if time_spent_reading < 1
219
+ true
220
+ else
221
+ @start_reading_time = nil
222
+ @number_bytes_read = 0
223
+ false
224
+ end
225
+ end
226
+
227
+ def should_shutdown_now?
228
+ # Ensure to read all remaining lines, but abort immediately if it
229
+ # seems to take too long time.
230
+ @shutdown_mutex.synchronize {
231
+ return false if @shutdown_start_time.nil?
232
+ return Fluent::Clock.now - @shutdown_start_time > @shutdown_timeout
233
+ }
234
+ end
235
+
236
+ def handle_notify
237
+ if @async_pending
238
+ @notify_pending = true
239
+ return
240
+ end
241
+
242
+ # A notification may arrive while a rejected batch is waiting for capacity.
243
+ @pending_read_more = true unless @lines.empty?
244
+
245
+ if limit_bytes_per_second_reached? || group_watcher&.limit_lines_reached?(@path)
246
+ @metrics.throttled.inc
247
+ return
248
+ end
249
+
250
+ with_io do |io|
251
+ iobuf = ''.force_encoding(@encoding)
252
+ begin
253
+ read_more = false
254
+ has_skipped_line = false
255
+
256
+ if !io.nil? && @lines.empty?
257
+ begin
258
+ while true
259
+ @start_reading_time ||= Fluent::Clock.now
260
+ group_watcher&.update_reading_time(@path)
261
+
262
+ data = io.readpartial(BYTES_TO_READ, iobuf)
263
+ @eof = false
264
+ @number_bytes_read += data.bytesize
265
+ @fifo << data
266
+
267
+ n_lines_before_read = @lines.size
268
+ has_skipped_line = @fifo.read_lines(@lines) || has_skipped_line
269
+ group_watcher&.update_lines_read(@path, @lines.size - n_lines_before_read)
270
+
271
+ group_watcher_limit = group_watcher&.limit_lines_reached?(@path)
272
+ @log.debug "Reading Limit exceeded #{@path} #{group_watcher.number_lines_read}" if group_watcher_limit
273
+
274
+ if group_watcher_limit || limit_bytes_per_second_reached? || should_shutdown_now?
275
+ # Just get out from tailing loop.
276
+ @metrics.throttled.inc if group_watcher_limit || limit_bytes_per_second_reached?
277
+ read_more = false
278
+ break
279
+ end
280
+
281
+ if @lines.size >= @read_lines_limit
282
+ # not to use too much memory in case the file is very large
283
+ read_more = true
284
+ break
285
+ end
286
+ end
287
+ rescue EOFError
288
+ @eof = true
289
+ ensure
290
+ iobuf.clear
291
+ end
292
+ end
293
+
294
+ if @lines.empty?
295
+ @watcher.pe.update_pos(io.pos - @fifo.reading_bytesize) if has_skipped_line
296
+ else
297
+ received = @receive_lines.call(@lines, @watcher)
298
+ if received == ASYNC_PENDING
299
+ @pending_position = io.pos - @fifo.reading_bytesize
300
+ @pending_read_more ||= read_more
301
+ @async_pending = true
302
+ read_more = false
303
+ elsif received
304
+ @watcher.pe.update_pos(io.pos - @fifo.reading_bytesize)
305
+ @lines.clear
306
+ @pending_read_more = false
307
+ else
308
+ # A rejected worker submission must retain the continuation for retry.
309
+ @pending_read_more ||= read_more
310
+ read_more = false
311
+ end
312
+ end
313
+ end while read_more
314
+ end
315
+ end
316
+
317
+ def open
318
+ io = Fluent::FileWrapper.open(@path)
319
+ io.seek(@watcher.pe.read_pos + @fifo.reading_bytesize)
320
+ @metrics.opened.inc
321
+ io
322
+ rescue RangeError
323
+ io.close if io
324
+ raise WatcherSetupError, "seek error with #{@path}: file position = #{@watcher.pe.read_pos.to_s(16)}, reading bytesize = #{@fifo.reading_bytesize.to_s(16)}"
325
+ rescue Errno::EACCES => e
326
+ @log.warn "#{e}"
327
+ nil
328
+ rescue Errno::ENOENT
329
+ nil
330
+ end
331
+
332
+ def with_io
333
+ if @open_on_every_update
334
+ io = open
335
+ begin
336
+ yield io
337
+ ensure
338
+ io.close unless io.nil?
339
+ end
340
+ else
341
+ @io ||= open
342
+ yield @io
343
+ @eof = true if @io.nil?
344
+ end
345
+ rescue WatcherSetupError => e
346
+ close
347
+ @eof = true
348
+ raise e
349
+ rescue
350
+ @log.error $!.to_s
351
+ @log.error_backtrace
352
+ close
353
+ @eof = true
354
+ end
355
+ end
356
+
357
+ class NullIOHandler
358
+ def initialize
359
+ end
360
+
361
+ def ready_to_shutdown(shutdown_start_time = nil)
362
+ end
363
+
364
+ def io
365
+ end
366
+
367
+ def on_notify
368
+ end
369
+
370
+ def close
371
+ end
372
+
373
+ def opened?
374
+ false
375
+ end
376
+
377
+ def eof?
378
+ true
379
+ end
380
+
381
+ def drained?
382
+ true
383
+ end
384
+
385
+ def pending?
386
+ false
387
+ end
388
+ end
389
+ end
390
+ end
391
+ end