fluentd 1.12.4-x86-mingw32 → 1.13.3-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fluentd might be problematic. Click here for more details.

Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.yaml +69 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.yaml +38 -0
  4. data/.github/workflows/linux-test.yaml +1 -1
  5. data/.github/workflows/windows-test.yaml +14 -3
  6. data/.gitlab-ci.yml +0 -22
  7. data/CHANGELOG.md +129 -0
  8. data/CONTRIBUTING.md +2 -2
  9. data/MAINTAINERS.md +1 -1
  10. data/README.md +3 -3
  11. data/bin/fluentd +8 -1
  12. data/example/counter.conf +1 -1
  13. data/example/v0_12_filter.conf +2 -2
  14. data/fluentd.gemspec +1 -1
  15. data/lib/fluent/command/cat.rb +19 -3
  16. data/lib/fluent/command/fluentd.rb +1 -2
  17. data/lib/fluent/command/plugin_generator.rb +15 -5
  18. data/lib/fluent/config.rb +1 -1
  19. data/lib/fluent/config/section.rb +5 -0
  20. data/lib/fluent/config/types.rb +15 -0
  21. data/lib/fluent/config/v1_parser.rb +3 -2
  22. data/lib/fluent/env.rb +2 -1
  23. data/lib/fluent/log.rb +1 -0
  24. data/lib/fluent/oj_options.rb +62 -0
  25. data/lib/fluent/plugin/file_wrapper.rb +35 -4
  26. data/lib/fluent/plugin/formatter.rb +1 -0
  27. data/lib/fluent/plugin/formatter_json.rb +9 -7
  28. data/lib/fluent/plugin/in_http.rb +10 -0
  29. data/lib/fluent/plugin/in_tail.rb +159 -41
  30. data/lib/fluent/plugin/in_tail/position_file.rb +20 -18
  31. data/lib/fluent/plugin/out_forward.rb +14 -33
  32. data/lib/fluent/plugin/parser_json.rb +2 -3
  33. data/lib/fluent/plugin/service_discovery.rb +0 -15
  34. data/lib/fluent/plugin_helper/http_server/router.rb +1 -1
  35. data/lib/fluent/plugin_helper/service_discovery.rb +39 -1
  36. data/lib/fluent/plugin_helper/service_discovery/manager.rb +11 -5
  37. data/lib/fluent/supervisor.rb +15 -0
  38. data/lib/fluent/system_config.rb +14 -0
  39. data/lib/fluent/test/driver/storage.rb +30 -0
  40. data/lib/fluent/version.rb +1 -1
  41. data/templates/new_gem/lib/fluent/plugin/storage.rb.erb +40 -0
  42. data/templates/new_gem/test/plugin/test_storage.rb.erb +18 -0
  43. data/test/command/test_cat.rb +99 -0
  44. data/test/command/test_plugin_generator.rb +2 -1
  45. data/test/config/test_section.rb +9 -0
  46. data/test/config/test_system_config.rb +46 -0
  47. data/test/config/test_types.rb +7 -0
  48. data/test/plugin/in_tail/test_io_handler.rb +4 -4
  49. data/test/plugin/in_tail/test_position_file.rb +23 -5
  50. data/test/plugin/test_file_wrapper.rb +22 -1
  51. data/test/plugin/test_in_forward.rb +59 -83
  52. data/test/plugin/test_in_http.rb +58 -40
  53. data/test/plugin/test_in_syslog.rb +66 -56
  54. data/test/plugin/test_in_tail.rb +341 -1
  55. data/test/plugin/test_in_tcp.rb +45 -32
  56. data/test/plugin/test_in_udp.rb +47 -33
  57. data/test/plugin/test_out_forward.rb +114 -95
  58. data/test/plugin/test_out_stream.rb +18 -8
  59. data/test/plugin_helper/http_server/test_route.rb +1 -1
  60. data/test/plugin_helper/test_child_process.rb +1 -1
  61. data/test/plugin_helper/test_http_server_helper.rb +33 -26
  62. data/test/plugin_helper/test_server.rb +137 -138
  63. data/test/plugin_helper/test_service_discovery.rb +74 -14
  64. data/test/plugin_helper/test_socket.rb +16 -9
  65. data/test/test_config.rb +2 -1
  66. data/test/test_event_time.rb +2 -2
  67. data/test/test_oj_options.rb +55 -0
  68. data/test/test_supervisor.rb +35 -0
  69. metadata +15 -7
  70. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -40
  71. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -23
@@ -22,19 +22,18 @@ module Fluent::Plugin
22
22
  UNWATCHED_POSITION = 0xffffffffffffffff
