fluentd 1.16.2-x64-mingw-ucrt → 1.16.3-x64-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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca3b6a3fb5bdaa795003d404012136767d6097fc3426ff08e3d90f582197ebbf
4
- data.tar.gz: af1d3135da23f2befd2da6e119474773e2bce8bc77bc7845509e4d29738f5db6
3
+ metadata.gz: 7cc0f02ec4452b5fdaf1ce0781c930e07f14c79148dbe0607ebb5da0722937e7
4
+ data.tar.gz: 0d627143a1062643391fde8fddd9c1b305e2d5af0b2a2d6c7134602faad6adc1
5
5
  SHA512:
6
- metadata.gz: '079ab55296623ac554b61ce9323fd546c7996c0845d51659d6a8694618e593b365bf6953317a19595bfae00929d1821fc811f502a2ec7224c47611f7ba5b261d'
7
- data.tar.gz: 225659babf6d4e8d9e3d0a6ff809a7d5cc34a5fc7c129be3d03321017bdb5bb55602bcad2bfe86fed67cd311cdb15669b85529acb2aeedd4b0590cb7352eb4ab
6
+ metadata.gz: 785c013daf2319ab94469cfc50be58ad23941180d5e1bc857fea4b1d2f72158af3e6895fedb4ffed5d84df70ad1a1e31d788c7bac9a2dca326e8f5e67e0287db
7
+ data.tar.gz: a10fb117af7414848a36a45c8af140d5539be7e02595afb56d0e55b03ab6f3a112f12ce4069683eb04412b507ae5055d8091f608b0e2acb4da6f00b866334ee3
@@ -2,9 +2,9 @@ name: Testing on Ubuntu
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [master]
5
+ branches: [master, v1.16]
6
6
  pull_request:
7
- branches: [master]
7
+ branches: [master, v1.16]
8
8
 
9
9
  jobs:
10
10
  test:
@@ -2,9 +2,9 @@ name: Testing on macOS
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [master]
5
+ branches: [master, v1.16]
6
6
  pull_request:
7
- branches: [master]
7
+ branches: [master, v1.16]
8
8
 
9
9
  jobs:
10
10
  test:
@@ -2,9 +2,9 @@ name: Testing on Windows
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [master]
5
+ branches: [master, v1.16]
6
6
  pull_request:
7
- branches: [master]
7
+ branches: [master, v1.16]
8
8
 
9
9
  jobs:
10
10
  test:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # v1.16
2
2
 
3
+ ## Release v1.16.3 - 2023/11/14
4
+
5
+ ### Bug Fix
6
+
7
+ * in_tail: Fix a stall bug on !follow_inode case
8
+ https://github.com/fluent/fluentd/pull/4327
9
+ * in_tail: add warning for silent stop on !follow_inodes case
10
+ https://github.com/fluent/fluentd/pull/4339
11
+ * Buffer: Fix NoMethodError with empty unstaged chunk arrays
12
+ https://github.com/fluent/fluentd/pull/4303
13
+ * Fix for rotate_age where Fluentd passes as Symbol
14
+ https://github.com/fluent/fluentd/pull/4311
15
+
3
16
  ## Release v1.16.2 - 2023/07/14
4
17
 
5
18
  ### Bug Fix
data/Rakefile CHANGED
@@ -13,7 +13,7 @@ task test: [:base_test]
13
13
  namespace :build do
14
14
  desc 'Build gems for all platforms'
15
15
  task :all do
16
- Bundler.with_clean_env do
16
+ Bundler.with_original_env do
17
17
  %w[ruby x86-mingw32 x64-mingw32 x64-mingw-ucrt].each do |name|
18
18
  ENV['GEM_BUILD_FAKE_PLATFORM'] = name
19
19
  Rake::Task["build"].execute
@@ -417,7 +417,7 @@ module Fluent
417
417
  if c.staged? && (enqueue || chunk_size_full?(c))
418
418
  m = c.metadata
419
419
  enqueue_chunk(m)
420
- if unstaged_chunks[m]
420
+ if unstaged_chunks[m] && !unstaged_chunks[m].empty?
421
421
  u = unstaged_chunks[m].pop
422
422
  u.synchronize do
423
423
  if u.unstaged? && !chunk_size_full?(u)
@@ -385,7 +385,7 @@ module Fluent::Plugin
385
385
  # So that inode can't be contained in `removed_hash`, and can't be unwatched by `stop_watchers`.
386
386
  #
387
387
  # This logic may work for `@follow_inodes false` too.
388
- # Just limiting the case to supress the impact to existing logics.
388
+ # Just limiting the case to suppress the impact to existing logics.
389
389
  @pf&.unwatch_removed_targets(target_paths_hash)
390
390
  need_unwatch_in_stop_watchers = false
391
391
  end
@@ -393,6 +393,28 @@ module Fluent::Plugin
393
393
  removed_hash = existence_paths_hash.reject {|key, value| target_paths_hash.key?(key)}
394
394
  added_hash = target_paths_hash.reject {|key, value| existence_paths_hash.key?(key)}
395
395
 
