fluentd 1.13.3 → 1.16.5

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 (179) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/{bug_report.yaml → bug_report.yml} +2 -0
  3. data/.github/ISSUE_TEMPLATE/config.yml +2 -2
  4. data/.github/ISSUE_TEMPLATE/{feature_request.yaml → feature_request.yml} +1 -0
  5. data/.github/workflows/stale-actions.yml +11 -9
  6. data/.github/workflows/test.yml +32 -0
  7. data/CHANGELOG.md +490 -10
  8. data/CONTRIBUTING.md +2 -2
  9. data/MAINTAINERS.md +7 -5
  10. data/README.md +3 -23
  11. data/Rakefile +1 -1
  12. data/SECURITY.md +14 -0
  13. data/fluentd.gemspec +7 -8
  14. data/lib/fluent/command/cat.rb +13 -3
  15. data/lib/fluent/command/ctl.rb +6 -3
  16. data/lib/fluent/command/fluentd.rb +73 -65
  17. data/lib/fluent/command/plugin_config_formatter.rb +1 -1
  18. data/lib/fluent/compat/output.rb +9 -6
  19. data/lib/fluent/config/dsl.rb +1 -1
  20. data/lib/fluent/config/error.rb +12 -0
  21. data/lib/fluent/config/literal_parser.rb +2 -2
  22. data/lib/fluent/config/parser.rb +1 -1
  23. data/lib/fluent/config/v1_parser.rb +3 -3
  24. data/lib/fluent/config/yaml_parser/fluent_value.rb +47 -0
  25. data/lib/fluent/config/yaml_parser/loader.rb +108 -0
  26. data/lib/fluent/config/yaml_parser/parser.rb +166 -0
  27. data/lib/fluent/config/yaml_parser/section_builder.rb +107 -0
  28. data/lib/fluent/config/yaml_parser.rb +56 -0
  29. data/lib/fluent/config.rb +14 -1
  30. data/lib/fluent/counter/server.rb +1 -1
  31. data/lib/fluent/counter/validator.rb +3 -3
  32. data/lib/fluent/daemon.rb +2 -4
  33. data/lib/fluent/engine.rb +1 -1
  34. data/lib/fluent/env.rb +4 -0
  35. data/lib/fluent/error.rb +3 -0
  36. data/lib/fluent/event.rb +8 -4
  37. data/lib/fluent/event_router.rb +47 -2
  38. data/lib/fluent/file_wrapper.rb +137 -0
  39. data/lib/fluent/log/console_adapter.rb +66 -0
  40. data/lib/fluent/log.rb +44 -5
  41. data/lib/fluent/match.rb +1 -1
  42. data/lib/fluent/msgpack_factory.rb +6 -1
  43. data/lib/fluent/oj_options.rb +1 -2
  44. data/lib/fluent/plugin/bare_output.rb +49 -8
  45. data/lib/fluent/plugin/base.rb +26 -9
  46. data/lib/fluent/plugin/buf_file.rb +34 -5
  47. data/lib/fluent/plugin/buf_file_single.rb +32 -3
  48. data/lib/fluent/plugin/buffer/file_chunk.rb +1 -1
  49. data/lib/fluent/plugin/buffer.rb +216 -70
  50. data/lib/fluent/plugin/filter.rb +35 -1
  51. data/lib/fluent/plugin/filter_record_transformer.rb +1 -1
  52. data/lib/fluent/plugin/in_forward.rb +2 -2
  53. data/lib/fluent/plugin/in_http.rb +39 -10
  54. data/lib/fluent/plugin/in_monitor_agent.rb +4 -2
  55. data/lib/fluent/plugin/in_sample.rb +1 -1
  56. data/lib/fluent/plugin/in_syslog.rb +13 -1
  57. data/lib/fluent/plugin/in_tail/group_watch.rb +204 -0
  58. data/lib/fluent/plugin/in_tail/position_file.rb +33 -33
  59. data/lib/fluent/plugin/in_tail.rb +216 -84
  60. data/lib/fluent/plugin/in_tcp.rb +47 -2
  61. data/lib/fluent/plugin/input.rb +39 -1
  62. data/lib/fluent/plugin/metrics.rb +119 -0
  63. data/lib/fluent/plugin/metrics_local.rb +96 -0
  64. data/lib/fluent/plugin/multi_output.rb +43 -6
  65. data/lib/fluent/plugin/out_copy.rb +1 -1
  66. data/lib/fluent/plugin/out_exec_filter.rb +2 -2
  67. data/lib/fluent/plugin/out_file.rb +20 -2
  68. data/lib/fluent/plugin/out_forward/ack_handler.rb +19 -4
  69. data/lib/fluent/plugin/out_forward/socket_cache.rb +2 -0
  70. data/lib/fluent/plugin/out_forward.rb +17 -9
  71. data/lib/fluent/plugin/out_secondary_file.rb +39 -22
  72. data/lib/fluent/plugin/output.rb +167 -78
  73. data/lib/fluent/plugin/parser.rb +3 -4
  74. data/lib/fluent/plugin/parser_apache2.rb +1 -1
  75. data/lib/fluent/plugin/parser_json.rb +1 -1
  76. data/lib/fluent/plugin/parser_syslog.rb +1 -1
  77. data/lib/fluent/plugin/storage_local.rb +3 -5
  78. data/lib/fluent/plugin.rb +10 -1
  79. data/lib/fluent/plugin_helper/child_process.rb +3 -0
  80. data/lib/fluent/plugin_helper/event_emitter.rb +8 -1
  81. data/lib/fluent/plugin_helper/event_loop.rb +2 -2
  82. data/lib/fluent/plugin_helper/http_server/server.rb +2 -1
  83. data/lib/fluent/plugin_helper/metrics.rb +129 -0
  84. data/lib/fluent/plugin_helper/record_accessor.rb +1 -1
  85. data/lib/fluent/plugin_helper/retry_state.rb +14 -4
  86. data/lib/fluent/plugin_helper/server.rb +35 -6
  87. data/lib/fluent/plugin_helper/service_discovery.rb +2 -2
  88. data/lib/fluent/plugin_helper/socket.rb +13 -2
  89. data/lib/fluent/plugin_helper/thread.rb +3 -3
  90. data/lib/fluent/plugin_helper.rb +1 -0
  91. data/lib/fluent/plugin_id.rb +3 -2
  92. data/lib/fluent/registry.rb +2 -1
  93. data/lib/fluent/root_agent.rb +6 -0
  94. data/lib/fluent/rpc.rb +4 -3
  95. data/lib/fluent/supervisor.rb +283 -259
  96. data/lib/fluent/system_config.rb +13 -3
  97. data/lib/fluent/test/driver/base.rb +11 -5
  98. data/lib/fluent/test/driver/filter.rb +4 -0
  99. data/lib/fluent/test/startup_shutdown.rb +6 -8
  100. data/lib/fluent/time.rb +21 -20
  101. data/lib/fluent/version.rb +1 -1
  102. data/lib/fluent/win32api.rb +38 -0
  103. data/lib/fluent/winsvc.rb +5 -8
  104. data/templates/new_gem/test/helper.rb.erb +0 -1
  105. data/test/command/test_cat.rb +31 -2
  106. data/test/command/test_ctl.rb +1 -2
  107. data/test/command/test_fluentd.rb +209 -24
  108. data/test/command/test_plugin_config_formatter.rb +0 -1
  109. data/test/compat/test_parser.rb +6 -6
  110. data/test/config/test_system_config.rb +13 -11
  111. data/test/config/test_types.rb +1 -1
  112. data/test/log/test_console_adapter.rb +110 -0
  113. data/test/plugin/in_tail/test_io_handler.rb +26 -8
  114. data/test/plugin/in_tail/test_position_file.rb +48 -59
  115. data/test/plugin/out_forward/test_ack_handler.rb +39 -0
  116. data/test/plugin/out_forward/test_socket_cache.rb +26 -1
  117. data/test/plugin/test_bare_output.rb +14 -1
  118. data/test/plugin/test_base.rb +133 -1
  119. data/test/plugin/test_buf_file.rb +62 -23
  120. data/test/plugin/test_buf_file_single.rb +65 -0
  121. data/test/plugin/test_buffer.rb +267 -3
  122. data/test/plugin/test_buffer_chunk.rb +11 -0
  123. data/test/plugin/test_filter.rb +12 -1
  124. data/test/plugin/test_filter_parser.rb +1 -1
  125. data/test/plugin/test_filter_stdout.rb +2 -2
  126. data/test/plugin/test_in_forward.rb +9 -11
  127. data/test/plugin/test_in_http.rb +65 -3
  128. data/test/plugin/test_in_monitor_agent.rb +216 -11
  129. data/test/plugin/test_in_object_space.rb +9 -3
  130. data/test/plugin/test_in_syslog.rb +35 -0
  131. data/test/plugin/test_in_tail.rb +1393 -385
  132. data/test/plugin/test_in_tcp.rb +87 -2
  133. data/test/plugin/test_in_udp.rb +28 -0
  134. data/test/plugin/test_in_unix.rb +2 -2
  135. data/test/plugin/test_input.rb +12 -1
  136. data/test/plugin/test_metrics.rb +294 -0
  137. data/test/plugin/test_metrics_local.rb +96 -0
  138. data/test/plugin/test_multi_output.rb +25 -1
  139. data/test/plugin/test_out_exec.rb +6 -4
  140. data/test/plugin/test_out_exec_filter.rb +6 -2
  141. data/test/plugin/test_out_file.rb +34 -17
  142. data/test/plugin/test_out_forward.rb +78 -77
  143. data/test/plugin/test_out_http.rb +1 -0
  144. data/test/plugin/test_out_stdout.rb +2 -2
  145. data/test/plugin/test_output.rb +297 -12
  146. data/test/plugin/test_output_as_buffered.rb +44 -44
  147. data/test/plugin/test_output_as_buffered_compress.rb +32 -18
  148. data/test/plugin/test_output_as_buffered_retries.rb +54 -7
  149. data/test/plugin/test_output_as_buffered_secondary.rb +4 -4
  150. data/test/plugin/test_parser_regexp.rb +1 -6
  151. data/test/plugin/test_parser_syslog.rb +1 -1
  152. data/test/plugin_helper/test_cert_option.rb +1 -1
  153. data/test/plugin_helper/test_child_process.rb +38 -16
  154. data/test/plugin_helper/test_event_emitter.rb +29 -0
  155. data/test/plugin_helper/test_http_server_helper.rb +1 -1
  156. data/test/plugin_helper/test_metrics.rb +137 -0
  157. data/test/plugin_helper/test_retry_state.rb +602 -38
  158. data/test/plugin_helper/test_server.rb +78 -6
  159. data/test/plugin_helper/test_timer.rb +2 -2
  160. data/test/test_config.rb +191 -24
  161. data/test/test_event_router.rb +17 -0
  162. data/test/test_file_wrapper.rb +53 -0
  163. data/test/test_formatter.rb +24 -21
  164. data/test/test_log.rb +122 -40
  165. data/test/test_msgpack_factory.rb +32 -0
  166. data/test/test_plugin_classes.rb +102 -0
  167. data/test/test_root_agent.rb +30 -1
  168. data/test/test_supervisor.rb +477 -257
  169. data/test/test_time_parser.rb +22 -0
  170. metadata +55 -34
  171. data/.drone.yml +0 -35
  172. data/.github/workflows/issue-auto-closer.yml +0 -12
  173. data/.github/workflows/linux-test.yaml +0 -36
  174. data/.github/workflows/macos-test.yaml +0 -30
  175. data/.github/workflows/windows-test.yaml +0 -46
  176. data/.gitlab-ci.yml +0 -103
  177. data/lib/fluent/plugin/file_wrapper.rb +0 -187
  178. data/test/plugin/test_file_wrapper.rb +0 -126
  179. data/test/test_logger_initializer.rb +0 -46