23
23
  POSITION_FILE_ENTRY_REGEX = /^([^\t]+)\t([0-9a-fA-F]+)\t([0-9a-fA-F]+)/.freeze
24
24
 
25
- def self.load(file, follow_inodes, existing_paths, logger:)
26
- pf = new(file, follow_inodes, existing_paths, logger: logger)
27
- pf.load
25
+ def self.load(file, follow_inodes, existing_targets, logger:)
26
+ pf = new(file, follow_inodes, logger: logger)
27
+ pf.load(existing_targets)
28
28
  pf
29
29
  end
30
30
 
31
- def initialize(file, follow_inodes, existing_paths, logger: nil)
31
+ def initialize(file, follow_inodes, logger: nil)
32
32
  @file = file
33
33
  @logger = logger
34
34
  @file_mutex = Mutex.new
35
35
  @map = {}
36
36
  @follow_inodes = follow_inodes
37
- @existing_paths = existing_paths
38
37
  end
39
38
 
40
39
  def [](target_info)
@@ -60,8 +59,8 @@ module Fluent::Plugin
60
59
  end
61
60
  end
62
61
 
63
- def load
64
- compact
62
+ def load(existing_targets = nil)
63
+ compact(existing_targets)
65
64
 
66
65
  map = {}
67
66
  @file_mutex.synchronize do
@@ -118,9 +117,9 @@ module Fluent::Plugin
118
117
 
119
118
  private
120
119
 
121
- def compact
120
+ def compact(existing_targets = nil)
122
121
  @file_mutex.synchronize do
123
- entries = fetch_compacted_entries.values.map(&:to_entry_fmt)
122
+ entries = fetch_compacted_entries(existing_targets).values.map(&:to_entry_fmt)
124
123
 
125
124
  @file.pos = 0
126
125
  @file.truncate(0)
@@ -128,7 +127,7 @@ module Fluent::Plugin
128
127
  end
129
128
  end
130
129
 
131
- def fetch_compacted_entries
130
+ def fetch_compacted_entries(existing_targets = nil)
132
131
  entries = {}
133
132
 
134
133
  @file.pos = 0
@@ -151,23 +150,26 @@ module Fluent::Plugin
151
150
  end
152
151
 
153
152
  if @follow_inodes
154
- entries[ino] = Entry.new(path, pos, ino, file_pos + path.size + 1)
153
+ entries[ino] = Entry.new(path, pos, ino, file_pos + path.bytesize + 1)
155
154
  else
156
- entries[path] = Entry.new(path, pos, ino, file_pos + path.size + 1)
155
+ entries[path] = Entry.new(path, pos, ino, file_pos + path.bytesize + 1)
157
156
  end
158
157
  file_pos += line.size
159
158
  end
160
159
  end
161
160
 
162
- entries = remove_deleted_files_entries(entries, @existing_paths) if @follow_inodes
161
+ entries = remove_deleted_files_entries(entries, existing_targets) if @follow_inodes
163
162
  entries
164
163
  end
165
164
 
166
- def remove_deleted_files_entries(existent_entries, existing_paths)
167
- filtered_entries = existent_entries.select {|file_entry|
168
- existing_paths.key?(file_entry)
169
- }
170
- filtered_entries
165
+ def remove_deleted_files_entries(existent_entries, existing_targets)
166
+ if existing_targets
167
+ existent_entries.select { |path_or_ino|
168
+ existing_targets.key?(path_or_ino)
169
+ }
170
+ else
171
+ existent_entries
172
+ end
171
173
  end
172
174
  end
173
175
 
@@ -227,31 +227,14 @@ module Fluent::Plugin
227
227
  socket_cache: socket_cache,
228
228
  )
229
229
 