396
+ # If an exisiting TailWatcher already follows a target path with the different inode,
397
+ # it means that the TailWatcher following the rotated file still exists. In this case,
398
+ # `refresh_watcher` can't start the new TailWatcher for the new current file. So, we
399
+ # should output a warning log in order to prevent silent collection stops.
400
+ # (Such as https://github.com/fluent/fluentd/pull/4327)
401
+ # (Usually, such a TailWatcher should be removed from `@tails` in `update_watcher`.)
402
+ # (The similar warning may work for `@follow_inodes true` too. Just limiting the case
403
+ # to suppress the impact to existing logics.)
404
+ unless @follow_inodes
405
+ target_paths_hash.each do |path, target|
406
+ next unless @tails.key?(path)
407
+ # We can't use `existence_paths_hash[path].ino` because it is from `TailWatcher.ino`,
408
+ # which is very unstable parameter. (It can be `nil` or old).
409
+ # So, we need to use `TailWatcher.pe.read_inode`.
410
+ existing_watcher_inode = @tails[path].pe.read_inode
411
+ if existing_watcher_inode != target.ino
412
+ log.warn "Could not follow a file (inode: #{target.ino}) because an existing watcher for that filepath follows a different inode: #{existing_watcher_inode} (e.g. keeps watching a already rotated file). If you keep getting this message, please restart Fluentd.",
413
+ filepath: target.path
414
+ end
415
+ end
416
+ end
417
+
396
418
  stop_watchers(removed_hash, unwatched: need_unwatch_in_stop_watchers) unless removed_hash.empty?
397
419
  start_watchers(added_hash) unless added_hash.empty?
398
420
  @startup = false if @startup
@@ -564,7 +586,7 @@ module Fluent::Plugin
564
586
 
565
587
  tw.close if close_io
566
588
 
567
- if tw.unwatched && @pf
589
+ if @pf && tw.unwatched && (@follow_inode || !@tails[tw.path])
568
590
  target_info = TargetInfo.new(tw.path, ino)
569
591
  @pf.unwatch(target_info)
570
592
  end
@@ -62,7 +62,7 @@ module Fluent
62
62
  config_param :time_format, :string, default: '%Y-%m-%d %H:%M:%S %z'
63
63
  config_param :rotate_age, default: nil do |v|
64
64
  if Fluent::Log::LOG_ROTATE_AGE.include?(v)
65
- v.to_sym
65
+ v
66
66
  else
67
67
  begin
68
68
  Integer(v)
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '1.16.2'
19
+ VERSION = '1.16.3'
20
20
 
21
21
  end
@@ -151,7 +151,7 @@ module Fluent::Config
151
151
  data('daily' => "daily",
152
152
  'weekly' => 'weekly',
153
153
  'monthly' => 'monthly')
154
- test "symbols for rotate_age" do |age|
154
+ test "strings for rotate_age" do |age|
155
155
  conf = parse_text(<<-EOS)
156
156
  <system>
157
157
  <log>
@@ -160,7 +160,7 @@ module Fluent::Config
160
160
  </system>
161
161
  EOS
162
162
  sc = Fluent::SystemConfig.new(conf)
163
- assert_equal(age.to_sym, sc.log.rotate_age)
163
+ assert_equal(age, sc.log.rotate_age)
164
164
  end
165
165
 
166
166
  test "numeric number for rotate age" do
@@ -3017,4 +3017,109 @@ class TailInputTest < Test::Unit::TestCase
3017
3017
  )
3018
3018
  end
3019
3019
  end