@@ -2,12 +2,15 @@ require_relative 'helper'
2
2
  require 'fluent/event_router'
3
3
  require 'fluent/system_config'
4
4
  require 'fluent/supervisor'
5
+ require 'fluent/file_wrapper'
5
6
  require_relative 'test_plugin_classes'
6
7
 
7
8
  require 'net/http'
8
9
  require 'uri'
9
10
  require 'fileutils'
10
11
  require 'tempfile'
12
+ require 'securerandom'
13
+ require 'pathname'
11
14
 
12
15
  if Fluent.windows?
13
16
  require 'win32/event'
@@ -22,33 +25,47 @@ class SupervisorTest < ::Test::Unit::TestCase
22
25
  end
23
26
  end
24
27
 
25
- TMP_DIR = File.expand_path(File.dirname(__FILE__) + "/tmp/supervisor#{ENV['TEST_ENV_NUMBER']}")
26
- TMP_ROOT_DIR = File.join(TMP_DIR, 'root')
28
+ def tmp_dir
29
+ File.join(File.dirname(__FILE__), "tmp", "supervisor#{ENV['TEST_ENV_NUMBER']}", SecureRandom.hex(10))
30
+ end
27
31
 
28
32
  def setup
29
- FileUtils.rm_rf(TMP_DIR)
30
- FileUtils.mkdir_p(TMP_DIR)
33
+ @stored_global_logger = $log
34
+ @tmp_dir = tmp_dir
35
+ @tmp_root_dir = File.join(@tmp_dir, 'root')
36
+ FileUtils.mkdir_p(@tmp_dir)
37
+ @sigdump_path = "/tmp/sigdump-#{Process.pid}.log"
38
+ end
39
+
40
+ def teardown
41
+ $log = @stored_global_logger
42
+ begin
43
+ FileUtils.rm_rf(@tmp_dir)
44
+ rescue Errno::EACCES
45
+ # It may occur on Windows because of delete pending state due to delayed GC.
46
+ # Ruby 3.2 or later doesn't ignore Errno::EACCES:
47
+ # https://github.com/ruby/ruby/commit/983115cf3c8f75b1afbe3274f02c1529e1ce3a81
48
+ end
31
49
  end
