fluentd 1.19.1 → 1.19.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f7d0597141166c9db2f30b7ea1761610ec6dc2e3c5b8443f3ff980530c4afd33
4
- data.tar.gz: eb02d36ab94976985da49b0abe845dfe17056806f02e99cb8fa38a88addb79be
3
+ metadata.gz: 4873da89c533afd45a6f02a86aa8f92f7502bd08204724290dd34187c7183cd5
4
+ data.tar.gz: 1f092049f456daae36077e374670a7a32d044da48b01ecea5410bc116f76c61b
5
5
  SHA512:
6
- metadata.gz: cd04fb1ed5a9407cae8d150fdb5875cac15d5e906356ba76232e82cb4c28053199f9b09fa403fad5733623b758ec713defb205d8bcc6058e067a71f01c0ec30c
7
- data.tar.gz: eba375ae694bf113a9a70bce6c77575ed42e6d8f14d5c463890ae570c14dfe48576eb7eecd90fb401480ebfd910ecd45fdfed1130f909b8c541440bdf7a3c407
6
+ metadata.gz: 820db817466aaade115300f5839e62d278a7fbbd19479b939206f4a0b212905046c1717c37cf2e19d90640dc07b570455e9b6f10fa5d21b04b96da4ec04f15b2
7
+ data.tar.gz: 581e8ac6c84ae65e8b33758de56a65ca684547f64c2864fcdb630c68e2b58bda6232e98c60dc48b99efe8c2cf584f31aef62a14fd1a72785d1b6d88f41635fea
data/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # v1.19
2
2
 
3
+ ## Release v1.19.2 - 2026/02/13
4
+
5
+ ### Bug Fix
6
+
7
+ * out_forward: add timeout to establish_connection to prevent infinite loop https://github.com/fluent/fluentd/pull/5138
8
+ * gem: use latest net-http to solve IPv6 addr error https://github.com/fluent/fluentd/pull/5192
9
+ * in_tail: fix error when files without read permission are included in glob patterns https://github.com/fluent/fluentd/pull/5222
10
+ * command/fluentd: load win32/registry when edit registry for Ruby 4.0 https://github.com/fluent/fluentd/pull/5221
11
+ * plugin_helper/http_server: Ensure request body is closed to prevent socket leaks in POST requests https://github.com/fluent/fluentd/pull/5234
12
+ * config: fix duplicate config file loading in config_include_dir https://github.com/fluent/fluentd/pull/5235
13
+ * gem: add ostruct gem as dependency for Ruby 4.0 https://github.com/fluent/fluentd/pull/5251
14
+
15
+ ### Misc
16
+
17
+ * config: warn when backed-up config file will be included https://github.com/fluent/fluentd/pull/5252
18
+ * filter_record_transformer: use cgi/escape to avoid Ruby 4.0 deprecation https://github.com/fluent/fluentd/pull/5256
19
+ * CI fixes
20
+ * https://github.com/fluent/fluentd/pull/5257
21
+ * https://github.com/fluent/fluentd/pull/5229
22
+ * https://github.com/fluent/fluentd/pull/5225
23
+ * https://github.com/fluent/fluentd/pull/5186
24
+ * https://github.com/fluent/fluentd/pull/5184
25
+ * https://github.com/fluent/fluentd/pull/5176
26
+
3
27
  ## Release v1.19.1 - 2025/11/06
4
28
 
5
29
  ### Bug Fix
@@ -344,6 +344,7 @@ if winsvcinstmode = opts[:regwinsvc]
344
344
  end
345
345
 
346
346
  if fluentdopt = opts[:fluentdopt]
347
+ require "win32/registry"
347
348
  Win32::Registry::HKEY_LOCAL_MACHINE.open("SYSTEM\\CurrentControlSet\\Services\\#{opts[:winsvc_name]}", Win32::Registry::KEY_ALL_ACCESS) do |reg|
348
349
  reg['fluentdopt', Win32::Registry::REG_SZ] = fluentdopt
349
350
  end