230
- configs = []
231
-
232
- # rewrite for using server as sd_static
233
- conf.elements(name: 'server').each do |s|
234
- s.name = 'service'
235
- end
236
-
237
- unless conf.elements(name: 'service').empty?
238
- # To copy `services` element only
239
- new_elem = Fluent::Config::Element.new('static_service_discovery', {}, {}, conf.elements(name: 'service'))
240
- configs << { type: :static, conf: new_elem }
241
- end
242
-
243
- conf.elements(name: 'service_discovery').each_with_index do |c, i|
244
- configs << { type: @service_discovery[i][:@type], conf: c }
245
- end
246
-
247
- service_discovery_create_manager(
230
+ service_discovery_configure(
248
231
  :out_forward_service_discovery_watcher,
249
- configurations: configs,
232
+ static_default_service_directive: 'server',
250
233
  load_balancer: LoadBalancer.new(log),
251
234
  custom_build_method: method(:build_node),
252
235
  )
253
236
 
254
- discovery_manager.services.each do |server|
237
+ service_discovery_services.each do |server|
255
238
  # it's only for test
256
239
  @nodes << server
257
240
  unless @heartbeat_type == :none
@@ -273,7 +256,7 @@ module Fluent::Plugin
273
256
  end
274
257
  end
275
258
 
276
- if discovery_manager.services.empty?
259
+ if service_discovery_services.empty?
277
260
  raise Fluent::ConfigError, "forward output plugin requires at least one node is required. Add <server> or <service_discovery>"
278
261
  end
279
262
 
@@ -306,7 +289,7 @@ module Fluent::Plugin
306
289
 
307
290
  unless @heartbeat_type == :none
308
291
  if @heartbeat_type == :udp
309
- @usock = socket_create_udp(discovery_manager.services.first.host, discovery_manager.services.first.port, nonblock: true)
292
+ @usock = socket_create_udp(service_discovery_services.first.host, service_discovery_services.first.port, nonblock: true)
310
293
  server_create_udp(:out_forward_heartbeat_receiver, 0, socket: @usock, max_bytes: @read_length, &method(:on_udp_heatbeat_response_recv))
311
294
  end
312
295
  timer_execute(:out_forward_heartbeat_request, @heartbeat_interval, &method(:on_heartbeat_timer))
@@ -318,7 +301,7 @@ module Fluent::Plugin
318
301
  end
319
302
 
320
303
  if @verify_connection_at_startup
321
- discovery_manager.services.each do |node|
304
+ service_discovery_services.each do |node|
322
305
  begin
323
306
  node.verify_connection
324
307
  rescue StandardError => e
@@ -374,7 +357,7 @@ module Fluent::Plugin
374
357
  return if chunk.empty?
375
358
  tag = chunk.metadata.tag
376
359
 
377
- discovery_manager.select_service { |node| node.send_data(tag, chunk) }
360
+ service_discovery_select_service { |node| node.send_data(tag, chunk) }
378
361
  end
379
362
 
380
363
  def try_write(chunk)
@@ -384,7 +367,7 @@ module Fluent::Plugin
384
367
  return
385
368
  end
386
369
  tag = chunk.metadata.tag
387
- discovery_manager.select_service { |node| node.send_data(tag, chunk) }
370
+ service_discovery_select_service { |node| node.send_data(tag, chunk) }
388
371
  last_ack if @require_ack_response && @suspend_flush
389
372
  end
390
373
 
@@ -434,7 +417,7 @@ module Fluent::Plugin
434
417
 
435
418
  def statistics
436
419
  stats = super
437
- services = discovery_manager.services
420
+ services = service_discovery_services
438
421
  healthy_nodes_count = 0
439
422
  registed_nodes_count = services.size
440
423
  services.each do |s|
@@ -471,7 +454,7 @@ module Fluent::Plugin
471
454
 
472
455
  def on_heartbeat_timer
473
456
  need_rebuild = false
474
- discovery_manager.services.each do |n|
457
+ service_discovery_services.each do |n|
475
458
  begin
476
459
  log.trace "sending heartbeat", host: n.host, port: n.port, heartbeat_type: @heartbeat_type
477
460
  n.usock = @usock if @usock
@@ -486,16 +469,16 @@ module Fluent::Plugin
486
469
  end
487
470
 
488
471
  if need_rebuild
489
- discovery_manager.rebalance
472
+ service_discovery_rebalance
490
473
  end
491
474
  end
492
475
 
493
476
  def on_udp_heatbeat_response_recv(data, sock)
494
477
  sockaddr = Socket.pack_sockaddr_in(sock.remote_port, sock.remote_host)
495
- if node = discovery_manager.services.find { |n| n.sockaddr == sockaddr }
478
+ if node = service_discovery_services.find { |n| n.sockaddr == sockaddr }
496
479
  # log.trace "heartbeat arrived", name: node.name, host: node.host, port: node.port
497
480
  if node.heartbeat
498
- discovery_manager.rebalance
481
+ service_discovery_rebalance
499
482
  end
500
483
  else
501
484
  log.warn("Unknown heartbeat response received from #{sock.remote_host}:#{sock.remote_port}. It may service out")
@@ -582,8 +565,6 @@ module Fluent::Plugin
582
565
  username: server.username || '',
583
566
  )
584
567
 
585
- @unpacker = Fluent::MessagePackFactory.msgpack_unpacker
586
-
587
568
  @resolved_host = nil
588
569
  @resolved_time = 0
589
570
  @resolved_once = false