32
50
 
33
51
  def write_config(path, data)
34
52
  FileUtils.mkdir_p(File.dirname(path))
35
- File.open(path, "w") {|f| f.write data }
53
+ Fluent::FileWrapper.open(path, "w") {|f| f.write data }
36
54
  end
37
55
 
38
56
 
39
57
  def test_system_config
40
- opts = Fluent::Supervisor.default_options
41
- sv = Fluent::Supervisor.new(opts)
58
+ sv = Fluent::Supervisor.new({})
42
59
  conf_data = <<-EOC
43
60
  <system>
44
61
  rpc_endpoint 127.0.0.1:24445
45
- suppress_repeated_stacktrace true
62
+ suppress_repeated_stacktrace false
46
63
  suppress_config_dump true
47
64
  without_source true
48
65
  enable_get_dump true
49
66
  process_name "process_name"
50
67
  log_level info
51
- root_dir #{TMP_ROOT_DIR}
68
+ root_dir #{@tmp_root_dir}
52
69
  <log>
53
70
  format json
54
71
  time_format %Y
@@ -70,13 +87,13 @@ class SupervisorTest < ::Test::Unit::TestCase
70
87
  sys_conf = sv.__send__(:build_system_config, conf)
71
88
 
72
89
  assert_equal '127.0.0.1:24445', sys_conf.rpc_endpoint
73
- assert_equal true, sys_conf.suppress_repeated_stacktrace
90
+ assert_equal false, sys_conf.suppress_repeated_stacktrace
74
91
  assert_equal true, sys_conf.suppress_config_dump
75
92
  assert_equal true, sys_conf.without_source
76
93
  assert_equal true, sys_conf.enable_get_dump
77
94
  assert_equal "process_name", sys_conf.process_name
78
95
  assert_equal 2, sys_conf.log_level
79
- assert_equal TMP_ROOT_DIR, sys_conf.root_dir
96
+ assert_equal @tmp_root_dir, sys_conf.root_dir
80
97
  assert_equal :json, sys_conf.log.format
81
98
  assert_equal '%Y', sys_conf.log.time_format
82
99
  counter_server = sys_conf.counter_server
@@ -90,26 +107,146 @@ class SupervisorTest < ::Test::Unit::TestCase
90
107
  assert_equal 2, counter_client.timeout
91
108
  end
92
109
 
93
- def test_main_process_signal_handlers
110
+ sub_test_case "yaml config" do
111
+ def parse_yaml(yaml)
112
+ context = Kernel.binding
113
+
114
+ config = nil
115
+ Tempfile.open do |file|
116
+ file.puts(yaml)
117
+ file.flush
118
+ s = Fluent::Config::YamlParser::Loader.new(context).load(Pathname.new(file))
119
+ config = Fluent::Config::YamlParser::Parser.new(s).build.to_element
120
+ end
121
+ config
122
+ end
123
+
124
+ def test_system_config
125
+ sv = Fluent::Supervisor.new({})
126
+ conf_data = <<-EOC
127
+ system:
128
+ rpc_endpoint: 127.0.0.1:24445
129
+ suppress_repeated_stacktrace: true
130
+ suppress_config_dump: true
131
+ without_source: true
132
+ enable_get_dump: true
133
+ process_name: "process_name"
134
+ log_level: info
135
+ root_dir: !fluent/s "#{@tmp_root_dir}"
136
+ log:
137
+ format: json
138
+ time_format: "%Y"
139
+ counter_server:
140
+ bind: 127.0.0.1
141
+ port: 24321
142
+ scope: server1
143
+ backup_path: /tmp/backup
144
+ counter_client:
145
+ host: 127.0.0.1
146
+ port: 24321
147
+ timeout: 2
148
+ EOC
149
+ conf = parse_yaml(conf_data)
150
+ sys_conf = sv.__send__(:build_system_config, conf)
151
+
152
+ counter_client = sys_conf.counter_client
153
+ counter_server = sys_conf.counter_server
154
+ assert_equal(
155
+ [
156
+ '127.0.0.1:24445',
157
+ true,
158
+ true,
159
+ true,
160
+ true,
161
+ "process_name",
162
+ 2,
163
+ @tmp_root_dir,
164
+ :json,
165
+ '%Y',
166
+ '127.0.0.1',
167
+ 24321,
168
+ 'server1',
169
+ '/tmp/backup',
170
+ '127.0.0.1',
171
+ 24321,
172
+ 2,
173
+ ],
174
+ [
175
+ sys_conf.rpc_endpoint,
176
+ sys_conf.suppress_repeated_stacktrace,
177
+ sys_conf.suppress_config_dump,
178
+ sys_conf.without_source,
179
+ sys_conf.enable_get_dump,
180
+ sys_conf.process_name,
181
+ sys_conf.log_level,
182
+ sys_conf.root_dir,
183
+ sys_conf.log.format,
184
+ sys_conf.log.time_format,
185
+ counter_server.bind,
186
+ counter_server.port,
187
+ counter_server.scope,
188
+ counter_server.backup_path,
189
+ counter_client.host,
190
+ counter_client.port,
191
+ counter_client.timeout,
192
+ ])
193
+ end
194
+ end
195
+
196
+ def test_usr1_in_main_process_signal_handlers
94
197
  omit "Windows cannot handle signals" if Fluent.windows?
95
198
 
96
199
  create_info_dummy_logger
97
200
 
98
- opts = Fluent::Supervisor.default_options
99
- sv = Fluent::Supervisor.new(opts)
201
+ sv = Fluent::Supervisor.new({})
100
202
  sv.send(:install_main_process_signal_handlers)
