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,44 @@
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 'serverengine'
18
+ require 'fileutils'
19
+
20
+ module Fluent
21
+ module Test
22
+ module StartupShutdown
23
+ def startup
24
+ @server = ServerEngine::SocketManager::Server.open
25
+ ENV['SERVERENGINE_SOCKETMANAGER_PATH'] = @server.path.to_s
26
+ end
27
+
28
+ def shutdown
29
+ @server.close
30
+ end
31
+
32
+ def self.setup
33
+ @server = ServerEngine::SocketManager::Server.open
34
+ ENV['SERVERENGINE_SOCKETMANAGER_PATH'] = @server.path.to_s
35
+ end
36
+
37
+ def self.teardown
38
+ @server.close
39
+ # on Windows, the path is a TCP port number
40
+ FileUtils.rm_f @server.path unless Fluent.windows?
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,61 @@
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 'test/unit'
18
+ require 'fluent/env' # for Fluent.windows?
19
+ require 'fluent/test/log'
20
+ require 'fluent/test/base'
21
+ require 'fluent/test/input_test'
22
+ require 'fluent/test/output_test'
23
+ require 'fluent/test/filter_test'
24
+ require 'fluent/test/parser_test'
25
+ require 'fluent/test/formatter_test'
26
+ require 'serverengine'
27
+
28
+
29
+ module Fluent
30
+ module Test
31
+ def self.dummy_logger
32
+ dl_opts = {log_level: ServerEngine::DaemonLogger::INFO}
33
+ logdev = Fluent::Test::DummyLogDevice.new
34
+ logger = ServerEngine::DaemonLogger.new(logdev, dl_opts)
35
+ Fluent::Log.new(logger)
36
+ end
37
+
38
+ def self.setup
39
+ ENV['SERVERENGINE_WORKER_ID'] = '0'
40
+
41
+ $log = dummy_logger
42
+
43
+ old_engine = Fluent.__send__(:remove_const, :Engine)
44
+ # Ensure that GC can remove the objects of the old engine.
45
+ # Some objects can still exist after `remove_const`. See https://github.com/fluent/fluentd/issues/5054.
46
+ old_engine.instance_variable_set(:@root_agent, nil)
47
+
48
+ engine = Fluent.const_set(:Engine, EngineClass.new).init(SystemConfig.new)
49
+ engine.define_singleton_method(:now=) {|n|
50
+ @now = n
51
+ }
52
+ engine.define_singleton_method(:now) {
53
+ @now ||= super()
54
+ }
55
+
56
+ nil
57
+ end
58
+ end
59
+ end
60
+
61
+ $log ||= Fluent::Test.dummy_logger
@@ -0,0 +1,513 @@
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 'time'
18
+ require 'msgpack'
19
+ require 'strptime'
20
+ require 'fluent/timezone'
21
+ require 'fluent/configurable'
22
+ require 'fluent/config/error'
23
+
24
+ module Fluent
25
+ class EventTime
26
+ TYPE = 0
27
+ FORMATTER = Strftime.new('%Y-%m-%d %H:%M:%S.%N %z')
28
+
29
+ def initialize(sec, nsec = 0)
30
+ @sec = sec
31
+ @nsec = nsec
32
+ end
33
+
34
+ def ==(other)
35
+ if other.is_a?(Fluent::EventTime)
36
+ @sec == other.sec
37
+ else
38
+ @sec == other
39
+ end
40
+ end
41
+
42
+ def sec
43
+ @sec
44
+ end
45
+
46
+ def nsec
47
+ @nsec
48
+ end
49
+
50
+ def to_int
51
+ @sec
52
+ end
53
+ alias :to_i :to_int
54
+
55
+ def to_f
56
+ @sec + @nsec / 1_000_000_000.0
57
+ end
58
+
59
+ # for Time.at
60
+ def to_r
61
+ Rational(@sec * 1_000_000_000 + @nsec, 1_000_000_000)
62
+ end
63
+
64
+ # for > and others
65
+ def coerce(other)
66
+ [other, @sec]
67
+ end
68
+
69
+ def to_s
70
+ @sec.to_s
71
+ end
72
+
73
+ begin
74
+ # ruby 2.5 or later
75
+ Time.at(0, 0, :nanosecond)
76
+
77
+ def to_time
78
+ Time.at(@sec, @nsec, :nanosecond)
79
+ end
80
+ rescue
81
+ def to_time
82
+ Time.at(Rational(@sec * 1_000_000_000 + @nsec, 1_000_000_000))
83
+ end
84
+ end
85
+
86
+ def to_json(*args)
87
+ @sec.to_s
88
+ end
89
+
90
+ def to_msgpack(io = nil)
91
+ @sec.to_msgpack(io)
92
+ end
93
+
94
+ def to_msgpack_ext
95
+ [@sec, @nsec].pack('NN')
96
+ end
97
+
98
+ def self.from_msgpack_ext(data)
99
+ new(*data.unpack('NN'))
100
+ end
101
+
102
+ def self.from_time(time)
103
+ Fluent::EventTime.new(time.to_i, time.nsec)
104
+ end
105
+
106
+ def self.eq?(a, b)
107
+ if a.is_a?(Fluent::EventTime) && b.is_a?(Fluent::EventTime)
108
+ a.sec == b.sec && a.nsec == b.nsec
109
+ else
110
+ a == b
111
+ end
112
+ end
113
+
114
+ def self.now
115
+ time = Time.now
116
+ Fluent::EventTime.new(time.to_i, time.nsec)
117
+ end
118
+
119
+ def self.parse(*args)
120
+ from_time(Time.parse(*args))
121
+ end
122
+
123
+ ## TODO: For performance, implement +, -, and so on
124
+ def method_missing(name, *args, &block)
125
+ @sec.send(name, *args, &block)
126
+ end
127
+
128
+ def inspect
129
+ FORMATTER.exec(Time.at(self))
130
+ end
131
+ end
132
+
133
+ module TimeMixin
134
+ TIME_TYPES = ['string', 'unixtime', 'float', 'mixed']
135
+
136
+ TIME_PARAMETERS = [
137
+ [:time_format, :string, {default: nil}],
138
+ [:localtime, :bool, {default: true}], # UTC if :localtime is false and :timezone is nil
139
+ [:utc, :bool, {default: false}], # to turn :localtime false
140
+ [:timezone, :string, {default: nil}],
141
+ [:time_format_fallbacks, :array, {default: []}], # try time_format, then try fallbacks
142
+ ]
143
+ TIME_FULL_PARAMETERS = [
144
+ # To avoid to define :time_type twice (in plugin_helper/inject)
145
+ [:time_type, :enum, {default: :string, list: TIME_TYPES.map(&:to_sym)}],
146
+ ] + TIME_PARAMETERS
147
+
148
+ module TimeParameters
149
+ include Fluent::Configurable
150
+ TIME_FULL_PARAMETERS.each do |name, type, opts|
151
+ config_param(name, type, **opts)
152
+ end
153
+
154
+ def configure(conf)
155
+ if conf.has_key?('localtime') || conf.has_key?('utc')
156
+ if conf.has_key?('localtime')
157
+ conf['localtime'] = Fluent::Config.bool_value(conf['localtime'])
158
+ elsif conf.has_key?('utc')
159
+ conf['localtime'] = !(Fluent::Config.bool_value(conf['utc']))
160
+ # Specifying "localtime false" means using UTC in TimeFormatter
161
+ # And specifying "utc" is different from specifying "timezone +0000"(it's not always UTC).
162
+ # There are difference between "Z" and "+0000" in timezone formatting.
163
+ # TODO: add kwargs to TimeFormatter to specify "using localtime", "using UTC" or "using specified timezone" in more explicit way
164
+ end
165
+ end
166
+
167
+ super
168
+
169
+ if conf.has_key?('localtime') && conf.has_key?('utc') && !(@localtime ^ @utc)
170
+ raise Fluent::ConfigError, "both of utc and localtime are specified, use only one of them"
171
+ end
172
+
173
+ if conf.has_key?('time_type') and @time_type == :mixed
174
+ if @time_format.nil? and @time_format_fallbacks.empty?
175
+ raise Fluent::ConfigError, "time_type is :mixed but time_format and time_format_fallbacks is empty."
176
+ end
177
+ end
178
+
179
+ Fluent::Timezone.validate!(@timezone) if @timezone
180
+ end
181
+ end
182
+
183
+ module Parser
184
+ def self.included(mod)
185
+ mod.include TimeParameters
186
+ end
187
+
188
+ def time_parser_create(type: @time_type, format: @time_format, timezone: @timezone, force_localtime: false)
189
+ return MixedTimeParser.new(type, format, @localtime, timezone, @utc, force_localtime, @time_format_fallbacks) if type == :mixed
190
+ return NumericTimeParser.new(type) if type != :string
191
+ return TimeParser.new(format, true, nil) if force_localtime
192
+
193
+ localtime = @localtime && (timezone.nil? && !@utc)
194
+ TimeParser.new(format, localtime, timezone)
195
+ end
196
+ end
197
+
198
+ module Formatter
199
+ def self.included(mod)
200
+ mod.include TimeParameters
201
+ end
202
+
203
+ def time_formatter_create(type: @time_type, format: @time_format, timezone: @timezone, force_localtime: false)
204
+ return NumericTimeFormatter.new(type) if type != :string
205
+ return TimeFormatter.new(format, true, nil) if force_localtime
206
+
207
+ localtime = @localtime && (timezone.nil? && !@utc)
208
+ TimeFormatter.new(format, localtime, timezone)
209
+ end
210
+ end
211
+ end
212
+
213
+ class TimeParser
214
+ class TimeParseError < StandardError; end
215
+
216
+ def initialize(format = nil, localtime = true, timezone = nil)
217
+ if format.nil? && (timezone || !localtime)
218
+ raise Fluent::ConfigError, "specifying timezone requires time format"
219
+ end
220
+
221
+ @cache1_key = nil
222
+ @cache1_time = nil
223
+ @cache2_key = nil
224
+ @cache2_time = nil
225
+
226
+ format_with_timezone = format && (format.include?("%z") || format.include?("%Z"))
227
+
228
+ utc_offset = case
229
+ when format_with_timezone then
230
+ nil
231
+ when timezone then
232
+ Fluent::Timezone.utc_offset(timezone)
233
+ when localtime then
234
+ nil
235
+ else
236
+ 0 # utc
237
+ end
238
+
239
+ strptime = format && (Strptime.new(format) rescue nil)
240
+
241
+ @parse = case
242
+ when format_with_timezone && strptime then ->(v){ Fluent::EventTime.from_time(strptime.exec(v)) }
243
+ when format_with_timezone then ->(v){ Fluent::EventTime.from_time(Time.strptime(v, format)) }
244
+ when format == '%iso8601' then ->(v){ Fluent::EventTime.from_time(Time.iso8601(v)) }
245
+ when strptime then
246
+ if utc_offset.nil?
247
+ ->(v){ t = strptime.exec(v); Fluent::EventTime.new(t.to_i, t.nsec) }
248
+ elsif utc_offset.respond_to?(:call)
249
+ ->(v) { t = strptime.exec(v); Fluent::EventTime.new(t.to_i + t.utc_offset - utc_offset.call(t), t.nsec) }
250
+ else
251
+ ->(v) { t = strptime.exec(v); Fluent::EventTime.new(t.to_i + t.utc_offset - utc_offset, t.nsec) }
252
+ end
253
+ when format then
254
+ if utc_offset.nil?
255
+ ->(v){ t = Time.strptime(v, format); Fluent::EventTime.new(t.to_i, t.nsec) }
256
+ elsif utc_offset.respond_to?(:call)
257
+ ->(v){ t = Time.strptime(v, format); Fluent::EventTime.new(t.to_i + t.utc_offset - utc_offset.call(t), t.nsec) }
258
+ else
259
+ ->(v){ t = Time.strptime(v, format); Fluent::EventTime.new(t.to_i + t.utc_offset - utc_offset, t.nsec) }
260
+ end
261
+ else ->(v){ Fluent::EventTime.parse(v) }
262
+ end
263
+ end
264
+
265
+ # TODO: new cache mechanism using format string
266
+ def parse(value)
267
+ unless value.is_a?(String)
268
+ raise TimeParseError, "value must be string: #{value}"
269
+ end
270
+
271
+ if @cache1_key == value
272
+ return @cache1_time
273
+ elsif @cache2_key == value
274
+ return @cache2_time
275
+ else
276
+ begin
277
+ time = @parse.call(value)
278
+ rescue => e
279
+ raise TimeParseError, "invalid time format: value = #{value}, error_class = #{e.class.name}, error = #{e.message}"
280
+ end
281
+ @cache1_key = @cache2_key
282
+ @cache1_time = @cache2_time
283
+ @cache2_key = value
284
+ @cache2_time = time
285
+ return time
286
+ end
287
+ end
288
+ alias :call :parse
289
+ end
290
+
291
+ class NumericTimeParser < TimeParser # to include TimeParseError
292
+ def initialize(type, localtime = nil, timezone = nil)
293
+ @cache1_key = @cache1_time = @cache2_key = @cache2_time = nil
294
+
295
+ if type == :unixtime
296
+ define_singleton_method(:parse, method(:parse_unixtime))
297
+ define_singleton_method(:call, method(:parse_unixtime))
298
+ else # :float
299
+ define_singleton_method(:parse, method(:parse_float))
300
+ define_singleton_method(:call, method(:parse_float))
301
+ end
302
+ end
303
+
304
+ def parse_unixtime(value)
305
+ unless value.is_a?(String) || value.is_a?(Numeric)
306
+ raise TimeParseError, "value must be a string or a number: #{value}(#{value.class})"
307
+ end
308
+
309
+ if @cache1_key == value
310
+ return @cache1_time
311
+ elsif @cache2_key == value
312
+ return @cache2_time
313
+ end
314
+
315
+ begin
316
+ time = Fluent::EventTime.new(value.to_i)
317
+ rescue => e
318
+ raise TimeParseError, "invalid time format: value = #{value}, error_class = #{e.class.name}, error = #{e.message}"
319
+ end
320
+ @cache1_key = @cache2_key
321
+ @cache1_time = @cache2_time
322
+ @cache2_key = value
323
+ @cache2_time = time
324
+ time
325
+ end
326
+
327
+ # rough benchmark result to compare handmade parser vs Fluent::EventTime.from_time(Time.at(value.to_r))
328
+ # full: with 9-digits of nsec after dot
329
+ # msec: with 3-digits of msec after dot
330
+ # 10_000_000 times loop on MacBookAir
331
+ ## parse_by_myself(full): 12.162475 sec
332
+ ## parse_by_myself(msec): 15.050435 sec
333
+ ## parse_by_to_r (full): 28.722362 sec
334
+ ## parse_by_to_r (msec): 28.232856 sec
335
+ def parse_float(value)
336
+ unless value.is_a?(String) || value.is_a?(Numeric)
337
+ raise TimeParseError, "value must be a string or a number: #{value}(#{value.class})"
338
+ end
339
+
340
+ if @cache1_key == value
341
+ return @cache1_time
342
+ elsif @cache2_key == value
343
+ return @cache2_time
344
+ end
345
+
346
+ begin
347
+ sec_s, nsec_s, _ = value.to_s.split('.', 3) # throw away second-dot and later
348
+ nsec_s = nsec_s && nsec_s[0..9] || '0'
349
+ nsec_s += '0' * (9 - nsec_s.size) if nsec_s.size < 9
350
+ time = Fluent::EventTime.new(sec_s.to_i, nsec_s.to_i)
351
+ rescue => e
352
+ raise TimeParseError, "invalid time format: value = #{value}, error_class = #{e.class.name}, error = #{e.message}"
353
+ end
354
+ @cache1_key = @cache2_key
355
+ @cache1_time = @cache2_time
356
+ @cache2_key = value
357
+ @cache2_time = time
358
+ time
359
+ end
360
+ end
361
+
362
+ class TimeFormatter
363
+ def initialize(format = nil, localtime = true, timezone = nil)
364
+ # An empty cache slot is marked by a nil string, not by its key: 0 is a
365
+ # valid timestamp, so a key can never say whether the slot is filled.
366
+ @tc1 = 0
367
+ @tc1_str = nil
368
+ @tc2 = 0
369
+ @tc2_str = nil
370
+
371
+ strftime = format && (Strftime.new(format) rescue nil)
372
+ if format && format =~ /(^|[^%])(%%)*%L|(^|[^%])(%%)*%\d*N/
373
+ define_singleton_method(:format, method(:format_with_subsec))
374
+ define_singleton_method(:call, method(:format_with_subsec))
375
+ else
376
+ define_singleton_method(:format, method(:format_without_subsec))
377
+ define_singleton_method(:call, method(:format_without_subsec))
378
+ end
379
+
380
+ formatter = Fluent::Timezone.formatter(timezone, strftime ? strftime : format)
381
+ @format_nocache = case
382
+ when formatter then formatter
383
+ when strftime && localtime then ->(time){ strftime.exec(Time.at(time)) }
384
+ when format && localtime then ->(time){ Time.at(time).strftime(format) }
385
+ when strftime then ->(time){ strftime.exec(Time.at(time).utc) }
386
+ when format then ->(time){ Time.at(time).utc.strftime(format) }
387
+ when localtime then ->(time){ Time.at(time).iso8601 }
388
+ else ->(time){ Time.at(time).utc.iso8601 }
389
+ end
390
+ end
391
+
392
+ def format_without_subsec(time)
393
+ if @tc1_str && @tc1 == time
394
+ return @tc1_str
395
+ elsif @tc2_str && @tc2 == time
396
+ return @tc2_str
397
+ else
398
+ str = format_nocache(time)
399
+ if @tc1 < @tc2
400
+ @tc1 = time
401
+ @tc1_str = str
402
+ else
403
+ @tc2 = time
404
+ @tc2_str = str
405
+ end
406
+ return str
407
+ end
408
+ end
409
+
410
+ def format_with_subsec(time)
411
+ if @tc1_str && Fluent::EventTime.eq?(@tc1, time)
412
+ return @tc1_str
413
+ elsif @tc2_str && Fluent::EventTime.eq?(@tc2, time)
414
+ return @tc2_str
415
+ else
416
+ str = format_nocache(time)
417
+ if @tc1 < @tc2
418
+ @tc1 = time
419
+ @tc1_str = str
420
+ else
421
+ @tc2 = time
422
+ @tc2_str = str
423
+ end
424
+ return str
425
+ end
426
+ end
427
+
428
+ ## Dynamically defined in #initialize
429
+ # def format(time)
430
+ # end
431
+
432
+ def format_nocache(time)
433
+ @format_nocache.call(time)
434
+ end
435
+ end
436
+
437
+ class NumericTimeFormatter < TimeFormatter
438
+ def initialize(type, localtime = nil, timezone = nil)
439
+ @cache1_key = @cache1_time = @cache2_key = @cache2_time = nil
440
+
441
+ if type == :unixtime
442
+ define_singleton_method(:format, method(:format_unixtime))
443
+ define_singleton_method(:call, method(:format_unixtime))
444
+ else # :float
445
+ define_singleton_method(:format, method(:format_float))
446
+ define_singleton_method(:call, method(:format_float))
447
+ end
448
+ end
449
+
450
+ def format_unixtime(time)
451
+ time.to_i.to_s
452
+ end
453
+
454
+ def format_float(time)
455
+ if time.is_a?(Fluent::EventTime) || time.is_a?(Time)
456
+ # 10.015 secs for 10_000_000 times call on MacBookAir
457
+ nsec_s = time.nsec.to_s
458
+ nsec_s = '0' * (9 - nsec_s.size) if nsec_s.size < 9
459
+ "#{time.sec}.#{nsec_s}"
460
+ else # integer (or float?)
461
+ time.to_f.to_s
462
+ end
463
+ end
464
+ end
465
+
466
+ # MixedTimeParser is available when time_type is set to :mixed
467
+ #
468
+ # Use Case 1: primary format is specified explicitly in time_format
469
+ # time_type mixed
470
+ # time_format %iso8601
471
+ # time_format_fallbacks unixtime
472
+ # Use Case 2: time_format is omitted
473
+ # time_type mixed
474
+ # time_format_fallbacks %iso8601, unixtime
475
+ #
476
+ class MixedTimeParser < TimeParser # to include TimeParseError
477
+ def initialize(type, format = nil, localtime = nil, timezone = nil, utc = nil, force_localtime = nil, fallbacks = [])
478
+ @parsers = []
479
+ fallbacks.unshift(format).each do |fallback|
480
+ next unless fallback
481
+ case fallback
482
+ when 'unixtime', 'float'
483
+ @parsers << NumericTimeParser.new(fallback, localtime, timezone)
484
+ else
485
+ if force_localtime
486
+ @parsers << TimeParser.new(fallback, true, nil)
487
+ else
488
+ localtime = localtime && (timezone.nil? && !utc)
489
+ @parsers << TimeParser.new(fallback, localtime, timezone)
490
+ end
491
+ end
492
+ end
493
+ end
494
+
495
+ def parse(value)
496
+ @parsers.each do |parser|
497
+ begin
498
+ Float(value) if parser.class == Fluent::NumericTimeParser
499
+ rescue
500
+ next
501
+ end
502
+ begin
503
+ return parser.parse(value)
504
+ rescue
505
+ # skip TimeParseError
506
+ end
507
+ end
508
+ fallback_class = @parsers.collect do |parser| parser.class end.join(",")
509
+ raise TimeParseError, "invalid time format: value = #{value}, even though fallbacks: #{fallback_class}"
510
+ end
511
+ end
512
+
513
+ end