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,272 @@
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 'fileutils'
18
+
19
+ require 'fluent/plugin/buffer'
20
+ require 'fluent/plugin/buffer/file_single_chunk'
21
+ require 'fluent/system_config'
22
+ require 'fluent/variable_store'
23
+
24
+ module Fluent
25
+ module Plugin
26
+ class FileSingleBuffer < Fluent::Plugin::Buffer
27
+ Plugin.register_buffer('file_single', self)
28
+
29
+ include SystemConfig::Mixin
30
+
31
+ DEFAULT_CHUNK_LIMIT_SIZE = 256 * 1024 * 1024 # 256MB
32
+ DEFAULT_TOTAL_LIMIT_SIZE = 64 * 1024 * 1024 * 1024 # 64GB
33
+
34
+ PATH_SUFFIX = ".#{Fluent::Plugin::Buffer::FileSingleChunk::PATH_EXT}"
35
+
36
+ desc 'The path where buffer chunks are stored.'
37
+ config_param :path, :string, default: nil
38
+ desc 'Calculate the number of record in chunk during resume'
39
+ config_param :calc_num_records, :bool, default: true
40
+ desc 'The format of chunk. This is used to calculate the number of record'
41
+ config_param :chunk_format, :enum, list: [:msgpack, :text, :auto], default: :auto
42
+
43
+ config_set_default :chunk_limit_size, DEFAULT_CHUNK_LIMIT_SIZE
44
+ config_set_default :total_limit_size, DEFAULT_TOTAL_LIMIT_SIZE
45
+
46
+ desc 'The permission of chunk file. If no specified, <system> setting or 0644 is used'
47
+ config_param :file_permission, :string, default: nil
48
+ desc 'The permission of chunk directory. If no specified, <system> setting or 0755 is used'
49
+ config_param :dir_permission, :string, default: nil
50
+
51
+ def initialize
52
+ super
53
+
54
+ @multi_workers_available = false
55
+ @additional_resume_path = nil
56
+ @variable_store = nil
57
+ end
58
+
59
+ def configure(conf)
60
+ super
61
+
62
+ @variable_store = Fluent::VariableStore.fetch_or_build(:buf_file_single)
63
+
64
+ if @chunk_format == :auto
65
+ @chunk_format = owner.formatted_to_msgpack_binary? ? :msgpack : :text
66
+ end
67
+
68
+ @key_in_path = nil
69
+ if owner.chunk_keys.empty?
70
+ log.debug "use event tag for buffer key"
71
+ else
72
+ if owner.chunk_key_tag
73
+ raise Fluent::ConfigError, "chunk keys must be tag or one field"
74
+ elsif owner.chunk_keys.size > 1
75
+ raise Fluent::ConfigError, "2 or more chunk keys is not allowed"
76
+ else
77
+ @key_in_path = owner.chunk_keys.first.to_sym
78
+ end
79
+ end
80
+
81
+ multi_workers_configured = owner.system_config.workers > 1
82
+ using_plugin_root_dir = false
83
+ unless @path
84
+ if root_dir = owner.plugin_root_dir
85
+ @path = File.join(root_dir, 'buffer')
86
+ using_plugin_root_dir = true # plugin_root_dir path contains worker id
87
+ else
88
+ raise Fluent::ConfigError, "buffer path is not configured. specify 'path' in <buffer>"
89
+ end
90
+ end
91
+
92
+ specified_directory_exists = File.exist?(@path) && File.directory?(@path)
93
+ unexisting_path_for_directory = !File.exist?(@path) && !@path.include?('.*')
94
+
95
+ if specified_directory_exists || unexisting_path_for_directory # directory
96
+ if using_plugin_root_dir || !multi_workers_configured
97
+ @path = File.join(@path, "fsb.*#{PATH_SUFFIX}")
98
+ else
99
+ @path = File.join(@path, "worker#{fluentd_worker_id}", "fsb.*#{PATH_SUFFIX}")
100
+ if fluentd_worker_id == 0
101
+ # worker 0 always checks unflushed buffer chunks to be resumed (might be created while non-multi-worker configuration)
102
+ @additional_resume_path = File.join(File.expand_path("../../", @path), "fsb.*#{PATH_SUFFIX}")
103
+ end
104
+ end
105
+ @multi_workers_available = true
106
+ else # specified path is file path
107
+ if File.basename(@path).include?('.*.')
108
+ new_path = File.join(File.dirname(@path), "fsb.*#{PATH_SUFFIX}")
109
+ log.warn "file_single doesn't allow user specified 'prefix.*.suffix' style path. Use '#{new_path}' for file instead: #{@path}"
110
+ @path = new_path
111
+ elsif File.basename(@path).end_with?('.*')
112
+ @path = @path + PATH_SUFFIX
113
+ else
114
+ # existing file will be ignored
115
+ @path = @path + ".*#{PATH_SUFFIX}"
116
+ end
117
+ @multi_workers_available = false
118
+ end
119
+
120
+ type_of_owner = Plugin.lookup_type_from_class(@_owner.class)
121
+ if @variable_store.has_key?(@path) && !called_in_test?
122
+ type_using_this_path = @variable_store[@path]
123
+ raise Fluent::ConfigError, "Other '#{type_using_this_path}' plugin already uses same buffer path: type = #{type_of_owner}, buffer path = #{@path}"
124
+ end
125
+
126
+ @variable_store[@path] = type_of_owner
127
+ @dir_permission = if @dir_permission
128
+ @dir_permission.to_i(8)
129
+ else
130
+ system_config.dir_permission || Fluent::DEFAULT_DIR_PERMISSION
131
+ end
132
+ end
133
+
134
+ # This method is called only when multi worker is configured
135
+ def multi_workers_ready?
136
+ unless @multi_workers_available
137
+ log.error "file_single buffer with multi workers should be configured to use directory 'path', or system root_dir and plugin id"
138
+ end
139
+ @multi_workers_available
140
+ end
141
+
142
+ def start
143
+ FileUtils.mkdir_p(File.dirname(@path), mode: @dir_permission)
144
+
145
+ super
146
+ end
147
+
148
+ def stop
149
+ if @variable_store
150
+ @variable_store.delete(@path)
151
+ end
152
+
153
+ super
154
+ end
155
+
156
+ def persistent?
157
+ true
158
+ end
159
+
160
+ def resume
161
+ stage = {}
162
+ queue = []
163
+ exist_broken_file = false
164
+
165
+ patterns = [@path]
166
+ patterns.unshift @additional_resume_path if @additional_resume_path
167
+ Dir.glob(escaped_patterns(patterns)) do |path|
168
+ next unless File.file?(path)
169
+
170
+ if owner.respond_to?(:buffer_config) && owner.buffer_config&.flush_at_shutdown
171
+ # When `flush_at_shutdown` is `true`, the remaining chunk files during resuming are possibly broken
172
+ # since there may be a power failure or similar failure.
173
+ log.warn { "restoring buffer file: path = #{path}" }
174
+ else
175
+ log.debug { "restoring buffer file: path = #{path}" }
176
+ end
177
+
178
+ m = new_metadata() # this metadata will be updated in FileSingleChunk.new
179
+ mode = Fluent::Plugin::Buffer::FileSingleChunk.assume_chunk_state(path)
180
+ if mode == :unknown
181
+ log.debug "unknown state chunk found", path: path
182
+ next
183
+ end
184
+
185
+ begin
186
+ chunk = Fluent::Plugin::Buffer::FileSingleChunk.new(m, path, mode, @key_in_path, compress: @compress, decompression_size_limit: @decompression_size_limit)
187
+ chunk.restore_size(@chunk_format) if @calc_num_records
188
+ rescue Fluent::Plugin::Buffer::FileSingleChunk::FileChunkError => e
189
+ exist_broken_file = true
190
+ handle_broken_files(path, mode, e)
191
+ next
192
+ end
193
+
194
+ case chunk.state
195
+ when :staged
196
+ if chunk_size_full?(chunk) || stage.key?(chunk.metadata)
197
+ queue << chunk.enqueued!
198
+ else
199
+ stage[chunk.metadata] = chunk
200
+ end
201
+ when :queued
202
+ queue << chunk
203
+ end
204
+ end
205
+
206
+ queue.sort_by!(&:modified_at)
207
+
208
+ # If one of the files is corrupted, other files may also be corrupted and be undetected.
209
+ # The time periods of each chunk are helpful to check the data.
210
+ if exist_broken_file
211
+ log.info "Since a broken chunk file was found, it is possible that other files remaining at the time of resuming were also broken. Here is the list of the files."
212
+ (stage.values + queue).each { |chunk|
213
+ log.info " #{chunk.path}:", :created_at => chunk.created_at, :modified_at => chunk.modified_at
214
+ }
215
+ end
216
+
217
+ return stage, queue
218
+ end
219
+
220
+ def generate_chunk(metadata)
221
+ # FileChunk generates real path with unique_id
222
+ perm = @file_permission || system_config.file_permission
223
+ chunk = Fluent::Plugin::Buffer::FileSingleChunk.new(metadata, @path, :create, @key_in_path, perm: perm, compress: @compress, decompression_size_limit: @decompression_size_limit)
224
+
225
+ log.debug "Created new chunk", chunk_id: dump_unique_id_hex(chunk.unique_id), metadata: metadata
226
+
227
+ chunk
228
+ end
229
+
230
+ def handle_broken_files(path, mode, e)
231
+ log.error "found broken chunk file during resume.", :path => path, :mode => mode, :err_msg => e.message
232
+ unique_id, _ = Fluent::Plugin::Buffer::FileSingleChunk.unique_id_and_key_from_path(path)
233
+ backup(unique_id) { |f|
234
+ File.open(path, 'rb') { |chunk|
235
+ chunk.set_encoding(Encoding::ASCII_8BIT)
236
+ chunk.sync = true
237
+ chunk.binmode
238
+ IO.copy_stream(chunk, f)
239
+ }
240
+ }
241
+ rescue => error
242
+ log.error "backup failed. Delete corresponding files.", :err_msg => error.message
243
+ ensure
244
+ log.warn "disable_chunk_backup is true. #{dump_unique_id_hex(unique_id)} chunk is thrown away." if @disable_chunk_backup
245
+ File.unlink(path) rescue nil
246
+ end
247
+
248
+ def evacuate_chunk(chunk)
249
+ unless chunk.is_a?(Fluent::Plugin::Buffer::FileSingleChunk)
250
+ raise ArgumentError, "The chunk must be FileSingleChunk, but it was #{chunk.class}."
251
+ end
252
+
253
+ backup_dir = evacuate_dir
254
+ FileUtils.mkdir_p(backup_dir, mode: system_config.dir_permission || Fluent::DEFAULT_DIR_PERMISSION) unless Dir.exist?(backup_dir)
255
+
256
+ FileUtils.copy(chunk.path, backup_dir)
257
+ log.warn "chunk files are evacuated to #{backup_dir}.", chunk_id: dump_unique_id_hex(chunk.unique_id)
258
+ rescue => e
259
+ log.error "unexpected error while evacuating chunk files.", error: e
260
+ end
261
+
262
+ private
263
+
264
+ def escaped_patterns(patterns)
265
+ patterns.map { |pattern|
266
+ # '{' '}' are special character in Dir.glob
267
+ pattern.gsub(/[\{\}]/) { |c| "\\#{c}" }
268
+ }
269
+ end
270
+ end
271
+ end
272
+ end
@@ -0,0 +1,34 @@
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/buffer'
18
+ require 'fluent/plugin/buffer/memory_chunk'
19
+
20
+ module Fluent
21
+ module Plugin
22
+ class MemoryBuffer < Fluent::Plugin::Buffer
23
+ Plugin.register_buffer('memory', self)
24
+
25
+ def resume
26
+ return {}, []
27
+ end
28
+
29
+ def generate_chunk(metadata)
30
+ Fluent::Plugin::Buffer::MemoryChunk.new(metadata, compress: @compress, decompression_size_limit: @decompression_size_limit)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,313 @@
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/buffer'
18
+ require 'fluent/plugin/compressable'
19
+ require 'fluent/unique_id'
20
+ require 'fluent/event'
21
+ require 'fluent/ext_monitor_require'
22
+
23
+ require 'tempfile'
24
+ require 'zlib'
25
+
26
+ module Fluent
27
+ module Plugin
28
+ class Buffer # fluent/plugin/buffer is already loaded
29
+ class Chunk
30
+ include MonitorMixin
31
+ include UniqueId::Mixin
32
+
33
+ # Chunks has 2 part:
34
+ # * metadata: contains metadata which should be restored after resume (if possible)
35
+ # v: {key=>value,key=>value,...} (optional)
36
+ # t: tag as string (optional)
37
+ # k: time slice key (optional)
38
+ #
39
+ # id: unique_id of chunk (*)
40
+ # s: size (number of events in chunk) (*)
41
+ # c: created_at as unix time (*)
42
+ # m: modified_at as unix time (*)
43
+ # (*): fields automatically injected by chunk itself
44
+ # * data: binary data, combined records represented as String, maybe compressed
45
+
46
+ # NOTE: keys of metadata are named with a single letter
47
+ # to decread bytesize of metadata I/O
48
+
49
+ # TODO: CompressedPackedMessage of forward protocol?
50
+
51
+ def initialize(metadata, compress: :text, decompression_size_limit: Compressable::DEFAULT_DECOMPRESSION_SIZE_LIMIT)
52
+ super()
53
+ @unique_id = generate_unique_id
54
+ @metadata = metadata
55
+
56
+ # state: unstaged/staged/queued/closed
57
+ @state = :unstaged
58
+
59
+ @size = 0
60
+ @created_at = Fluent::Clock.real_now
61
+ @modified_at = Fluent::Clock.real_now
62
+ if compress == :gzip
63
+ extend GzipDecompressable
64
+ elsif compress == :zstd
65
+ extend ZstdDecompressable
66
+ end
67
+ @decompression_size_limit = decompression_size_limit
68
+ end
69
+
70
+ attr_reader :unique_id, :metadata, :state
71
+
72
+ def raw_create_at
73
+ @created_at
74
+ end
75
+
76
+ def raw_modified_at
77
+ @modified_at
78
+ end
79
+
80
+ # for compatibility
81
+ def created_at
82
+ @created_at_object ||= Time.at(@created_at)
83
+ end
84
+
85
+ # for compatibility
86
+ def modified_at
87
+ @modified_at_object ||= Time.at(@modified_at)
88
+ end
89
+
90
+ # data is array of formatted record string
91
+ def append(data, **kwargs)
92
+ raise ArgumentError, "`compress: #{kwargs[:compress]}` can be used for Compressable module" if kwargs[:compress] == :gzip || kwargs[:compress] == :zstd
93
+ begin
94
+ adding = data.join.force_encoding(Encoding::ASCII_8BIT)
95
+ rescue
96
+ # Fallback
97
+ # Array#join throws an exception if data contains strings with a different encoding.
98
+ # Although such cases may be rare, it should be considered as a safety precaution.
99
+ adding = ''.force_encoding(Encoding::ASCII_8BIT)
100
+ data.each do |d|
101
+ adding << d.b
102
+ end
103
+ end
104
+ concat(adding, data.size)
105
+ end
106
+
107
+ # for event streams which is packed or zipped (and we want not to unpack/uncompress)
108
+ def concat(bulk, records)
109
+ raise NotImplementedError, "Implement this method in child class"
110
+ end
111
+
112
+ def commit
113
+ raise NotImplementedError, "Implement this method in child class"
114
+ end
115
+
116
+ def rollback
117
+ raise NotImplementedError, "Implement this method in child class"
118
+ end
119
+
120
+ def bytesize
121
+ raise NotImplementedError, "Implement this method in child class"
122
+ end
123
+
124
+ def size
125
+ raise NotImplementedError, "Implement this method in child class"
126
+ end
127
+ alias :length :size
128
+
129
+ def empty?
130
+ size == 0
131
+ end
132
+
133
+ def writable?
134
+ @state == :staged || @state == :unstaged
135
+ end
136
+
137
+ def unstaged?
138
+ @state == :unstaged
139
+ end
140
+
141
+ def staged?
142
+ @state == :staged
143
+ end
144
+
145
+ def queued?
146
+ @state == :queued
147
+ end
148
+
149
+ def closed?
150
+ @state == :closed
151
+ end
152
+
153
+ def staged!
154
+ @state = :staged
155
+ self
156
+ end
157
+
158
+ def unstaged!
159
+ @state = :unstaged
160
+ self
161
+ end
162
+
163
+ def enqueued!
164
+ @state = :queued
165
+ self
166
+ end
167
+
168
+ def close
169
+ @state = :closed
170
+ self
171
+ end
172
+
173
+ def purge
174
+ @state = :closed
175
+ self
176
+ end
177
+
178
+ def read(**kwargs)
179
+ raise ArgumentError, "`compressed: #{kwargs[:compressed]}` can be used for Compressable module" if kwargs[:compressed] == :gzip || kwargs[:compressed] == :zstd
180
+ raise NotImplementedError, "Implement this method in child class"
181
+ end
182
+
183
+ def open(**kwargs, &block)
184
+ raise ArgumentError, "`compressed: #{kwargs[:compressed]}` can be used for Compressable module" if kwargs[:compressed] == :gzip || kwargs[:compressed] == :zstd
185
+ raise NotImplementedError, "Implement this method in child class"
186
+ end
187
+
188
+ def write_to(io, **kwargs)
189
+ raise ArgumentError, "`compressed: #{kwargs[:compressed]}` can be used for Compressable module" if kwargs[:compressed] == :gzip || kwargs[:compressed] == :zstd
190
+ open do |i|
191
+ IO.copy_stream(i, io)
192
+ end
193
+ end
194
+
195
+ module GzipDecompressable
196
+ include Fluent::Plugin::Compressable
197
+
198
+ def append(data, **kwargs)
199
+ if kwargs[:compress] == :gzip
200
+ io = StringIO.new
201
+ Zlib::GzipWriter.wrap(io) do |gz|
202
+ data.each do |d|
203
+ gz.write d
204
+ end
205
+ end
206
+ concat(io.string, data.size)
207
+ else
208
+ super
209
+ end
210
+ end
211
+
212
+ def open(**kwargs, &block)
213
+ if kwargs[:compressed] == :gzip
214
+ super
215
+ else
216
+ super(**kwargs) do |chunk_io|
217
+ output_io = if chunk_io.is_a?(StringIO)
218
+ StringIO.new
219
+ else
220
+ Tempfile.new('decompressed-data')
221
+ end
222
+ output_io.binmode if output_io.is_a?(Tempfile)
223
+ begin
224
+ decompress(input_io: chunk_io, output_io: output_io)
225
+ output_io.seek(0, IO::SEEK_SET)
226
+ yield output_io
227
+ ensure
228
+ output_io.close! if output_io.is_a?(Tempfile)
229
+ end
230
+ end
231
+ end
232
+ end
233
+
234
+ def read(**kwargs)
235
+ if kwargs[:compressed] == :gzip
236
+ super
237
+ else
238
+ decompress(super)
239
+ end
240
+ end
241
+
242
+ def write_to(io, **kwargs)
243
+ open(compressed: :gzip) do |chunk_io|
244
+ if kwargs[:compressed] == :gzip
245
+ IO.copy_stream(chunk_io, io)
246
+ else
247
+ decompress(input_io: chunk_io, output_io: io)
248
+ end
249
+ end
250
+ end
251
+ end
252
+
253
+ module ZstdDecompressable
254
+ include Fluent::Plugin::Compressable
255
+
256
+ def append(data, **kwargs)
257
+ if kwargs[:compress] == :zstd
258
+ io = StringIO.new
259
+ stream = Zstd::StreamWriter.new(io)
260
+ data.each do |d|
261
+ stream.write(d)
262
+ end
263
+ stream.finish
264
+ concat(io.string, data.size)
265
+ else
266
+ super
267
+ end
268
+ end
269
+
270
+ def open(**kwargs, &block)
271
+ if kwargs[:compressed] == :zstd
272
+ super
273
+ else
274
+ super(**kwargs) do |chunk_io|
275
+ output_io = if chunk_io.is_a?(StringIO)
276
+ StringIO.new
277
+ else
278
+ Tempfile.new('decompressed-data')
279
+ end
280
+ output_io.binmode if output_io.is_a?(Tempfile)
281
+ begin
282
+ decompress(input_io: chunk_io, output_io: output_io, type: :zstd)
283
+ output_io.seek(0, IO::SEEK_SET)
284
+ yield output_io
285
+ ensure
286
+ output_io.close! if output_io.is_a?(Tempfile)
287
+ end
288
+ end
289
+ end
290
+ end
291
+
292
+ def read(**kwargs)
293
+ if kwargs[:compressed] == :zstd
294
+ super
295
+ else
296
+ decompress(super,type: :zstd)
297
+ end
298
+ end
299
+
300
+ def write_to(io, **kwargs)
301
+ open(compressed: :zstd) do |chunk_io|
302
+ if kwargs[:compressed] == :zstd
303
+ IO.copy_stream(chunk_io, io)
304
+ else
305
+ decompress(input_io: chunk_io, output_io: io, type: :zstd)
306
+ end
307
+ end
308
+ end
309
+ end
310
+ end
311
+ end
312
+ end
313
+ end