101
203
 
102
- begin
103
- Process.kill :USR1, $$
104
- rescue
105
- end
204
+ Process.kill :USR1, Process.pid
106
205
 
107
206
  sleep 1
108
207
 
109
- info_msg = '[info]: force flushing buffered events' + "\n"
208
+ info_msg = "[info]: force flushing buffered events\n"
110
209
  assert{ $log.out.logs.first.end_with?(info_msg) }
111
210
  ensure
112
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
211
+ $log.out.reset if $log&.out&.respond_to?(:reset)
212
+ end
213
+
214
+ def test_cont_in_main_process_signal_handlers
215
+ omit "Windows cannot handle signals" if Fluent.windows?
216
+
217
+ sv = Fluent::Supervisor.new({})
218
+ sv.send(:install_main_process_signal_handlers)
219
+
220
+ Process.kill :CONT, Process.pid
221
+
222
+ sleep 1
223
+
224
+ assert{ File.exist?(@sigdump_path) }
225
+ ensure
226
+ File.delete(@sigdump_path) if File.exist?(@sigdump_path)
227
+ end
228
+
229
+ def test_term_cont_in_main_process_signal_handlers
230
+ omit "Windows cannot handle signals" if Fluent.windows?
231
+
232
+ create_debug_dummy_logger
233
+
234
+ sv = Fluent::Supervisor.new({})
235
+ sv.send(:install_main_process_signal_handlers)
236
+
237
+ Process.kill :TERM, Process.pid
238
+ Process.kill :CONT, Process.pid
239
+
240
+ sleep 1
241
+
242
+ debug_msg = "[debug]: fluentd main process get SIGTERM\n"
243
+ logs = $log.out.logs
244
+ assert{ logs.any?{|log| log.include?(debug_msg) } }
245
+
246
+ assert{ not File.exist?(@sigdump_path) }
247
+ ensure
248
+ $log.out.reset if $log&.out&.respond_to?(:reset)
249
+ File.delete(@sigdump_path) if File.exist?(@sigdump_path)
113
250
  end
114
251
 
115
252
  def test_main_process_command_handlers
@@ -117,8 +254,7 @@ class SupervisorTest < ::Test::Unit::TestCase
117
254
 
118
255
  create_info_dummy_logger
119
256
 
120
- opts = Fluent::Supervisor.default_options
121
- sv = Fluent::Supervisor.new(opts)
257
+ sv = Fluent::Supervisor.new({})
122
258
  r, w = IO.pipe
123
259
  $stdin = r
124
260
  sv.send(:install_main_process_signal_handlers)
@@ -132,23 +268,21 @@ class SupervisorTest < ::Test::Unit::TestCase
132
268
 
133
269
  sleep 1
134
270
 
135
- info_msg = '[info]: force flushing buffered events' + "\n"
271
+ info_msg = "[info]: force flushing buffered events\n"
136
272
  assert{ $log.out.logs.first.end_with?(info_msg) }
137
273
  ensure
138
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
274
+ $log.out.reset if $log&.out&.respond_to?(:reset)
139
275
  end
140
276
 
141
- def test_supervisor_signal_handler
277
+ def test_usr1_in_supervisor_signal_handler
142
278
  omit "Windows cannot handle signals" if Fluent.windows?
143
279
 
144
280
  create_debug_dummy_logger
145
281
 
146
282
  server = DummyServer.new
147
283
  server.install_supervisor_signal_handlers
148
- begin
149
- Process.kill :USR1, $$
150
- rescue
151
- end
284
+
285
+ Process.kill :USR1, Process.pid
152
286
 
153
287
  sleep 1
154
288
 
@@ -156,12 +290,43 @@ class SupervisorTest < ::Test::Unit::TestCase
156
290
  logs = $log.out.logs
157
291
  assert{ logs.any?{|log| log.include?(debug_msg) } }
158
292
  ensure
159
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
293
+ $log.out.reset if $log&.out&.respond_to?(:reset)
294
+ end
295
+
296
+ def test_cont_in_supervisor_signal_handler
297
+ omit "Windows cannot handle signals" if Fluent.windows?
298
+
299
+ server = DummyServer.new
300
+ server.install_supervisor_signal_handlers
301
+
302
+ Process.kill :CONT, Process.pid
303
+
304
+ sleep 1
305
+
306
+ assert{ File.exist?(@sigdump_path) }
307
+ ensure
308
+ File.delete(@sigdump_path) if File.exist?(@sigdump_path)
309
+ end
310
+
311
+ def test_term_cont_in_supervisor_signal_handler
312
+ omit "Windows cannot handle signals" if Fluent.windows?
313
+
314
+ server = DummyServer.new
315
+ server.install_supervisor_signal_handlers
316
+
317
+ Process.kill :TERM, Process.pid
318
+ Process.kill :CONT, Process.pid
319
+
320
+ assert{ not File.exist?(@sigdump_path) }
321
+ ensure
322
+ File.delete(@sigdump_path) if File.exist?(@sigdump_path)
160
323
  end
161
324
 
162
325
  def test_windows_shutdown_event
163
326
  omit "Only for Windows platform" unless Fluent.windows?
164
327
 
328
+ create_debug_dummy_logger
329
+
165
330
  server = DummyServer.new
166
331
  def server.config
167
332
  {:signame => "TestFluentdEvent"}
@@ -184,7 +349,7 @@ class SupervisorTest < ::Test::Unit::TestCase
184
349
  logs = $log.out.logs
185
350
  assert{ logs.any?{|log| log.include?(debug_msg) } }
186
351
  ensure
187
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
352
+ $log.out.reset if $log&.out&.respond_to?(:reset)
188
353
  end
189
354
 
190
355
  def test_supervisor_event_handler
@@ -210,19 +375,66 @@ class SupervisorTest < ::Test::Unit::TestCase
210
375
  logs = $log.out.logs
211
376
  assert{ logs.any?{|log| log.include?(debug_msg) } }
212
377
  ensure
213
- $log.out.reset if $log && $log.out && $log.out.respond_to?(:reset)
378
+ $log.out.reset if $log&.out&.respond_to?(:reset)
214
379
  end
215
380
 