@@ -27,17 +27,18 @@ module Fluent
27
27
  class V1Parser < LiteralParser
28
28
  ELEMENT_NAME = /[a-zA-Z0-9_]+/
29
29
 
30
- def self.parse(data, fname, basepath = Dir.pwd, eval_context = nil)
30
+ def self.parse(data, fname, basepath = Dir.pwd, eval_context = nil, on_file_parsed: nil)
31
31
  ss = StringScanner.new(data)
32
- ps = V1Parser.new(ss, basepath, fname, eval_context)
32
+ ps = V1Parser.new(ss, basepath, fname, eval_context, on_file_parsed: on_file_parsed)
33
33
  ps.parse!
34
34
  end
35
35
 
36
- def initialize(strscan, include_basepath, fname, eval_context)
36
+ def initialize(strscan, include_basepath, fname, eval_context, on_file_parsed: nil)
37
37
  super(strscan, eval_context)
38
38
  @include_basepath = include_basepath
39
39
  @fname = fname
40
40
  @logger = defined?($log) ? $log : nil
41
+ @on_file_parsed = on_file_parsed
41
42
  end
42
43
 
43
44
  def parse!
@@ -138,6 +139,8 @@ module Fluent
138
139
  end
139
140
  end
140
141
 
142
+ @on_file_parsed&.call(File.expand_path(File.join(@include_basepath, @fname))) if root_element
143
+
141
144
  return attrs, elems
142
145
  end
143
146
 
@@ -163,10 +166,15 @@ module Fluent
163
166
  Dir.glob(pattern).sort.each { |entry|
164
167
  basepath = File.dirname(entry)
165
168
  fname = File.basename(entry)
169
+ suspicious_backup_extensions = %w(bak old backup orig prev conf tmp temp debug wip)
170
+ if path.end_with?('*.conf') and
171
+ suspicious_backup_extensions.any? { |ext| fname.end_with?(".#{ext}.conf", "_#{ext}.conf") }
172
+ @logger.warn "There is a possibility that '@include #{uri}' includes duplicated backed-up config file such as <#{fname}>" if @logger
173
+ end
166
174
  data = File.read(entry)
167
175
  data.force_encoding('UTF-8')
168
176
  ss = StringScanner.new(data)
169
- V1Parser.new(ss, basepath, fname, @eval_context).parse_element(true, nil, attrs, elems)
177
+ V1Parser.new(ss, basepath, fname, @eval_context, on_file_parsed: @on_file_parsed).parse_element(true, nil, attrs, elems)
170
178
  }
171
179
  else
172
180
  require 'open-uri'
@@ -175,7 +183,7 @@ module Fluent
175
183
  data = u.open { |f| f.read }
176
184
  data.force_encoding('UTF-8')
177
185
  ss = StringScanner.new(data)
178
- V1Parser.new(ss, basepath, fname, @eval_context).parse_element(true, nil, attrs, elems)
186
+ V1Parser.new(ss, basepath, fname, @eval_context, on_file_parsed: @on_file_parsed).parse_element(true, nil, attrs, elems)
179
187
  end
180
188
  rescue SystemCallError => e
181
189
  cpe = ConfigParseError.new("include error #{uri} - #{e}")
@@ -30,9 +30,10 @@ module Fluent
30
30
  FLUENT_STR_TAG = 'tag:fluent/s'.freeze
31
31
  SHOVEL = '<<'.freeze
32
32
 
33
- def initialize(context = Kernel.binding)
33
+ def initialize(context = Kernel.binding, on_file_parsed: nil)
34
34
  @context = context
35
35
  @current_path = nil
36
+ @on_file_parsed = on_file_parsed
36
37
  end
37
38
 
38
39
  # @param [String] path
@@ -55,9 +56,13 @@ module Fluent
55
56
  Fluent::Config::YamlParser::FluentValue::StringValue.new(val, @context)
56
57
  end
57
58
 
58
- path.open do |f|
59
+ config = path.open do |f|
59
60
  visitor.accept(Psych.parse(f))