@@ -630,7 +611,7 @@ module Fluent::Plugin
630
611
  sleep @sender.read_interval
631
612
  next
632
613
  end
633
- @unpacker.feed_each(buf) do |data|
614
+ Fluent::MessagePackFactory.msgpack_unpacker.feed_each(buf) do |data|
634
615
  if @handshake.invoke(sock, ri, data) == :established
635
616
  @log.debug "connection established", host: @host, port: @port
636
617
  end
@@ -15,8 +15,8 @@
15
15
  #
16
16
 
17
17
  require 'fluent/plugin/parser'
18
- require 'fluent/env'
19
18
  require 'fluent/time'
19
+ require 'fluent/oj_options'
20
20
 
21
21
  require 'yajl'
22
22
  require 'json'
@@ -50,8 +50,7 @@ module Fluent
50
50
  def configure_json_parser(name)
51
51
  case name
52
52
  when :oj
53
- require 'oj'
54
- Oj.default_options = Fluent::DEFAULT_OJ_OPTIONS
53
+ raise LoadError unless Fluent::OjOptions.available?
55
54
  [Oj.method(:load), Oj::ParseError]
56
55
  when :json then [JSON.method(:load), JSON::ParserError]
57
56
  when :yajl then [Yajl.method(:load), Yajl::ParseError]
@@ -13,21 +13,6 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
  #
16
- #
17
- # Fluentd
18
- #
19
- # Licensed under the Apache License, Version 2.0 (the "License");
20
- # you may not use this file except in compliance with the License.
21
- # You may obtain a copy of the License at
22
- #
23
- # http://www.apache.org/licenses/LICENSE-2.0
24
- #
25
- # Unless required by applicable law or agreed to in writing, software
26
- # distributed under the License is distributed on an "AS IS" BASIS,
27
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
28
- # See the License for the specific language governing permissions and
29
- # limitations under the License.
30
- #
31
16
 
32
17
  require 'fluent/plugin/base'
33
18
 
@@ -22,7 +22,7 @@ module Fluent
22
22
  class Router
23
23
  class NotFoundApp
24
24
  def self.call(req)
25
- [404, { 'Content-Type' => 'text/plain' }, "404 Not Found: #{req.path}\n"]
25
+ [404, { 'Content-Type' => 'text/plain' }, "404 Not Found\n"]
26
26
  end
27
27
  end
28
28
 
@@ -22,10 +22,19 @@ module Fluent
22
22
  module ServiceDiscovery
23
23
  include Fluent::PluginHelper::Timer
24
24
 
25
+ # For the compatibility with older versions without `param_name: :service_discovery_configs`
26
+ attr_reader :service_discovery
27
+
25
28
  def self.included(mod)
26
29
  mod.include ServiceDiscoveryParams
27
30
  end
28
31
 
32
+ def configure(conf)
33
+ super
34
+ # For the compatibility with older versions without `param_name: :service_discovery_configs`
35
+ @service_discovery = @service_discovery_configs
36
+ end
37
+
29
38
  def start
30
39
  unless @discovery_manager
31
40
  log.warn('There is no discovery_manager. skip start them')
@@ -52,6 +61,35 @@ module Fluent
52
61
 
53
62
  private
54
63
 
64
+ # @param title [Symbol] the thread name. this value should be unique.
65
+ # @param static_default_service_directive [String] the directive name of each service when "static" service discovery is enabled in default
66
+ # @param load_balancer [Object] object which has two methods #rebalance and #select_service
67
+ # @param custom_build_method [Proc]
68
+ def service_discovery_configure(title, static_default_service_directive: nil, load_balancer: nil, custom_build_method: nil, interval: 3)
69
+ configs = @service_discovery_configs.map(&:corresponding_config_element)
70
+ if static_default_service_directive
71
+ configs.prepend Fluent::Config::Element.new(
72
+ 'service_discovery',
73
+ '',
74
+ {'@type' => 'static'},
75
+ @config.elements(name: static_default_service_directive.to_s).map{|e| Fluent::Config::Element.new('service', e.arg, e.dup, e.elements, e.unused) }
76
+ )
77
+ end
78
+ service_discovery_create_manager(title, configurations: configs, load_balancer: load_balancer, custom_build_method: custom_build_method, interval: interval)
79
+ end
80
+
81
+ def service_discovery_select_service(&block)
82
+ @discovery_manager.select_service(&block)
83
+ end
84
+
85
+ def service_discovery_services
86
+ @discovery_manager.services
87
+ end
88
+
89
+ def service_discovery_rebalance
90
+ @discovery_manager.rebalance
91
+ end
92
+
55
93
  # @param title [Symbol] the thread name. this value should be unique.