216
- def test_rpc_server
381
+ data("Normal", {raw_path: "C:\\Windows\\Temp\\sigdump.log", expected: "C:\\Windows\\Temp\\sigdump-#{Process.pid}.log"})
382
+ data("UNIX style", {raw_path: "/Windows/Temp/sigdump.log", expected: "/Windows/Temp/sigdump-#{Process.pid}.log"})
383
+ data("No extension", {raw_path: "C:\\Windows\\Temp\\sigdump", expected: "C:\\Windows\\Temp\\sigdump-#{Process.pid}"})
384
+ data("Multi-extension", {raw_path: "C:\\Windows\\Temp\\sig.dump.bk", expected: "C:\\Windows\\Temp\\sig.dump-#{Process.pid}.bk"})
385
+ def test_fluentsigdump_get_path_with_pid(data)
386
+ path = Fluent::FluentSigdump.get_path_with_pid(data[:raw_path])
387
+ assert_equal(data[:expected], path)
388
+ end
389
+
390
+ def test_supervisor_event_dump_windows
391
+ omit "Only for Windows, alternative to UNIX signals" unless Fluent.windows?
392
+
393
+ server = DummyServer.new
394
+ def server.config
395
+ {:signame => "TestFluentdEvent"}
396
+ end
397
+ server.install_windows_event_handler
398
+
399
+ assert_rr do
400
+ # Have to use mock because `Sigdump.dump` seems to be somehow incompatible with RR.
401
+ # The `mock(server).restart(true) { nil }` line in `test_rpc_server_windows` cause the next error.
402
+ # Failure: test_supervisor_event_dump_windows(SupervisorTest):
403
+ # class()
404
+ # Called 0 times.
405
+ # Expected 1 times.
406
+ # .../Ruby26-x64/lib/ruby/gems/2.6.0/gems/sigdump-0.2.4/lib/sigdump.rb:74:in `block in dump_object_count'
407
+ # 73: ObjectSpace.each_object {|o|
408
+ # 74: c = o.class <-- HERE!
409
+ mock(Sigdump).dump(anything)
410
+
411
+ begin
412
+ sleep 0.1 # Wait for starting windows event thread
413
+ event = Win32::Event.open("TestFluentdEvent_CONT")
414
+ event.set
415
+ event.close
416
+ sleep 1.0 # Wait for dumping
417
+ ensure
418
+ server.stop_windows_event_thread
419
+ end
420
+ end
421
+ end
422
+
423
+ data(:ipv4 => ["0.0.0.0", "127.0.0.1", false],
424
+ :ipv6 => ["[::]", "[::1]", true],
425
+ :localhost_ipv4 => ["localhost", "127.0.0.1", false])
426
+ def test_rpc_server(data)
217
427
  omit "Windows cannot handle signals" if Fluent.windows?
218
428
 
429
+ bindaddr, localhost, ipv6 = data
430
+ omit "IPv6 is not supported on this environment" if ipv6 && !ipv6_enabled?
431
+
219
432
  create_info_dummy_logger
220
433
 
221
- opts = Fluent::Supervisor.default_options
222
- sv = Fluent::Supervisor.new(opts)
434
+ sv = Fluent::Supervisor.new({})
223
435
  conf_data = <<-EOC
224
436
  <system>
225
- rpc_endpoint 0.0.0.0:24447
437
+ rpc_endpoint "#{bindaddr}:24447"
226
438
  </system>
227
439
  EOC
228
440
  conf = Fluent::Config.parse(conf_data, "(test)", "(test_dir)", true)
@@ -235,8 +447,8 @@ class SupervisorTest < ::Test::Unit::TestCase
235
447
  server.run_rpc_server
236
448
 
237
449
  sv.send(:install_main_process_signal_handlers)
238
- response = Net::HTTP.get(URI.parse('http://127.0.0.1:24447/api/plugins.flushBuffers'))
239
- info_msg = '[info]: force flushing buffered events' + "\n"
450
+ response = Net::HTTP.get(URI.parse("http://#{localhost}:24447/api/plugins.flushBuffers"))
451
+ info_msg = "[info]: force flushing buffered events\n"
240
452
 
241
453
  server.stop_rpc_server
242
454
 
@@ -250,16 +462,43 @@ class SupervisorTest < ::Test::Unit::TestCase
250
462
  $log.out.reset if $log.out.is_a?(Fluent::Test::DummyLogDevice)
251
463
  end
252
464
 
253
- def test_rpc_server_windows
465
+ data(:no_port => ["127.0.0.1"],
466
+ :invalid_addr => ["*:24447"])
467
+ def test_invalid_rpc_endpoint(data)
468
+ endpoint = data[0]
469
+
470
+ sv = Fluent::Supervisor.new({})
471
+ conf_data = <<-EOC
472
+ <system>
473
+ rpc_endpoint "#{endpoint}"
474
+ </system>
475
+ EOC
476
+ conf = Fluent::Config.parse(conf_data, "(test)", "(test_dir)", true)
477
+ sys_conf = sv.__send__(:build_system_config, conf)
478
+
479
+ server = DummyServer.new
480
+ server.rpc_endpoint = sys_conf.rpc_endpoint
481
+
482
+ assert_raise(Fluent::ConfigError.new("Invalid rpc_endpoint: #{endpoint}")) do
483
+ server.run_rpc_server
484
+ end
485
+ end
486
+
487
+ data(:ipv4 => ["0.0.0.0", "127.0.0.1", false],
488
+ :ipv6 => ["[::]", "[::1]", true],
489
+ :localhost_ipv4 => ["localhost", "127.0.0.1", true])
490
+ def test_rpc_server_windows(data)
254
491
  omit "Only for windows platform" unless Fluent.windows?
255
492
 
493
+ bindaddr, localhost, ipv6 = data
494
+ omit "IPv6 is not supported on this environment" if ipv6 && !ipv6_enabled?
495
+
256
496
  create_info_dummy_logger
257
497
 
258
- opts = Fluent::Supervisor.default_options
259
- sv = Fluent::Supervisor.new(opts)
498
+ sv = Fluent::Supervisor.new({})
260
499
  conf_data = <<-EOC
261
500
  <system>
262
- rpc_endpoint 0.0.0.0:24447
501
+ rpc_endpoint "#{bindaddr}:24447"
263
502
  </system>
264
503
  EOC
265
504
  conf = Fluent::Config.parse(conf_data, "(test)", "(test_dir)", true)
@@ -277,42 +516,23 @@ class SupervisorTest < ::Test::Unit::TestCase
277
516
  server.run_rpc_server
278
517
 
279
518
  mock(server).restart(true) { nil }
280
- response = Net::HTTP.get(URI.parse('http://127.0.0.1:24447/api/plugins.flushBuffers'))
519
+ response = Net::HTTP.get(URI.parse("http://#{localhost}:24447/api/plugins.flushBuffers"))
281
520
 