60
61
  end
62
+
63
+ @on_file_parsed&.call(File.expand_path(path.to_s))
64
+
65
+ config
61
66
  end
62
67
 
63
68
  def eval_include(path, parent)
@@ -21,7 +21,7 @@ require 'pathname'
21
21
  module Fluent
22
22
  module Config
23
23
  module YamlParser
24
- def self.parse(path)
24
+ def self.parse(path, on_file_parsed: nil)
25
25
  context = Kernel.binding
26
26
 
27
27
  unless context.respond_to?(:use_nil)
@@ -48,7 +48,7 @@ module Fluent
48
48
  end
49
49
  end
50
50
 
51
- s = Fluent::Config::YamlParser::Loader.new(context).load(Pathname.new(path))
51
+ s = Fluent::Config::YamlParser::Loader.new(context, on_file_parsed: on_file_parsed).load(Pathname.new(path))
52
52
  Fluent::Config::YamlParser::Parser.new(s).build.to_element
53
53
  end
54
54
  end
data/lib/fluent/config.rb CHANGED
@@ -26,7 +26,7 @@ module Fluent
26
26
  # @param additional_config [String] config which is added to last of config body
27
27
  # @param use_v1_config [Bool] config is formatted with v1 or not
28
28
  # @return [Fluent::Config]
29
- def self.build(config_path:, encoding: 'utf-8', additional_config: nil, use_v1_config: true, type: nil)
29
+ def self.build(config_path:, encoding: 'utf-8', additional_config: nil, use_v1_config: true, type: nil, on_file_parsed: nil)
30
30
  if type == :guess
31
31
  config_file_ext = File.extname(config_path)
32
32
  if config_file_ext == '.yaml' || config_file_ext == '.yml'
@@ -35,7 +35,7 @@ module Fluent
35
35
  end
36
36
 
37
37
  if type == :yaml || type == :yml
38
- return Fluent::Config::YamlParser.parse(config_path)
38
+ return Fluent::Config::YamlParser.parse(config_path, on_file_parsed: on_file_parsed)
39
39
  end
40
40
 
41
41
  config_fname = File.basename(config_path)
@@ -49,10 +49,10 @@ module Fluent
49
49
  s
50
50
  end
51
51
 
52
- Fluent::Config.parse(config_data, config_fname, config_basedir, use_v1_config)
52
+ Fluent::Config.parse(config_data, config_fname, config_basedir, use_v1_config, on_file_parsed: on_file_parsed)
53
53
  end
54
54
 
55
- def self.parse(str, fname, basepath = Dir.pwd, v1_config = nil, syntax: :v1)
55
+ def self.parse(str, fname, basepath = Dir.pwd, v1_config = nil, syntax: :v1, on_file_parsed: nil)
56
56
  parser = if fname =~ /\.rb$/ || syntax == :ruby
57
57
  :ruby
58
58
  elsif v1_config.nil?
@@ -68,7 +68,7 @@ module Fluent
68
68
  case parser
69
69
  when :v1
70
70
  require 'fluent/config/v1_parser'
71
- V1Parser.parse(str, fname, basepath, Kernel.binding)
71
+ V1Parser.parse(str, fname, basepath, Kernel.binding, on_file_parsed: on_file_parsed)
72
72
  when :v0
73
73
  # TODO: show deprecated message in v1
74
74
  require 'fluent/config/parser'
@@ -71,7 +71,7 @@ module Fluent::Plugin
71
71
  # require utilities which would be used in ruby placeholders
72
72
  require 'pathname'
73
73
  require 'uri'
74
- require 'cgi'
74
+ require 'cgi/escape'
75
75
  RubyPlaceholderExpander.new(placeholder_expander_params)
76
76
  else
77
77
  PlaceholderExpander.new(placeholder_expander_params)
@@ -59,6 +59,7 @@ module Fluent::Plugin
59
59
  @shutdown_start_time = nil
60
60
  @metrics = nil