3020
+
3021
+ sub_test_case "Update watchers for rotation without follow_inodes" do
3022
+ # The scenario where in_tail wrongly unwatches the PositionEntry.
3023
+ # This is reported in https://github.com/fluent/fluentd/issues/3614.
3024
+ def test_refreshTW_during_rotation
3025
+ config = config_element(
3026
+ "ROOT",
3027
+ "",
3028
+ {
3029
+ "path" => "#{@tmp_dir}/tail.txt0",
3030
+ "pos_file" => "#{@tmp_dir}/tail.pos",
3031
+ "tag" => "t1",
3032
+ "format" => "none",
3033
+ "read_from_head" => "true",
3034
+ # In order to detach the old watcher quickly.
3035
+ "rotate_wait" => "3s",
3036
+ # In order to reproduce the same condition stably, ensure that `refresh_watchers` is not
3037
+ # called by a timer.
3038
+ "refresh_interval" => "1h",
3039
+ # stat_watcher often calls `TailWatcher::on_notify` faster than creating a new log file,
3040
+ # so disable it in order to reproduce the same condition stably.
3041
+ "enable_stat_watcher" => "false",
3042
+ }
3043
+ )
3044
+ d = create_driver(config, false)
3045
+
3046
+ tail_watchers = []
3047
+ stub.proxy(d.instance).setup_watcher do |tw|
3048
+ tail_watchers.append(tw)
3049
+ tw
3050
+ end
3051
+
3052
+ Fluent::FileWrapper.open("#{@tmp_dir}/tail.txt0", "wb") {|f| f.puts "file1 log1"}
3053
+
3054
+ d.run(expect_records: 6, timeout: 15) do
3055
+ Fluent::FileWrapper.open("#{@tmp_dir}/tail.txt0", "ab") {|f| f.puts "file1 log2"}
3056
+ FileUtils.move("#{@tmp_dir}/tail.txt0", "#{@tmp_dir}/tail.txt" + "1")
3057
+
3058
+ # This reproduces the following situation:
3059
+ # `refresh_watchers` is called during the rotation process and it detects the current file being lost.
3060
+ # Then it stops and unwatches the TailWatcher.
3061
+ d.instance.refresh_watchers
3062
+
3063
+ Fluent::FileWrapper.open("#{@tmp_dir}/tail.txt0", "wb") {|f| f.puts "file2 log1"}
3064
+
3065
+ # `watch_timer` calls `TailWatcher::on_notify`, and then `update_watcher` trys to add the new TailWatcher.
3066
+ # After `rotate_wait` interval, the PositionEntry is unwatched.
3067
+ # HOWEVER, the new TailWatcher is still using that PositionEntry, so this breaks the PositionFile!!
3068
+ # That PositionEntry is removed from `PositionFile::map`, but it is still working and remaining in the real pos file.
3069
+ sleep 5
3070
+
3071
+ # Append to the new current log file.
3072
+ # The PositionEntry is updated although it does not exist in `PositionFile::map`.
3073
+ # `PositionFile::map`: empty
3074
+ # Real pos file: `.../tail.txt 0000000000000016 (inode)`
3075
+ Fluent::FileWrapper.open("#{@tmp_dir}/tail.txt0", "ab") {|f| f.puts "file2 log2"}
3076
+
3077
+ # Rotate again
3078
+ [1, 0].each do |i|
3079
+ FileUtils.move("#{@tmp_dir}/tail.txt#{i}", "#{@tmp_dir}/tail.txt#{i + 1}")
3080
+ end
3081
+ Fluent::FileWrapper.open("#{@tmp_dir}/tail.txt0", "wb") {|f| f.puts "file3 log1"}
3082
+
3083
+ # `watch_timer` calls `TailWatcher::on_notify`, and then `update_watcher` trys to update the TailWatcher.
3084
+ sleep 3
3085
+
3086
+ Fluent::FileWrapper.open("#{@tmp_dir}/tail.txt0", "ab") {|f| f.puts "file3 log2"}
3087
+
3088
+ # Wait `rotate_wait` for file2 to make sure to close all IO handlers
3089
+ sleep 3
3090
+ end
3091
+
3092
+ inode_0 = tail_watchers[0]&.ino
3093
+ inode_1 = tail_watchers[1]&.ino
3094
+ inode_2 = tail_watchers[2]&.ino
3095
+ record_values = d.events.collect { |event| event[2]["message"] }.sort
3096
+ position_entries = []
3097
+ Fluent::FileWrapper.open("#{@tmp_dir}/tail.pos", "r") do |f|
3098
+ f.readlines(chomp: true).each do |line|
3099
+ values = line.split("\t")
3100
+ position_entries.append([values[0], values[1], values[2].to_i(16)])
3101
+ end
3102
+ end
3103
+
3104
+ assert_equal(
3105
+ {
3106
+ record_values: ["file1 log1", "file1 log2", "file2 log1", "file2 log2", "file3 log1", "file3 log2"],
3107
+ tail_watcher_paths: ["#{@tmp_dir}/tail.txt0", "#{@tmp_dir}/tail.txt0", "#{@tmp_dir}/tail.txt0"],
3108
+ tail_watcher_inodes: [inode_0, inode_1, inode_2],
3109
+ tail_watcher_io_handler_opened_statuses: [false, false, false],
3110
+ position_entries: [
3111
+ # The recorded path is old, but it is no problem. The path is not used when using follow_inodes.
3112
+ ["#{@tmp_dir}/tail.txt0", "0000000000000016", inode_2],
3113
+ ],
3114
+ },
3115
+ {
3116
+ record_values: record_values,
3117
+ tail_watcher_paths: tail_watchers.collect { |tw| tw.path },
3118
+ tail_watcher_inodes: tail_watchers.collect { |tw| tw.ino },
3119
+ tail_watcher_io_handler_opened_statuses: tail_watchers.collect { |tw| tw.instance_variable_get(:@io_handler)&.opened? || false },
3120
+ position_entries: position_entries
3121
+ },
3122
+ )
3123
+ end
3124
+ end
3020
3125
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluentd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.16.2
4
+ version: 1.16.3
5
5
  platform: x64-mingw-ucrt
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-14 00:00:00.000000000 Z
11
+ date: 2023-11-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -1014,7 +1014,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1014
1014
  - !ruby/object:Gem::Version
1015
1015
  version: '0'
1016
1016
  requirements: []
1017
- rubygems_version: 3.3.5
1017
+ rubygems_version: 3.4.19
1018
1018
  signing_key:
1019
1019
  specification_version: 4
1020
1020
  summary: Fluentd event collector