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
data/lib/fluent/log.rb ADDED
@@ -0,0 +1,775 @@
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 'forwardable'
18
+ require 'logger'
19
+
20
+ module Fluent
21
+ class Log
22
+ module TTYColor
23
+ RESET = "\033]R"
24
+ CRE = "\033[K"
25
+ CLEAR = "\033c"
26
+ NORMAL = "\033[0;39m"
27
+ RED = "\033[1;31m"
28
+ GREEN = "\033[1;32m"
29
+ YELLOW = "\033[1;33m"
30
+ BLUE = "\033[1;34m"
31
+ MAGENTA = "\033[1;35m"
32
+ CYAN = "\033[1;36m"
33
+ WHITE = "\033[1;37m"
34
+ end
35
+
36
+ LEVEL_TRACE = 0
37
+ LEVEL_DEBUG = 1
38
+ LEVEL_INFO = 2
39
+ LEVEL_WARN = 3
40
+ LEVEL_ERROR = 4
41
+ LEVEL_FATAL = 5
42
+
43
+ LEVEL_TEXT = %w(trace debug info warn error fatal)
44
+
45
+ LOG_EVENT_TAG_PREFIX = 'fluent'
46
+ LOG_EVENT_LABEL = '@FLUENT_LOG'
47
+ LOG_TYPE_SUPERVISOR = :supervisor # only in supervisor, or a worker with --no-supervisor
48
+ LOG_TYPE_WORKER0 = :worker0 # only in a worker with worker_id=0 (without showing worker id)
49
+ LOG_TYPE_DEFAULT = :default # show logs in all supervisor/workers, with worker id in workers (default)
50
+
51
+ LOG_TYPES = [LOG_TYPE_SUPERVISOR, LOG_TYPE_WORKER0, LOG_TYPE_DEFAULT].freeze
52
+ LOG_ROTATE_AGE = %w(daily weekly monthly)
53
+
54
+ IGNORE_SAME_LOG_MAX_CACHE_SIZE = 1000 # If need, make this an option of system config.
55
+
56
+ def self.str_to_level(log_level_str)
57
+ case log_level_str.downcase
58
+ when "trace" then LEVEL_TRACE
59
+ when "debug" then LEVEL_DEBUG
60
+ when "info" then LEVEL_INFO
61
+ when "warn" then LEVEL_WARN
62
+ when "error" then LEVEL_ERROR
63
+ when "fatal" then LEVEL_FATAL
64
+ else raise "Unknown log level: level = #{log_level_str}"
65
+ end
66
+ end
67
+
68
+ def self.event_tags
69
+ LEVEL_TEXT.map{|t| "#{LOG_EVENT_TAG_PREFIX}.#{t}" }
70
+ end
71
+
72
+ # Create a unique path for each process.
73
+ #
74
+ # >>> per_process_path("C:/tmp/test.log", :worker, 1)
75
+ # C:/tmp/test-1.log
76
+ # >>> per_process_path("C:/tmp/test.log", :supervisor, 0)
77
+ # C:/tmp/test-supervisor-0.log
78
+ def self.per_process_path(path, process_type, worker_id)
79
+ path = Pathname(path)
80
+ ext = path.extname
81
+
82
+ if process_type == :supervisor
83
+ suffix = "-#{process_type}-0#{ext}" # "-0" for backword compatibility.
84
+ else
85
+ suffix = "-#{worker_id}#{ext}"
86
+ end
87
+ return path.sub_ext(suffix).to_s
88
+ end
89
+
90
+ def initialize(logger, opts={})
91
+ # When ServerEngine changes the logger.level, the Fluentd logger level should also change.
92
+ # So overwrites logger.level= below.
93
+ # However, currently Fluentd doesn't use the ServerEngine's reloading feature,
94
+ # so maybe we don't need this overwriting anymore.
95
+ orig_logger_level_setter = logger.class.public_instance_method(:level=).bind(logger)
96
+ me = self
97
+ # The original ruby logger sets the number as each log level like below.
98
+ # DEBUG = 0
99
+ # INFO = 1
100
+ # WARN = 2
101
+ # ERROR = 3
102
+ # FATAL = 4
103
+ # Serverengine use this original log number. In addition to this, serverengine sets -1 as TRACE level.
104
+ # TRACE = -1
105
+ #
106
+ # On the other hand, in fluentd side, it sets the number like below.
107
+ # TRACE = 0
108
+ # DEBUG = 1
109
+ # INFO = 2
110
+ # WARN = 3
111
+ # ERROR = 4
112
+ # FATAL = 5
113
+ #
114
+ # Then fluentd's level is set as serverengine's level + 1.
115
+ # So if serverengine's logger level is changed, fluentd's log level will be changed to that + 1.
116
+ logger.define_singleton_method(:level=) {|level| orig_logger_level_setter.call(level); me.level = self.level + 1 }
117
+
118
+ @path = opts[:path]
119
+ @logger = logger
120
+ @out = logger.instance_variable_get(:@logdev)
121
+ @level = logger.level + 1
122
+ @debug_mode = false
123
+ @log_event_enabled = false
124
+ @depth_offset = 1
125
+ @format = nil
126
+ @time_format = nil
127
+ @formatter = nil
128
+
129
+ self.format = opts.fetch(:format, :text)
130
+ self.time_format = opts[:time_format] if opts.key?(:time_format)
131
+ enable_color out.tty?
132
+ # TODO: This variable name is unclear so we should change to better name.
133
+ @threads_exclude_events = []
134
+
135
+ # Fluent::Engine requires Fluent::Log, so we must take that object lazily
136
+ @engine = Fluent.const_get('Engine')
137
+ @optional_header = nil
138
+ @optional_attrs = nil
139
+
140
+ @suppress_repeated_stacktrace = opts[:suppress_repeated_stacktrace]
141
+ @forced_stacktrace_level = nil
142
+ @ignore_repeated_log_interval = opts[:ignore_repeated_log_interval]
143
+ @ignore_same_log_interval = opts[:ignore_same_log_interval]
144
+
145
+ @process_type = opts[:process_type] # :supervisor, :worker0, :workers Or :standalone
146
+ @process_type ||= :standalone # to keep behavior of existing code
147
+ case @process_type
148
+ when :supervisor
149
+ @show_supervisor_log = true
150
+ @show_worker0_log = false
151
+ when :worker0
152
+ @show_supervisor_log = false
153
+ @show_worker0_log = true
154
+ when :workers
155
+ @show_supervisor_log = false
156
+ @show_worker0_log = false
157
+ when :standalone
158
+ @show_supervisor_log = true
159
+ @show_worker0_log = true
160
+ else
161
+ raise "BUG: unknown process type for logger:#{@process_type}"
162
+ end
163
+ @worker_id = opts[:worker_id]
164
+ @worker_id_part = "##{@worker_id} " # used only for :default log type in workers
165
+ end
166
+
167
+ def dup
168
+ dl_opts = {}
169
+ dl_opts[:log_level] = @level - 1
170
+ logger = ServerEngine::DaemonLogger.new(@out, dl_opts)
171
+ clone = self.class.new(logger, suppress_repeated_stacktrace: @suppress_repeated_stacktrace, process_type: @process_type,
172
+ worker_id: @worker_id, ignore_repeated_log_interval: @ignore_repeated_log_interval,
173
+ ignore_same_log_interval: @ignore_same_log_interval)
174
+ clone.format = @format
175
+ clone.time_format = @time_format
176
+ clone.log_event_enabled = @log_event_enabled
177
+ clone.force_stacktrace_level(@forced_stacktrace_level)
178
+ # optional headers/attrs are not copied, because new PluginLogger should have another one of it
179
+ clone
180
+ end
181
+
182
+ attr_reader :format
183
+ attr_reader :time_format
184
+ attr_accessor :log_event_enabled, :ignore_repeated_log_interval, :ignore_same_log_interval, :suppress_repeated_stacktrace
185
+ attr_accessor :out
186
+ # Strictly speaking, we should also change @logger.level when the setter of @level is called.
187
+ # Currently, we don't need to do it, since Fluentd::Log doesn't use ServerEngine::DaemonLogger.level.
188
+ # Since We overwrites logger.level= so that @logger.level is applied to @level,
189
+ # we need to find a good way to do this, otherwise we will end up in an endless loop.
190
+ attr_accessor :level
191
+ attr_accessor :optional_header, :optional_attrs
192
+
193
+ def logdev=(logdev)
194
+ @out = logdev
195
+ @logger.instance_variable_set(:@logdev, logdev)
196
+ nil
197
+ end
198
+
199
+ def format=(fmt)
200
+ return if @format == fmt
201
+
202
+ @time_format = '%Y-%m-%d %H:%M:%S %z'
203
+ @time_formatter = Strftime.new(@time_format) rescue nil
204
+
205
+ case fmt
206
+ when :text
207
+ @format = :text
208
+ @formatter = Proc.new { |type, time, level, msg|
209
+ r = caller_line(type, time, @depth_offset, level)
210
+ r << msg
211
+ r
212
+ }
213
+ when :json
214
+ @format = :json
215
+ @formatter = Proc.new { |type, time, level, msg|
216
+ r = {
217
+ 'time' => format_time(time),
218
+ 'level' => LEVEL_TEXT[level],
219
+ 'message' => msg
220
+ }
221
+ if wid = get_worker_id(type)
222
+ r['worker_id'] = wid
223
+ end
224
+ JSON.generate(r)
225
+ }
226
+ end
227
+
228
+ nil
229
+ end
230
+
231
+ def time_format=(time_fmt)
232
+ @time_format = time_fmt
233
+ @time_formatter = Strftime.new(@time_format) rescue nil
234
+ end
235
+
236
+ def stdout?
237
+ @out == $stdout
238
+ end
239
+
240
+ def reopen!
241
+ @out.reopen(@path, "a") if @path && @path != "-"
242
+ nil
243
+ end
244
+
245
+ def force_stacktrace_level?
246
+ not @forced_stacktrace_level.nil?
247
+ end
248
+
249
+ def force_stacktrace_level(level)
250
+ @forced_stacktrace_level = level
251
+ end
252
+
253
+ def enable_debug(b=true)
254
+ @debug_mode = b
255
+ self
256
+ end
257
+
258
+ def enable_event(b=true)
259
+ @log_event_enabled = b
260
+ self
261
+ end
262
+
263
+ # If you want to suppress event emitting in specific thread, please use this method.
264
+ # Events in passed thread are never emitted.
265
+ def disable_events(thread)
266
+ # this method is not symmetric with #enable_event.
267
+ @threads_exclude_events.push(thread) unless @threads_exclude_events.include?(thread)
268
+ end
269
+
270
+ def enable_color?
271
+ !@color_reset.empty?
272
+ end
273
+
274
+ def enable_color(b=true)
275
+ if b
276
+ @color_trace = TTYColor::BLUE
277
+ @color_debug = TTYColor::WHITE
278
+ @color_info = TTYColor::GREEN
279
+ @color_warn = TTYColor::YELLOW
280
+ @color_error = TTYColor::MAGENTA
281
+ @color_fatal = TTYColor::RED
282
+ @color_reset = TTYColor::NORMAL
283
+ else
284
+ @color_trace = ''
285
+ @color_debug = ''
286
+ @color_info = ''
287
+ @color_warn = ''
288
+ @color_error = ''
289
+ @color_fatal = ''
290
+ @color_reset = ''
291
+ end
292
+ self
293
+ end
294
+
295
+ def log_type(args)
296
+ if LOG_TYPES.include?(args.first)
297
+ args.shift
298
+ else
299
+ LOG_TYPE_DEFAULT
300
+ end
301
+ end
302
+
303
+ # TODO: skip :worker0 logs when Fluentd gracefully restarted
304
+ def skipped_type?(type)
305
+ case type
306
+ when LOG_TYPE_DEFAULT
307
+ false
308
+ when LOG_TYPE_WORKER0
309
+ !@show_worker0_log
310
+ when LOG_TYPE_SUPERVISOR
311
+ !@show_supervisor_log
312
+ else
313
+ raise "BUG: unknown log type:#{type}"
314
+ end
315
+ end
316
+
317
+ def on_trace
318
+ return if @level > LEVEL_TRACE
319
+ yield
320
+ end
321
+
322
+ def trace(*args, &block)
323
+ return if @level > LEVEL_TRACE
324
+ type = log_type(args)
325
+ return if skipped_type?(type)
326
+ args << block.call if block
327
+ time, msg = event(:trace, args)
328
+ return if time.nil?
329
+ puts [@color_trace, @formatter.call(type, time, LEVEL_TRACE, msg), @color_reset].join
330
+ rescue
331
+ # logger should not raise an exception. This rescue prevents unexpected behaviour.
332
+ end
333
+ alias TRACE trace
334
+
335
+ def trace_backtrace(backtrace=$!.backtrace, type: :default)
336
+ dump_stacktrace(type, backtrace, LEVEL_TRACE)
337
+ end
338
+
339
+ def on_debug
340
+ return if @level > LEVEL_DEBUG
341
+ yield
342
+ end
343
+
344
+ def debug(*args, &block)
345
+ return if @level > LEVEL_DEBUG
346
+ type = log_type(args)
347
+ return if skipped_type?(type)
348
+ args << block.call if block
349
+ time, msg = event(:debug, args)
350
+ return if time.nil?
351
+ puts [@color_debug, @formatter.call(type, time, LEVEL_DEBUG, msg), @color_reset].join
352
+ rescue
353
+ end
354
+ alias DEBUG debug
355
+
356
+ def debug_backtrace(backtrace=$!.backtrace, type: :default)
357
+ dump_stacktrace(type, backtrace, LEVEL_DEBUG)
358
+ end
359
+
360
+ def on_info
361
+ return if @level > LEVEL_INFO
362
+ yield
363
+ end
364
+
365
+ def info(*args, &block)
366
+ return if @level > LEVEL_INFO
367
+ type = log_type(args)
368
+ return if skipped_type?(type)
369
+ args << block.call if block
370
+ time, msg = event(:info, args)
371
+ return if time.nil?
372
+ puts [@color_info, @formatter.call(type, time, LEVEL_INFO, msg), @color_reset].join
373
+ rescue
374
+ end
375
+ alias INFO info
376
+
377
+ def info_backtrace(backtrace=$!.backtrace, type: :default)
378
+ dump_stacktrace(type, backtrace, LEVEL_INFO)
379
+ end
380
+
381
+ def on_warn
382
+ return if @level > LEVEL_WARN
383
+ yield
384
+ end
385
+
386
+ def warn(*args, &block)
387
+ return if @level > LEVEL_WARN
388
+ type = log_type(args)
389
+ return if skipped_type?(type)
390
+ args << block.call if block
391
+ time, msg = event(:warn, args)
392
+ return if time.nil?
393
+ puts [@color_warn, @formatter.call(type, time, LEVEL_WARN, msg), @color_reset].join
394
+ rescue
395
+ end
396
+ alias WARN warn
397
+
398
+ def warn_backtrace(backtrace=$!.backtrace, type: :default)
399
+ dump_stacktrace(type, backtrace, LEVEL_WARN)
400
+ end
401
+
402
+ def on_error
403
+ return if @level > LEVEL_ERROR
404
+ yield
405
+ end
406
+
407
+ def error(*args, &block)
408
+ return if @level > LEVEL_ERROR
409
+ type = log_type(args)
410
+ return if skipped_type?(type)
411
+ args << block.call if block
412
+ time, msg = event(:error, args)
413
+ return if time.nil?
414
+ puts [@color_error, @formatter.call(type, time, LEVEL_ERROR, msg), @color_reset].join
415
+ rescue
416
+ end
417
+ alias ERROR error
418
+
419
+ def error_backtrace(backtrace=$!.backtrace, type: :default)
420
+ dump_stacktrace(type, backtrace, LEVEL_ERROR)
421
+ end
422
+
423
+ def on_fatal
424
+ return if @level > LEVEL_FATAL
425
+ yield
426
+ end
427
+
428
+ def fatal(*args, &block)
429
+ return if @level > LEVEL_FATAL
430
+ type = log_type(args)
431
+ return if skipped_type?(type)
432
+ args << block.call if block
433
+ time, msg = event(:fatal, args)
434
+ return if time.nil?
435
+ puts [@color_fatal, @formatter.call(type, time, LEVEL_FATAL, msg), @color_reset].join
436
+ rescue
437
+ end
438
+ alias FATAL fatal
439
+
440
+ def fatal_backtrace(backtrace=$!.backtrace, type: :default)
441
+ dump_stacktrace(type, backtrace, LEVEL_FATAL)
442
+ end
443
+
444
+ def puts(msg)
445
+ @logger << msg + "\n"
446
+ @out.flush
447
+ msg
448
+ rescue
449
+ # FIXME
450
+ nil
451
+ end
452
+
453
+ def write(data)
454
+ @out.write(data)
455
+ end
456
+ # We need `#<<` method to use this logger class with other
457
+ # libraries such as aws-sdk
458
+ alias << write
459
+
460
+ def flush
461
+ @out.flush
462
+ end
463
+
464
+ def reset
465
+ @out.reset if @out.respond_to?(:reset)
466
+ end
467
+
468
+ CachedLog = Struct.new(:msg, :time)
469
+
470
+ def ignore_repeated_log?(key, time, message)
471
+ cached_log = Thread.current[key]
472
+ return false if cached_log.nil?
473
+ (cached_log.msg == message) && (time - cached_log.time <= @ignore_repeated_log_interval)
474
+ end
475
+
476
+ def ignore_same_log?(time, message)
477
+ cached_log = Thread.current[:last_same_log]
478
+ if cached_log.nil?
479
+ Thread.current[:last_same_log] = {message => time}
480
+ return false
481
+ end
482
+
483
+ prev_time = cached_log[message]
484
+ if prev_time
485
+ if (time - prev_time) <= @ignore_same_log_interval
486
+ true
487
+ else
488
+ cached_log[message] = time
489
+ false
490
+ end
491
+ else
492
+ if cached_log.size >= IGNORE_SAME_LOG_MAX_CACHE_SIZE
493
+ cached_log.reject! do |_, cached_time|
494
+ (time - cached_time) > @ignore_same_log_interval
495
+ end
496
+ end
497
+ # If the size is still over, we have no choice but to clear it.
498
+ cached_log.clear if cached_log.size >= IGNORE_SAME_LOG_MAX_CACHE_SIZE
499
+ cached_log[message] = time
500
+ false
501
+ end
502
+ end
503
+
504
+ def suppress_stacktrace?(backtrace)
505
+ cached_log = Thread.current[:last_repeated_stacktrace]
506
+ return false if cached_log.nil?
507
+ cached_log.msg == backtrace
508
+ end
509
+
510
+ def dump_stacktrace(type, backtrace, level)
511
+ return if @level > level
512
+
513
+ dump_stacktrace_internal(
514
+ type,
515
+ backtrace,
516
+ force_stacktrace_level? ? @forced_stacktrace_level : level,
517
+ )
518
+ end
519
+
520
+ def dump_stacktrace_internal(type, backtrace, level)
521
+ return if @level > level
522
+
523
+ time = Time.now
524
+
525
+ if @format == :text
526
+ line = caller_line(type, time, 5, level)
527
+ if @ignore_repeated_log_interval && ignore_repeated_log?(:last_repeated_stacktrace, time, backtrace)
528
+ return
529
+ elsif @suppress_repeated_stacktrace && suppress_stacktrace?(backtrace)
530
+ puts [" ", line, 'suppressed same stacktrace'].join
531
+ Thread.current[:last_repeated_stacktrace] = CachedLog.new(backtrace, time) if @ignore_repeated_log_interval
532
+ else
533
+ backtrace.each { |msg|
534
+ puts [" ", line, msg].join
535
+ }
536
+ Thread.current[:last_repeated_stacktrace] = CachedLog.new(backtrace, time) if @suppress_repeated_stacktrace
537
+ end
538
+ else
539
+ r = {
540
+ 'time' => format_time(time),
541
+ 'level' => LEVEL_TEXT[level],
542
+ }
543
+ if wid = get_worker_id(type)
544
+ r['worker_id'] = wid
545
+ end
546
+
547
+ if @ignore_repeated_log_interval && ignore_repeated_log?(:last_repeated_stacktrace, time, backtrace)
548
+ return
549
+ elsif @suppress_repeated_stacktrace && suppress_stacktrace?(backtrace)
550
+ r['message'] = 'suppressed same stacktrace'
551
+ Thread.current[:last_repeated_stacktrace] = CachedLog.new(backtrace, time) if @ignore_repeated_log_interval
552
+ else
553
+ r['message'] = backtrace.join("\n")
554
+ Thread.current[:last_repeated_stacktrace] = CachedLog.new(backtrace, time) if @suppress_repeated_stacktrace
555
+ end
556
+
557
+ puts JSON.generate(r)
558
+ end
559
+
560
+ nil
561
+ end
562
+
563
+ def get_worker_id(type)
564
+ if type == :default && (@process_type == :worker0 || @process_type == :workers)
565
+ @worker_id
566
+ else
567
+ nil
568
+ end
569
+ end
570
+
571
+ def event(level, args)
572
+ time = Time.now
573
+ message = @optional_header ? @optional_header.dup : ''
574
+ map = @optional_attrs ? @optional_attrs.dup : {}
575
+ args.each {|a|
576
+ if a.is_a?(Hash)
577
+ a.each_pair {|k,v|
578
+ map[k.to_s] = v
579
+ }
580
+ else
581
+ message << a.to_s
582
+ end
583
+ }
584
+
585
+ map.each_pair {|k,v|
586
+ if k == "error".freeze && v.is_a?(Exception) && !map.has_key?("error_class")
587
+ message << " error_class=#{v.class.to_s} error=#{v.to_s.inspect}"
588
+ else
589
+ message << " #{k}=#{v.inspect}"
590
+ end
591
+ }
592
+
593
+ if @ignore_same_log_interval
594
+ if ignore_same_log?(time, message)
595
+ return nil, nil
596
+ end
597
+ elsif @ignore_repeated_log_interval
598
+ if ignore_repeated_log?(:last_repeated_log, time, message)
599
+ return nil, nil
600
+ else
601
+ Thread.current[:last_repeated_log] = CachedLog.new(message, time)
602
+ end
603
+ end
604
+
605
+ if @log_event_enabled && !@threads_exclude_events.include?(Thread.current)
606
+ record = map.dup
607
+ record.keys.each {|key|
608
+ record[key] = record[key].inspect unless record[key].respond_to?(:to_msgpack)
609
+ }
610
+ record['message'] = message.dup
611
+ @engine.push_log_event("#{LOG_EVENT_TAG_PREFIX}.#{level}", Fluent::EventTime.from_time(time), record)
612
+ end
613
+
614
+ return time, message
615
+ end
616
+
617
+ def caller_line(type, time, depth, level)
618
+ worker_id_part = if type == :default && (@process_type == :worker0 || @process_type == :workers)
619
+ @worker_id_part
620
+ else
621
+ "".freeze
622
+ end
623
+ log_msg = "#{format_time(time)} [#{LEVEL_TEXT[level]}]: #{worker_id_part}"
624
+ if @debug_mode
625
+ line = caller(depth+1)[0]
626
+ if match = /^(.+?):(\d+)(?::in `(.*)')?/.match(line)
627
+ file = match[1].split('/')[-2,2].join('/')
628
+ line = match[2]
629
+ method = match[3]
630
+ return "#{log_msg}#{file}:#{line}:#{method}: "
631
+ end
632
+ end
633
+ return log_msg
634
+ end
635
+
636
+ def format_time(time)
637
+ @time_formatter ? @time_formatter.exec(time) : time.strftime(@time_format)
638
+ end
639
+ end
640
+
641
+
642
+ # PluginLogger has own log level separated from global $log object.
643
+ # This class enables log_level option in each plugin.
644
+ #
645
+ # PluginLogger has same functionality as Log but some methods are forwarded to internal logger
646
+ # for keeping logging action consistency in the process, e.g. color, event, etc.
647
+ class PluginLogger < Log
648
+ def initialize(logger)
649
+ @logger = logger
650
+ @level = @logger.level
651
+ @format = nil
652
+ @depth_offset = 2
653
+ if logger.instance_variable_defined?(:@suppress_repeated_stacktrace)
654
+ @suppress_repeated_stacktrace = logger.instance_variable_get(:@suppress_repeated_stacktrace)
655
+ end
656
+ if logger.instance_variable_defined?(:@forced_stacktrace_level)
657
+ @forced_stacktrace_level = logger.instance_variable_get(:@forced_stacktrace_level)
658
+ end
659
+ if logger.instance_variable_defined?(:@ignore_repeated_log_interval)
660
+ @ignore_repeated_log_interval = logger.instance_variable_get(:@ignore_repeated_log_interval)
661
+ end
662
+ if logger.instance_variable_defined?(:@ignore_same_log_interval)
663
+ @ignore_same_log_interval = logger.instance_variable_get(:@ignore_same_log_interval)
664
+ end
665
+
666
+ self.format = @logger.format
667
+ self.time_format = @logger.time_format
668
+ enable_color @logger.enable_color?
669
+ end
670
+
671
+ def level=(log_level_str)
672
+ @level = Log.str_to_level(log_level_str)
673
+ end
674
+
675
+ alias orig_format= format=
676
+ alias orig_time_format= time_format=
677
+ alias orig_enable_color enable_color
678
+
679
+ def format=(fmt)
680
+ self.orig_format = fmt
681
+ @logger.format = fmt
682
+ end
683
+
684
+ def time_format=(fmt)
685
+ self.orig_time_format = fmt
686
+ @logger.time_format = fmt
687
+ end
688
+
689
+ def enable_color(b = true)
690
+ orig_enable_color b
691
+ @logger.enable_color b
692
+ end
693
+
694
+ extend Forwardable
695
+ def_delegators '@logger', :get_worker_id, :enable_color?, :enable_debug, :enable_event,
696
+ :disable_events, :log_event_enabled, :log_event_enabled=, :event, :caller_line, :puts, :write,
697
+ :<<, :flush, :reset, :out, :out=, :optional_header, :optional_header=, :optional_attrs,
698
+ :optional_attrs=
699
+ end
700
+
701
+
702
+ module PluginLoggerMixin
703
+ def self.included(klass)
704
+ klass.instance_eval {
705
+ desc 'Allows the user to set different levels of logging for each plugin.'
706
+ config_param :@log_level, :string, default: nil, alias: :log_level # 'log_level' will be warned as deprecated
707
+ }
708
+ end
709
+
710
+ def initialize
711
+ super
712
+
713
+ @log = $log # Use $log object directly by default
714
+ end
715
+
716
+ attr_accessor :log
717
+
718
+ def configure(conf)
719
+ super
720
+
721
+ if plugin_id_configured? || conf['@log_level']
722
+ @log = PluginLogger.new($log.dup) unless @log.is_a?(PluginLogger)
723
+ @log.optional_attrs = {}
724
+
725
+ if level = conf['@log_level']
726
+ @log.level = level
727
+ end
728
+
729
+ if plugin_id_configured?
730
+ @log.optional_header = "[#{@id}] "
731
+ end
732
+ end
733
+ end
734
+
735
+ def terminate
736
+ super
737
+ @log.reset
738
+ end
739
+ end
740
+
741
+ # This class delegates some methods which are used in `Fluent::Logger` to a instance variable(`dev`) in `Logger::LogDevice` class
742
+ # https://github.com/ruby/ruby/blob/7b2d47132ff8ee950b0f978ab772dee868d9f1b0/lib/logger.rb#L661
743
+ class LogDeviceIO < ::Logger::LogDevice
744
+ def flush
745
+ if @dev.respond_to?(:flush)
746
+ @dev.flush
747
+ else
748
+ super
749
+ end
750
+ end
751
+
752
+ def tty?
753
+ if @dev.respond_to?(:tty?)
754
+ @dev.tty?
755
+ else
756
+ super
757
+ end
758
+ end
759
+
760
+ def sync=(v)
761
+ if @dev.respond_to?(:sync=)
762
+ @dev.sync = v
763
+ else
764
+ super
765
+ end
766
+ end
767
+
768
+ def reopen(path, mode)
769
+ if mode != 'a'
770
+ raise "Unsupported mode: #{mode}"
771
+ end
772
+ super(path)
773
+ end
774
+ end
775
+ end