61
61
  @startup = true
62
+ @capability = Fluent::Capability.new(:current_process)
62
63
  end
63
64
 
64
65
  desc 'The paths to read. Multiple paths can be specified, separated by comma.'
@@ -195,7 +196,6 @@ module Fluent::Plugin
195
196
  @dir_perm = system_config.dir_permission || Fluent::DEFAULT_DIR_PERMISSION
196
197
  # parser is already created by parser helper
197
198
  @parser = parser_create(usage: parser_config['usage'] || @parser_configs.first.usage)
198
- @capability = Fluent::Capability.new(:current_process)
199
199
  if @read_bytes_limit_per_second > 0
200
200
  if !@enable_watch_timer
201
201
  raise Fluent::ConfigError, "Need to enable watch timer when using log throttling feature"
@@ -620,7 +620,17 @@ module Fluent::Plugin
620
620
  end
621
621
 
622
622
  def establish_connection(sock, ri)
623
+ start_time = Fluent::Clock.now
624
+ timeout = @sender.hard_timeout
625
+
623
626
  while ri.state != :established
627
+ # Check for timeout to prevent infinite loop
628
+ if Fluent::Clock.now - start_time > timeout
629
+ @log.warn "handshake timeout after #{timeout}s", host: @host, port: @port
630
+ disable!
631
+ break
632
+ end
633
+
624
634
  begin
625
635
  # TODO: On Ruby 2.2 or earlier, read_nonblock doesn't work expectedly.
626
636
  # We need rewrite around here using new socket/server plugin helper.
@@ -71,6 +71,8 @@ module Fluent
71
71
  path
72
72
  end
73
73
  @router.route!(name, canonical_path, req)
74
+ ensure
75
+ request.body&.close
74
76
  end
75
77
  end
76
78
  end
@@ -18,6 +18,7 @@ require 'fileutils'
18
18
  require 'open3'
19
19
  require 'pathname'
20
20
  require 'find'
21
+ require 'set'
21
22
 
22
23
  require 'fluent/config'
23
24
  require 'fluent/counter'
@@ -796,18 +797,20 @@ module Fluent
796
797
  $log.warn('the value "-" for `inline_config` is deprecated. See https://github.com/fluent/fluentd/issues/2711')
797
798
  @inline_config = STDIN.read
798
799
  end
800
+ parsed_files = Set.new
799
801
  @conf = Fluent::Config.build(
800
802
  config_path: @config_path,
801
803
  encoding: @conf_encoding,
802
804
  additional_config: @inline_config,
803
805
  use_v1_config: @use_v1_config,
804
806
  type: @config_file_type,
807
+ on_file_parsed: ->(path) { parsed_files << path },
805
808
  )
806
809
  @system_config = build_system_config(@conf)
807
810
 
808
811
  $log.info :supervisor, 'parsing config file is succeeded', path: @config_path
809
812
 
810
- build_additional_configurations do |additional_conf|
813
+ build_additional_configurations(parsed_files) do |additional_conf|
811
814
  @conf += additional_conf
812
815
  end
813
816
 
@@ -854,6 +857,7 @@ module Fluent
854
857
  additional_config: @inline_config,
855
858
  use_v1_config: @use_v1_config,
856
859
  type: @config_file_type,
860
+ on_file_parsed: nil,
857
861
  )
858
862
  system_config = build_system_config(conf)
859
863
 
@@ -1088,15 +1092,17 @@ module Fluent
1088
1092
  $log.debug('worker got SIGUSR2')
1089
1093
 
1090
1094
  begin
1095
+ parsed_files = Set.new
1091
1096
  conf = Fluent::Config.build(
1092
1097
  config_path: @config_path,
1093
1098
  encoding: @conf_encoding,
1094
1099
  additional_config: @inline_config,
1095
1100
  use_v1_config: @use_v1_config,
1096
1101
  type: @config_file_type,
1102
+ on_file_parsed: ->(path) { parsed_files << path },
1097
1103
  )
1098
1104
 