56
94
  # @param configurations [Hash] hash which must has discivery_service type and its configuration like `{ type: :static, conf: <Fluent::Config::Element> }`
57
95
  # @param load_balancer [Object] object which has two methods #rebalance and #select_service
@@ -78,7 +116,7 @@ module Fluent
78
116
  module ServiceDiscoveryParams
79
117
  include Fluent::Configurable
80
118
 
81
- config_section :service_discovery do
119
+ config_section :service_discovery, multi: true, param_name: :service_discovery_configs do
82
120
  config_param :@type, :string
83
121
  end
84
122
  end
@@ -32,17 +32,23 @@ module Fluent
32
32
  @static_config = true
33
33
  end
34
34
 
35
- def configure(opts, parent: nil)
36
- opts.each do |opt|
37
- sd = Fluent::Plugin.new_sd(opt[:type], parent: parent)
38
- sd.configure(opt[:conf])
35
+ def configure(configs, parent: nil)
36
+ configs.each do |config|
37
+ type, conf = if config.has_key?(:conf) # for compatibility with initial API
38
+ [config[:type], config[:conf]]
39
+ else
40
+ [config['@type'], config]
41
+ end
42
+
43
+ sd = Fluent::Plugin.new_sd(type, parent: parent)
44
+ sd.configure(conf)
39
45
 
40
46
  sd.services.each do |s|
41
47
  @services[s.discovery_id] = build_service(s)
42
48
  end
43
49
  @discoveries << sd
44
50
 
45
- if @static_config && opt[:type] != :static
51
+ if @static_config && type.to_sym != :static
46
52
  @static_config = false
47
53
  end
48
54
  end
@@ -518,6 +518,8 @@ module Fluent
518
518
  dl_opts = {}
519
519
  # subtract 1 to match serverengine daemon logger side logging severity.
520
520
  dl_opts[:log_level] = @level - 1
521
+ dl_opts[:log_rotate_age] = @log_rotate_age if @log_rotate_age
522
+ dl_opts[:log_rotate_size] = @log_rotate_size if @log_rotate_size
521
523
  logger = ServerEngine::DaemonLogger.new(@logdev, dl_opts)
522
524
  $log = Fluent::Log.new(logger, @opts)
523
525
  $log.enable_color(false) if @path
@@ -606,6 +608,19 @@ module Fluent
606
608
 
607
609
  @cl_opt = opt
608
610
  @conf = nil
611
+ # parse configuration immediately to initialize logger in early stage
612
+ if @config_path and File.exist?(@config_path)
613
+ @conf = Fluent::Config.build(config_path: @config_path,
614
+ encoding: @conf_encoding ? @conf_encoding : 'utf-8',
615
+ additional_config: @inline_config ? @inline_config : nil,
616
+ use_v1_config: !!@use_v1_config)
617
+ @system_config = build_system_config(@conf)
618
+ if @system_config.log
619
+ @log_rotate_age ||= @system_config.log.rotate_age
620
+ @log_rotate_size ||= @system_config.log.rotate_size
621
+ end
622
+ @conf = nil
623
+ end
609
624
 
610
625
  log_opts = {suppress_repeated_stacktrace: opt[:suppress_repeated_stacktrace], ignore_repeated_log_interval: opt[:ignore_repeated_log_interval],
611
626
  ignore_same_log_interval: opt[:ignore_same_log_interval]}
@@ -55,6 +55,20 @@ module Fluent
55
55
  config_section :log, required: false, init: true, multi: false do
56
56
  config_param :format, :enum, list: [:text, :json], default: :text
57
57
  config_param :time_format, :string, default: '%Y-%m-%d %H:%M:%S %z'
58
+ config_param :rotate_age, default: nil do |v|
59
+ if Fluent::Log::LOG_ROTATE_AGE.include?(v)
60
+ v.to_sym
61
+ else
62
+ begin
63
+ Integer(v)
64
+ rescue ArgumentError => e
65
+ raise Fluent::ConfigError, e.message
66
+ else
67
+ v.to_i
68
+ end
69
+ end
70
+ end
71
+ config_param :rotate_size, :size, default: nil
58
72
  end
59
73
 
60
74
  config_section :counter_server, multi: false do
@@ -0,0 +1,30 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'fluent/test/driver/base_owned'
18
+
19
+ module Fluent
20
+ module Test
21
+ module Driver
22
+ class Storage < BaseOwned
23
+ def initialize(klass, **kwargs, &block)
24
+ super
25
+ @section_name = "storage"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end