282
521
  server.stop_rpc_server
283
522
  assert_equal('{"ok":true}', response)
284
523
  end
285
524
 
286
- def test_load_config
287
- tmp_dir = "#{TMP_DIR}/dir/test_load_config.conf"
288
- conf_info_str = %[
289
- <system>
290
- log_level info
291
- </system>
292
- ]
293
- conf_debug_str = %[
294
- <system>
295
- log_level debug
296
- </system>
297
- ]
298
- now = Time.now
299
- Timecop.freeze(now)
300
-
301
- write_config tmp_dir, conf_info_str
302
-
525
+ def test_serverengine_config
303
526
  params = {}
304
527
  params['workers'] = 1
528
+ params['fluentd_conf_path'] = "fluentd.conf"
305
529
  params['use_v1_config'] = true
306
- params['log_path'] = 'test/tmp/supervisor/log'
307
- params['suppress_repeated_stacktrace'] = true
308
- params['log_level'] = Fluent::Log::LEVEL_INFO
309
530
  params['conf_encoding'] = 'utf-8'
310
- load_config_proc = Proc.new { Fluent::Supervisor.load_config(tmp_dir, params) }
531
+ params['log_level'] = Fluent::Log::LEVEL_INFO
532
+ load_config_proc = Proc.new { Fluent::Supervisor.serverengine_config(params) }
311
533
 
312
- # first call
313
534
  se_config = load_config_proc.call
314
535
  assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
315
- assert_equal true, se_config[:suppress_repeated_stacktrace]
316
536
  assert_equal 'spawn', se_config[:worker_type]
317
537
  assert_equal 1, se_config[:workers]
318
538
  assert_equal false, se_config[:log_stdin]
@@ -320,99 +540,23 @@ class SupervisorTest < ::Test::Unit::TestCase
320
540
  assert_equal false, se_config[:log_stderr]
321
541
  assert_equal true, se_config[:enable_heartbeat]
322
542
  assert_equal false, se_config[:auto_heartbeat]
543
+ assert_equal "fluentd.conf", se_config[:config_path]
323
544
  assert_equal false, se_config[:daemonize]
324
545
  assert_nil se_config[:pid_path]
325
-
326
- # second call immediately(reuse config)
327
- se_config = load_config_proc.call
328
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
329
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
330
- assert_nil pre_config_mtime
331
- assert_nil pre_loadtime
332
-
333
- Timecop.freeze(now + 5)
334
-
335
- # third call after 5 seconds(don't reuse config)
336
- se_config = load_config_proc.call
337
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
338
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
339
- assert_not_nil pre_config_mtime
340
- assert_not_nil pre_loadtime
341
-
342
- # forth call immediately(reuse config)
343
- se_config = load_config_proc.call
344
- # test that pre_config_mtime and pre_loadtime are not changed from previous one because reused pre_config
345
- assert_equal pre_config_mtime, se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
346
- assert_equal pre_loadtime, se_config[:windows_daemon_cmdline][5]['pre_loadtime']
347
-
348
- write_config tmp_dir, conf_debug_str
349
-
350
- # fifth call after changed conf file(don't reuse config)
351
- se_config = load_config_proc.call
352
- assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
353
- ensure
354
- Timecop.return
355
546
  end
356
547
 
357
- def test_load_config_for_logger
358
- tmp_dir = "#{TMP_DIR}/dir/test_load_config_log.conf"
359
- conf_info_str = %[
360
- <system>
361
- <log>
362
- format json
363
- time_format %FT%T.%L%z
364
- </log>
365
- </system>
366
- ]
367
- write_config tmp_dir, conf_info_str
368
- params = {
369
- 'use_v1_config' => true,
370
- 'conf_encoding' => 'utf8',
371
- 'log_level' => Fluent::Log::LEVEL_INFO,
372
- 'log_path' => 'test/tmp/supervisor/log',
373
-
374
- 'workers' => 1,
375
- 'log_format' => :json,
376
- 'log_time_format' => '%FT%T.%L%z',
377
- }
378
-
379
- r = Fluent::Supervisor.load_config(tmp_dir, params)
380
- assert_equal :json, r[:logger].format
381
- assert_equal '%FT%T.%L%z', r[:logger].time_format
382
- end
383
-
384
- def test_load_config_for_daemonize
385
- tmp_dir = "#{TMP_DIR}/dir/test_load_config.conf"
386
- conf_info_str = %[
387
- <system>
388
- log_level info
389
- </system>
390
- ]
391
- conf_debug_str = %[
392
- <system>
393
- log_level debug
394
- </system>
395
- ]
396
-
397
- now = Time.now
398
- Timecop.freeze(now)
399
-
400
- write_config tmp_dir, conf_info_str
401
-
548
+ def test_serverengine_config_for_daemonize
402
549
  params = {}
403
550
  params['workers'] = 1
551
+ params['fluentd_conf_path'] = "fluentd.conf"
404
552
  params['use_v1_config'] = true
405
- params['log_path'] = 'test/tmp/supervisor/log'
406
- params['suppress_repeated_stacktrace'] = true
553
+ params['conf_encoding'] = 'utf-8'
407
554
  params['log_level'] = Fluent::Log::LEVEL_INFO
408
555
  params['daemonize'] = './fluentd.pid'
409
- params['conf_encoding'] = 'utf-8'
410
- load_config_proc = Proc.new { Fluent::Supervisor.load_config(tmp_dir, params) }
556
+ load_config_proc = Proc.new { Fluent::Supervisor.serverengine_config(params) }
411
557
 
412
- # first call
413
558
  se_config = load_config_proc.call
414
559
  assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
415
- assert_equal true, se_config[:suppress_repeated_stacktrace]
416
560
  assert_equal 'spawn', se_config[:worker_type]
417
561
  assert_equal 1, se_config[:workers]
418
562
  assert_equal false, se_config[:log_stdin]
@@ -420,136 +564,212 @@ class SupervisorTest < ::Test::Unit::TestCase
420
564
  assert_equal false, se_config[:log_stderr]
421
565
  assert_equal true, se_config[:enable_heartbeat]
422
566
  assert_equal false, se_config[:auto_heartbeat]
567
+ assert_equal "fluentd.conf", se_config[:config_path]
423
568
  assert_equal true, se_config[:daemonize]
424
569
  assert_equal './fluentd.pid', se_config[:pid_path]