1099
- build_additional_configurations do |additional_conf|
1105
+ build_additional_configurations(parsed_files) do |additional_conf|
1100
1106
  conf += additional_conf
1101
1107
  end
1102
1108
 
@@ -1206,7 +1212,7 @@ module Fluent
1206
1212
  system_config
1207
1213
  end
1208
1214
 
1209
- def build_additional_configurations
1215
+ def build_additional_configurations(parsed_files)
1210
1216
  if @system_config.config_include_dir&.empty?
1211
1217
  $log.info :supervisor, 'configuration include directory is disabled'
1212
1218
  return
@@ -1218,11 +1224,17 @@ module Fluent
1218
1224
  next unless supported_suffixes.include?(File.extname(path))
1219
1225
  # NOTE: both types of normal config (.conf) and YAML will be loaded.
1220
1226
  # Thus, it does not care whether @config_path is .conf or .yml.
1227
+ if parsed_files.include?(path)
1228
+ $log.info :supervisor, 'skip auto loading, it was already loaded', path: path
1229
+ next
1230
+ end
1231
+
1221
1232
  $log.info :supervisor, 'loading additional configuration file', path: path
1222
1233
  yield Fluent::Config.build(config_path: path,
1223
1234
  encoding: @conf_encoding,
1224
1235
  use_v1_config: @use_v1_config,
1225
- type: :guess)
1236
+ type: :guess,
1237
+ on_file_parsed: nil)
1226
1238
  end
1227
1239
  rescue Errno::ENOENT
1228
1240
  $log.info :supervisor, 'inaccessible include directory was specified', path: @system_config.config_include_dir
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '1.19.1'
19
+ VERSION = '1.19.2'
20
20
 
21
21
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluentd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.19.1
4
+ version: 1.19.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
@@ -220,9 +220,6 @@ dependencies:
220
220
  - - "~>"
221
221
  - !ruby/object:Gem::Version
222
222
  version: '1.0'
223
- - - "<"
224
- - !ruby/object:Gem::Version
225
- version: 1.1.0
226
223
  type: :runtime
227
224
  prerelease: false
228
225
  version_requirements: !ruby/object:Gem::Requirement
@@ -230,9 +227,20 @@ dependencies:
230
227
  - - "~>"
231
228
  - !ruby/object:Gem::Version
232
229
  version: '1.0'
233
- - - "<"
230
+ - !ruby/object:Gem::Dependency
231
+ name: net-http
232
+ requirement: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: '0.8'
237
+ type: :runtime
238
+ prerelease: false
239
+ version_requirements: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - "~>"
234
242
  - !ruby/object:Gem::Version
235
- version: 1.1.0
243
+ version: '0.8'
236
244
  - !ruby/object:Gem::Dependency
237
245
  name: async-http
238
246
  requirement: !ruby/object:Gem::Requirement
@@ -303,6 +311,20 @@ dependencies:
303
311
  - - "~>"
304
312
  - !ruby/object:Gem::Version
305
313
  version: '1.6'
314
+ - !ruby/object:Gem::Dependency
315
+ name: ostruct
316
+ requirement: !ruby/object:Gem::Requirement
317
+ requirements:
318
+ - - "~>"
319
+ - !ruby/object:Gem::Version
320
+ version: '0.6'
321
+ type: :runtime
322
+ prerelease: false
323
+ version_requirements: !ruby/object:Gem::Requirement
324
+ requirements:
325
+ - - "~>"
326
+ - !ruby/object:Gem::Version
327
+ version: '0.6'
306
328
  - !ruby/object:Gem::Dependency
307
329
  name: rake
308
330
  requirement: !ruby/object:Gem::Requirement
@@ -861,7 +883,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
861
883
  - !ruby/object:Gem::Version
862
884
  version: '0'
863
885
  requirements: []
864
- rubygems_version: 3.6.8
886
+ rubygems_version: 3.6.9
865
887
  specification_version: 4
866
888
  summary: Fluentd event collector
867
889
  test_files: []