425
-
426
- # second call immediately(reuse config)
427
- se_config = load_config_proc.call
428
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
429
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
430
- assert_nil pre_config_mtime
431
- assert_nil pre_loadtime
432
-
433
- Timecop.freeze(now + 5)
434
-
435
- # third call after 6 seconds(don't reuse config)
436
- se_config = load_config_proc.call
437
- pre_config_mtime = se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
438
- pre_loadtime = se_config[:windows_daemon_cmdline][5]['pre_loadtime']
439
- assert_not_nil pre_config_mtime
440
- assert_not_nil pre_loadtime
441
-
442
- # forth call immediately(reuse config)
443
- se_config = load_config_proc.call
444
- # test that pre_config_mtime and pre_loadtime are not changed from previous one because reused pre_config
445
- assert_equal pre_config_mtime, se_config[:windows_daemon_cmdline][5]['pre_config_mtime']
446
- assert_equal pre_loadtime, se_config[:windows_daemon_cmdline][5]['pre_loadtime']
447
-
448
- write_config tmp_dir, conf_debug_str
449
-
450
- # fifth call after changed conf file(don't reuse config)
451
- se_config = load_config_proc.call
452
- assert_equal Fluent::Log::LEVEL_INFO, se_config[:log_level]
453
- ensure
454
- Timecop.return
455
570
  end
456
571
 
457
- def test_logger
458
- opts = Fluent::Supervisor.default_options
459
- sv = Fluent::Supervisor.new(opts)
460
- log = sv.instance_variable_get(:@log)
461
- log.init(:standalone, 0)
462
- logger = $log.instance_variable_get(:@logger)
572
+ sub_test_case "init logger" do
573
+ data(supervisor: true)
574
+ data(worker: false)
575
+ def test_init_for_logger(supervisor)
576
+ tmp_conf_path = "#{@tmp_dir}/dir/test_init_for_logger.conf"
577
+ conf_info_str = <<~EOC
578
+ <system>
579
+ log_level warn # To suppress logs
580
+ suppress_repeated_stacktrace false
581
+ ignore_repeated_log_interval 10s
582
+ ignore_same_log_interval 20s
583
+ <log>
584
+ format json
585
+ time_format %FT%T.%L%z
586
+ </log>
587
+ </system>
588
+ EOC
589
+ write_config tmp_conf_path, conf_info_str
590
+
591
+ s = Fluent::Supervisor.new({config_path: tmp_conf_path})
592
+ s.configure(supervisor: supervisor)
593
+
594
+ assert_equal :json, $log.format
595
+ assert_equal '%FT%T.%L%z', $log.time_format
596
+ assert_equal false, $log.suppress_repeated_stacktrace
597
+ assert_equal 10, $log.ignore_repeated_log_interval
598
+ assert_equal 20, $log.ignore_same_log_interval
599
+ end
463
600
 
464
- assert_equal Fluent::Log::LEVEL_INFO, $log.level
601
+ data(
602
+ daily_age: 'daily',
603
+ weekly_age: 'weekly',
604
+ monthly_age: 'monthly',
605
+ integer_age: 2,
606
+ )
607
+ def test_logger_with_rotate_age_and_rotate_size(rotate_age)
608
+ config_path = "#{@tmp_dir}/empty.conf"
609
+ write_config config_path, ""
610
+
611
+ sv = Fluent::Supervisor.new(
612
+ config_path: config_path,
613
+ log_path: "#{@tmp_dir}/test",
614
+ log_rotate_age: rotate_age,
615
+ log_rotate_size: 10,
616
+ )
617
+ sv.__send__(:setup_global_logger)
618
+
619
+ assert_equal Fluent::LogDeviceIO, $log.out.class
620
+ assert_equal rotate_age, $log.out.instance_variable_get(:@shift_age)
621
+ assert_equal 10, $log.out.instance_variable_get(:@shift_size)
622
+ end
465
623
 
466
- # test that DamonLogger#level= overwrites Fluent.log#level
467
- logger.level = 'debug'
468
- assert_equal Fluent::Log::LEVEL_DEBUG, $log.level
624
+ def test_can_start_with_rotate_but_no_log_path
625
+ config_path = "#{@tmp_dir}/empty.conf"
626
+ write_config config_path, ""
469
627
 
470
- assert_equal 5, logger.instance_variable_get(:@rotate_age)
471
- assert_equal 1048576, logger.instance_variable_get(:@rotate_size)
472
- end
628
+ sv = Fluent::Supervisor.new(
629
+ config_path: config_path,
630
+ log_rotate_age: 5,
631
+ )
632
+ sv.__send__(:setup_global_logger)
473
633
 
474
- data(
475
- daily_age: 'daily',
476
- weekly_age: 'weekly',
477
- monthly_age: 'monthly',
478
- integer_age: 2,
479
- )
480
- def test_logger_with_rotate_age_and_rotate_size(rotate_age)
481
- opts = Fluent::Supervisor.default_options.merge(
482
- log_path: "#{TMP_DIR}/test", log_rotate_age: rotate_age, log_rotate_size: 10
483
- )
484
- sv = Fluent::Supervisor.new(opts)
485
- log = sv.instance_variable_get(:@log)
486
- log.init(:standalone, 0)
634
+ assert_true $log.stdout?
635
+ end
487
636
 
488
- assert_equal Fluent::LogDeviceIO, $log.out.class
489
- assert_equal rotate_age, $log.out.instance_variable_get(:@shift_age)
490
- assert_equal 10, $log.out.instance_variable_get(:@shift_size)
491
- end
637
+ sub_test_case "system log rotation" do
638
+ def parse_text(text)
639
+ basepath = File.expand_path(File.dirname(__FILE__) + '/../../')
640
+ Fluent::Config.parse(text, '(test)', basepath, true).elements.find { |e| e.name == 'system' }
641
+ end
492
642
 
493
- sub_test_case "system log rotation" do
494
- def parse_text(text)
495
- basepath = File.expand_path(File.dirname(__FILE__) + '/../../')
496
- Fluent::Config.parse(text, '(test)', basepath, true).elements.find { |e| e.name == 'system' }
497
- end
643
+ def test_override_default_log_rotate
644
+ Tempfile.open do |file|
645
+ config = parse_text(<<-EOS)
646
+ <system>
647
+ <log>
648
+ rotate_age 3
649
+ rotate_size 300
650
+ </log>
651
+ </system>
652
+ EOS
653
+ file.puts(config)
654
+ file.flush
655
+ sv = Fluent::Supervisor.new({log_path: "#{@tmp_dir}/test.log", config_path: file.path})
656
+
657
+ sv.__send__(:setup_global_logger)
658
+ logger = $log.instance_variable_get(:@logger)
659
+
660
+ assert_equal Fluent::LogDeviceIO, $log.out.class
661
+ assert_equal 3, $log.out.instance_variable_get(:@shift_age)
662
+ assert_equal 300, $log.out.instance_variable_get(:@shift_size)
663
+ end
664
+ end
498
665
 
499
- def test_override_default_log_rotate
500
- Tempfile.open do |file|
501
- config = parse_text(<<-EOS)
502
- <system>
503
- <log>
504
- rotate_age 3
505
- rotate_size 300
506
- </log>
507
- </system>
508
- EOS
509
- file.puts(config)
510
- file.flush
511
- opts = Fluent::Supervisor.default_options.merge(
512
- log_path: "#{TMP_DIR}/test.log", config_path: file.path
513
- )
514
- sv = Fluent::Supervisor.new(opts)
515
-
516
- log = sv.instance_variable_get(:@log)
517
- log.init(:standalone, 0)
518
- logger = $log.instance_variable_get(:@logger)
519
-
520
- assert_equal([3, 300],
521
- [logger.instance_variable_get(:@rotate_age),
522
- logger.instance_variable_get(:@rotate_size)])
666
+ def test_override_default_log_rotate_with_yaml_config
667
+ Tempfile.open do |file|
668
+ config = <<-EOS
669
+ system:
670
+ log:
671
+ rotate_age: 3
672
+ rotate_size: 300
673
+ EOS
674
+ file.puts(config)
675
+ file.flush
676
+ sv = Fluent::Supervisor.new({log_path: "#{@tmp_dir}/test.log", config_path: file.path, config_file_type: :yaml})
677
+
678
+ sv.__send__(:setup_global_logger)
679
+ logger = $log.instance_variable_get(:@logger)
680
+
681
+ assert_equal Fluent::LogDeviceIO, $log.out.class
682
+ assert_equal 3, $log.out.instance_variable_get(:@shift_age)
683
+ assert_equal 300, $log.out.instance_variable_get(:@shift_size)
684
+ end
523
685
  end
524
686
  end
525
- end
526
687
 
527
- def test_inline_config
528
- omit 'this feature is deprecated. see https://github.com/fluent/fluentd/issues/2711'
688
+ def test_log_level_affects
689
+ sv = Fluent::Supervisor.new({})
529
690
 
530
- opts = Fluent::Supervisor.default_options
531
- opts[:inline_config] = '-'
532
- sv = Fluent::Supervisor.new(opts)
533
- assert_equal '-', sv.instance_variable_get(:@inline_config)
691
+ c = Fluent::Config::Element.new('system', '', { 'log_level' => 'error' }, [])
692
+ stub(Fluent::Config).build { config_element('ROOT', '', {}, [c]) }
534
693
 
535
- inline_config = '<match *>\n@type stdout\n</match>'
536
- stub(STDIN).read { inline_config }
537
- stub(Fluent::Config).build # to skip
538
- stub(sv).build_system_config { Fluent::SystemConfig.new } # to skip
694
+ sv.configure
695
+ assert_equal Fluent::Log::LEVEL_ERROR, $log.level
696
+ end
539
697
 
540
- sv.configure
541
- assert_equal inline_config, sv.instance_variable_get(:@inline_config)
542
- end
698
+ data(supervisor: true)
699
+ data(worker: false)
700
+ def test_log_path(supervisor)
701
+ log_path = Pathname(@tmp_dir) + "fluentd.log"
702
+ config_path = Pathname(@tmp_dir) + "fluentd.conf"
703
+ write_config config_path.to_s, ""
704
+
705
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
706
+ assert_rr do
707
+ mock.proxy(File).chmod(0o777, log_path.parent.to_s).never
708
+ s.__send__(:setup_global_logger, supervisor: supervisor)
709
+ end
710
+
711
+ assert { log_path.parent.exist? }
712
+ ensure
713
+ $log.out.close
714
+ end
543
715
 
544
- def test_log_level_affects
545
- opts = Fluent::Supervisor.default_options
546
- sv = Fluent::Supervisor.new(opts)
716
+ data(supervisor: true)
717
+ data(worker: false)
718
+ def test_dir_permission(supervisor)
719
+ omit "NTFS doesn't support UNIX like permissions" if Fluent.windows?
720
+
721
+ log_path = Pathname(@tmp_dir) + "fluentd.log"
722
+ config_path = Pathname(@tmp_dir) + "fluentd.conf"
723
+ conf = <<~EOC
724
+ <system>
725
+ dir_permission 0o777
726
+ </system>
727
+ EOC
728
+ write_config config_path.to_s, conf
729
+
730
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
731
+ assert_rr do
732
+ mock.proxy(File).chmod(0o777, log_path.parent.to_s).once
733
+ s.__send__(:setup_global_logger, supervisor: supervisor)
734
+ end
547
735
 
548
- c = Fluent::Config::Element.new('system', '', { 'log_level' => 'error' }, [])
549
- stub(Fluent::Config).build { config_element('ROOT', '', {}, [c]) }
736
+ assert { log_path.parent.exist? }
737
+ assert { (File.stat(log_path.parent).mode & 0xFFF) == 0o777 }
738
+ ensure
739
+ $log.out.close
740
+ end
550
741
 
551
- sv.configure
552
- assert_equal Fluent::Log::LEVEL_ERROR, $log.level
742
+ def test_files_for_each_process_with_rotate_on_windows
743
+ omit "Only for Windows." unless Fluent.windows?
744
+
745
+ log_path = Pathname(@tmp_dir) + "log" + "fluentd.log"
746
+ config_path = Pathname(@tmp_dir) + "fluentd.conf"
747
+ conf = <<~EOC
748
+ <system>
749
+ <log>
750
+ rotate_age 5
751
+ </log>
752
+ </system>
753
+ EOC
754
+ write_config config_path.to_s, conf
755
+
756
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
757
+ s.__send__(:setup_global_logger, supervisor: true)
758
+ $log.out.close
759
+
760
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
761
+ s.__send__(:setup_global_logger, supervisor: false)
762
+ $log.out.close
763
+
764
+ ENV["SERVERENGINE_WORKER_ID"] = "1"
765
+ s = Fluent::Supervisor.new(config_path: config_path.to_s, log_path: log_path.to_s)
766
+ s.__send__(:setup_global_logger, supervisor: false)
767
+ $log.out.close
768
+
769
+ assert { log_path.parent.entries.size == 5 } # [".", "..", "logfile.log", ...]
770
+ ensure
771
+ ENV.delete("SERVERENGINE_WORKER_ID")
772
+ end
553
773
  end
554
774
 
555
775
  def test_enable_shared_socket