fluentd 1.16.0 → 1.16.7
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 +4 -4
- data/.github/ISSUE_TEMPLATE/{bug_report.yaml → bug_report.yml} +1 -0
- data/.github/ISSUE_TEMPLATE/{feature_request.yaml → feature_request.yml} +1 -0
- data/.github/workflows/stale-actions.yml +24 -0
- data/.github/workflows/test.yml +39 -0
- data/CHANGELOG.md +161 -0
- data/CONTRIBUTING.md +1 -1
- data/MAINTAINERS.md +3 -3
- data/README.md +0 -2
- data/SECURITY.md +5 -9
- data/fluentd.gemspec +10 -2
- data/lib/fluent/command/ctl.rb +2 -2
- data/lib/fluent/command/fluentd.rb +1 -1
- data/lib/fluent/command/plugin_config_formatter.rb +1 -1
- data/lib/fluent/config/dsl.rb +1 -1
- data/lib/fluent/config/v1_parser.rb +2 -2
- data/lib/fluent/config/yaml_parser/parser.rb +4 -0
- data/lib/fluent/counter/server.rb +1 -1
- data/lib/fluent/counter/validator.rb +3 -3
- data/lib/fluent/engine.rb +1 -1
- data/lib/fluent/event.rb +8 -4
- data/lib/fluent/log.rb +9 -0
- data/lib/fluent/match.rb +1 -1
- data/lib/fluent/msgpack_factory.rb +6 -1
- data/lib/fluent/plugin/base.rb +1 -1
- data/lib/fluent/plugin/buffer.rb +96 -87
- data/lib/fluent/plugin/filter_record_transformer.rb +1 -1
- data/lib/fluent/plugin/in_forward.rb +1 -1
- data/lib/fluent/plugin/in_http.rb +8 -8
- data/lib/fluent/plugin/in_sample.rb +1 -1
- data/lib/fluent/plugin/in_tail/position_file.rb +32 -18
- data/lib/fluent/plugin/in_tail.rb +99 -31
- data/lib/fluent/plugin/in_tcp.rb +43 -0
- data/lib/fluent/plugin/out_exec_filter.rb +2 -2
- data/lib/fluent/plugin/out_file.rb +8 -0
- data/lib/fluent/plugin/output.rb +2 -2
- data/lib/fluent/plugin/parser_json.rb +4 -12
- data/lib/fluent/plugin_helper/event_loop.rb +2 -2
- data/lib/fluent/plugin_helper/record_accessor.rb +1 -1
- data/lib/fluent/plugin_helper/server.rb +8 -0
- data/lib/fluent/plugin_helper/thread.rb +3 -3
- data/lib/fluent/plugin_id.rb +1 -1
- data/lib/fluent/supervisor.rb +2 -2
- data/lib/fluent/system_config.rb +1 -1
- data/lib/fluent/version.rb +1 -1
- data/lib/fluent/winsvc.rb +28 -3
- data/templates/new_gem/test/helper.rb.erb +0 -1
- data/test/command/test_cat.rb +2 -2
- data/test/command/test_fluentd.rb +65 -12
- data/test/config/test_system_config.rb +2 -2
- data/test/helper.rb +27 -7
- data/test/plugin/in_tail/test_io_handler.rb +13 -14
- data/test/plugin/in_tail/test_position_file.rb +37 -8
- data/test/plugin/out_forward/test_ack_handler.rb +3 -3
- data/test/plugin/out_forward/test_socket_cache.rb +3 -3
- data/test/plugin/test_base.rb +1 -1
- data/test/plugin/test_buffer.rb +110 -0
- data/test/plugin/test_buffer_chunk.rb +11 -0
- data/test/plugin/test_in_forward.rb +11 -10
- data/test/plugin/test_in_http.rb +1 -1
- data/test/plugin/test_in_monitor_agent.rb +6 -6
- data/test/plugin/test_in_syslog.rb +25 -18
- data/test/plugin/test_in_tail.rb +639 -0
- data/test/plugin/test_in_tcp.rb +75 -5
- data/test/plugin/test_in_udp.rb +35 -1
- data/test/plugin/test_in_unix.rb +2 -2
- data/test/plugin/test_multi_output.rb +1 -1
- data/test/plugin/test_out_exec_filter.rb +14 -9
- data/test/plugin/test_out_file.rb +24 -4
- data/test/plugin/test_out_forward.rb +36 -42
- data/test/plugin/test_out_stream.rb +1 -1
- data/test/plugin/test_output.rb +12 -12
- data/test/plugin/test_output_as_buffered.rb +44 -44
- data/test/plugin/test_output_as_buffered_compress.rb +32 -18
- data/test/plugin/test_output_as_buffered_retries.rb +1 -1
- data/test/plugin/test_output_as_buffered_secondary.rb +2 -2
- data/test/plugin/test_parser_json.rb +31 -0
- data/test/plugin_helper/test_child_process.rb +15 -5
- data/test/plugin_helper/test_http_server_helper.rb +1 -1
- data/test/plugin_helper/test_server.rb +110 -38
- data/test/plugin_helper/test_socket.rb +1 -1
- data/test/test_config.rb +6 -0
- data/test/test_event_router.rb +2 -2
- data/test/test_log.rb +38 -1
- data/test/test_msgpack_factory.rb +32 -0
- data/test/test_supervisor.rb +13 -0
- metadata +44 -17
- data/.github/workflows/linux-test.yaml +0 -36
- data/.github/workflows/macos-test.yaml +0 -34
- data/.github/workflows/windows-test.yaml +0 -49
data/lib/fluent/plugin/buffer.rb
CHANGED
|
@@ -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)
|
|
@@ -580,7 +580,7 @@ module Fluent
|
|
|
580
580
|
chunk = @dequeued.delete(chunk_id)
|
|
581
581
|
return false unless chunk # already purged by other thread
|
|
582
582
|
@queue.unshift(chunk)
|
|
583
|
-
log.trace "chunk taken back", instance: self.object_id, chunk_id: dump_unique_id_hex(chunk_id), metadata: chunk.metadata
|
|
583
|
+
log.on_trace { log.trace "chunk taken back", instance: self.object_id, chunk_id: dump_unique_id_hex(chunk_id), metadata: chunk.metadata }
|
|
584
584
|
@queued_num[chunk.metadata] += 1 # BUG if nil
|
|
585
585
|
@dequeued_num[chunk.metadata] -= 1
|
|
586
586
|
end
|
|
@@ -610,7 +610,7 @@ module Fluent
|
|
|
610
610
|
@queued_num.delete(metadata)
|
|
611
611
|
@dequeued_num.delete(metadata)
|
|
612
612
|
end
|
|
613
|
-
log.trace "chunk purged", instance: self.object_id, chunk_id: dump_unique_id_hex(chunk_id), metadata: metadata
|
|
613
|
+
log.on_trace { log.trace "chunk purged", instance: self.object_id, chunk_id: dump_unique_id_hex(chunk_id), metadata: metadata }
|
|
614
614
|
end
|
|
615
615
|
|
|
616
616
|
nil
|
|
@@ -728,7 +728,6 @@ module Fluent
|
|
|
728
728
|
|
|
729
729
|
def write_step_by_step(metadata, data, format, splits_count, &block)
|
|
730
730
|
splits = []
|
|
731
|
-
errors = []
|
|
732
731
|
if splits_count > data.size
|
|
733
732
|
splits_count = data.size
|
|
734
733
|
end
|
|
@@ -749,16 +748,14 @@ module Fluent
|
|
|
749
748
|
modified_chunks = []
|
|
750
749
|
modified_metadata = metadata
|
|
751
750
|
get_next_chunk = ->(){
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
modified_chunks << c
|
|
761
|
-
c
|
|
751
|
+
if staged_chunk_used
|
|
752
|
+
# Staging new chunk here is bad idea:
|
|
753
|
+
# Recovering whole state including newly staged chunks is much harder than current implementation.
|
|
754
|
+
modified_metadata = modified_metadata.dup_next
|
|
755
|
+
generate_chunk(modified_metadata)
|
|
756
|
+
else
|
|
757
|
+
synchronize { @stage[modified_metadata] ||= generate_chunk(modified_metadata).staged! }
|
|
758
|
+
end
|
|
762
759
|
}
|
|
763
760
|
|
|
764
761
|
writing_splits_index = 0
|
|
@@ -766,104 +763,116 @@ module Fluent
|
|
|
766
763
|
|
|
767
764
|
while writing_splits_index < splits.size
|
|
768
765
|
chunk = get_next_chunk.call
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
original_bytesize = committed_bytesize = chunk.bytesize
|
|
774
|
-
begin
|
|
775
|
-
while writing_splits_index < splits.size
|
|
776
|
-
split = splits[writing_splits_index]
|
|
777
|
-
formatted_split = format ? format.call(split) : nil
|
|
766
|
+
errors = []
|
|
767
|
+
# The chunk must be locked until being passed to &block.
|
|
768
|
+
chunk.mon_enter
|
|
769
|
+
modified_chunks << {chunk: chunk, adding_bytesize: 0, errors: errors}
|
|
778
770
|
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
if @compress != :text
|
|
782
|
-
determined_bytesize = nil
|
|
783
|
-
elsif formatted_split
|
|
784
|
-
determined_bytesize = formatted_split.bytesize
|
|
785
|
-
elsif split.first.respond_to?(:bytesize)
|
|
786
|
-
determined_bytesize = split.first.bytesize
|
|
787
|
-
end
|
|
771
|
+
raise ShouldRetry unless chunk.writable?
|
|
772
|
+
staged_chunk_used = true if chunk.staged?
|
|
788
773
|
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
errors << "a #{determined_bytesize} bytes record (nth: #{writing_splits_index}) is larger than buffer chunk limit size (#{@chunk_limit_size})"
|
|
795
|
-
writing_splits_index += 1
|
|
796
|
-
next
|
|
797
|
-
end
|
|
774
|
+
original_bytesize = committed_bytesize = chunk.bytesize
|
|
775
|
+
begin
|
|
776
|
+
while writing_splits_index < splits.size
|
|
777
|
+
split = splits[writing_splits_index]
|
|
778
|
+
formatted_split = format ? format.call(split) : nil
|
|
798
779
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
780
|
+
if split.size == 1 # Check BufferChunkOverflowError
|
|
781
|
+
determined_bytesize = nil
|
|
782
|
+
if @compress != :text
|
|
783
|
+
determined_bytesize = nil
|
|
784
|
+
elsif formatted_split
|
|
785
|
+
determined_bytesize = formatted_split.bytesize
|
|
786
|
+
elsif split.first.respond_to?(:bytesize)
|
|
787
|
+
determined_bytesize = split.first.bytesize
|
|
805
788
|
end
|
|
806
789
|
|
|
807
|
-
if
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
790
|
+
if determined_bytesize && determined_bytesize > @chunk_limit_size
|
|
791
|
+
# It is a obvious case that BufferChunkOverflowError should be raised here.
|
|
792
|
+
# But if it raises here, already processed 'split' or
|
|
793
|
+
# the proceeding 'split' will be lost completely.
|
|
794
|
+
# So it is a last resort to delay raising such a exception
|
|
795
|
+
errors << "a #{determined_bytesize} bytes record (nth: #{writing_splits_index}) is larger than buffer chunk limit size (#{@chunk_limit_size})"
|
|
796
|
+
writing_splits_index += 1
|
|
797
|
+
next
|
|
811
798
|
end
|
|
812
|
-
adding_bytes = chunk.bytesize - committed_bytesize
|
|
813
799
|
|
|
814
|
-
if
|
|
815
|
-
|
|
800
|
+
if determined_bytesize.nil? || chunk.bytesize + determined_bytesize > @chunk_limit_size
|
|
801
|
+
# The split will (might) cause size over so keep already processed
|
|
802
|
+
# 'split' content here (allow performance regression a bit).
|
|
803
|
+
chunk.commit
|
|
816
804
|
committed_bytesize = chunk.bytesize
|
|
805
|
+
end
|
|
806
|
+
end
|
|
817
807
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
# As already processed content is kept after rollback, then unstaged chunk should be queued.
|
|
825
|
-
# After that, re-process current split again.
|
|
826
|
-
# New chunk should be allocated, to do it, modify @stage and so on.
|
|
827
|
-
synchronize { @stage.delete(modified_metadata) }
|
|
828
|
-
staged_chunk_used = false
|
|
829
|
-
chunk.unstaged!
|
|
830
|
-
break
|
|
831
|
-
end
|
|
832
|
-
end
|
|
808
|
+
if format
|
|
809
|
+
chunk.concat(formatted_split, split.size)
|
|
810
|
+
else
|
|
811
|
+
chunk.append(split, compress: @compress)
|
|
812
|
+
end
|
|
813
|
+
adding_bytes = chunk.bytesize - committed_bytesize
|
|
833
814
|
|
|
834
|
-
|
|
835
|
-
|
|
815
|
+
if chunk_size_over?(chunk) # split size is larger than difference between size_full? and size_over?
|
|
816
|
+
chunk.rollback
|
|
817
|
+
committed_bytesize = chunk.bytesize
|
|
818
|
+
|
|
819
|
+
if split.size == 1 # Check BufferChunkOverflowError again
|
|
820
|
+
if adding_bytes > @chunk_limit_size
|
|
821
|
+
errors << "concatenated/appended a #{adding_bytes} bytes record (nth: #{writing_splits_index}) is larger than buffer chunk limit size (#{@chunk_limit_size})"
|
|
822
|
+
writing_splits_index += 1
|
|
823
|
+
next
|
|
836
824
|
else
|
|
837
|
-
|
|
825
|
+
# As already processed content is kept after rollback, then unstaged chunk should be queued.
|
|
826
|
+
# After that, re-process current split again.
|
|
827
|
+
# New chunk should be allocated, to do it, modify @stage and so on.
|
|
828
|
+
synchronize { @stage.delete(modified_metadata) }
|
|
829
|
+
staged_chunk_used = false
|
|
830
|
+
chunk.unstaged!
|
|
831
|
+
break
|
|
838
832
|
end
|
|
833
|
+
end
|
|
839
834
|
|
|
840
|
-
|
|
835
|
+
if chunk_size_full?(chunk) || split.size == 1
|
|
836
|
+
enqueue_chunk_before_retry = true
|
|
837
|
+
else
|
|
838
|
+
splits_count *= 10
|
|
841
839
|
end
|
|
842
840
|
|
|
843
|
-
|
|
841
|
+
raise ShouldRetry
|
|
842
|
+
end
|
|
843
|
+
|
|
844
|
+
writing_splits_index += 1
|
|
844
845
|
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
end
|
|
846
|
+
if chunk_size_full?(chunk)
|
|
847
|
+
break
|
|
848
848
|
end
|
|
849
|
-
rescue
|
|
850
|
-
chunk.purge if chunk.unstaged? # unstaged chunk will leak unless purge it
|
|
851
|
-
raise
|
|
852
849
|
end
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
850
|
+
rescue
|
|
851
|
+
chunk.purge if chunk.unstaged? # unstaged chunk will leak unless purge it
|
|
852
|
+
raise
|
|
856
853
|
end
|
|
854
|
+
|
|
855
|
+
modified_chunks.last[:adding_bytesize] = chunk.bytesize - original_bytesize
|
|
856
|
+
end
|
|
857
|
+
modified_chunks.each do |data|
|
|
858
|
+
block.call(data[:chunk], data[:adding_bytesize], data[:errors])
|
|
857
859
|
end
|
|
858
860
|
rescue ShouldRetry
|
|
859
|
-
modified_chunks.each do |
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
861
|
+
modified_chunks.each do |data|
|
|
862
|
+
chunk = data[:chunk]
|
|
863
|
+
chunk.rollback rescue nil
|
|
864
|
+
if chunk.unstaged?
|
|
865
|
+
chunk.purge rescue nil
|
|
863
866
|
end
|
|
867
|
+
chunk.mon_exit rescue nil
|
|
864
868
|
end
|
|
865
869
|
enqueue_chunk(metadata) if enqueue_chunk_before_retry
|
|
866
870
|
retry
|
|
871
|
+
ensure
|
|
872
|
+
modified_chunks.each do |data|
|
|
873
|
+
chunk = data[:chunk]
|
|
874
|
+
chunk.mon_exit
|
|
875
|
+
end
|
|
867
876
|
end
|
|
868
877
|
|
|
869
878
|
STATS_KEYS = [
|
|
@@ -316,7 +316,7 @@ module Fluent::Plugin
|
|
|
316
316
|
end
|
|
317
317
|
|
|
318
318
|
(Object.instance_methods).each do |m|
|
|
319
|
-
undef_method m unless
|
|
319
|
+
undef_method m unless /^__|respond_to_missing\?|object_id|public_methods|instance_eval|method_missing|define_singleton_method|respond_to\?|new_ostruct_member|^class$/.match?(m.to_s)
|
|
320
320
|
end
|
|
321
321
|
end
|
|
322
322
|
end
|
|
@@ -430,7 +430,7 @@ module Fluent::Plugin
|
|
|
430
430
|
end
|
|
431
431
|
_ping, hostname, shared_key_salt, shared_key_hexdigest, username, password_digest = message
|
|
432
432
|
|
|
433
|
-
node = @nodes.
|
|
433
|
+
node = @nodes.find{|n| n[:address].include?(remote_addr) rescue false }
|
|
434
434
|
if !node && !@security.allow_anonymous_source
|
|
435
435
|
log.warn "Anonymous client disallowed", address: remote_addr, hostname: hostname
|
|
436
436
|
return false, "anonymous source host '#{remote_addr}' denied", nil
|
|
@@ -428,7 +428,7 @@ module Fluent::Plugin
|
|
|
428
428
|
@content_type = ""
|
|
429
429
|
@content_encoding = ""
|
|
430
430
|
headers.each_pair {|k,v|
|
|
431
|
-
@env["HTTP_#{k.
|
|
431
|
+
@env["HTTP_#{k.tr('-','_').upcase}"] = v
|
|
432
432
|
case k
|
|
433
433
|
when /\AExpect\z/i
|
|
434
434
|
expect = v
|
|
@@ -439,9 +439,9 @@ module Fluent::Plugin
|
|
|
439
439
|
when /\AContent-Encoding\Z/i
|
|
440
440
|
@content_encoding = v
|
|
441
441
|
when /\AConnection\Z/i
|
|
442
|
-
if
|
|
442
|
+
if /close/i.match?(v)
|
|
443
443
|
@keep_alive = false
|
|
444
|
-
elsif
|
|
444
|
+
elsif /Keep-alive/i.match?(v)
|
|
445
445
|
@keep_alive = true
|
|
446
446
|
end
|
|
447
447
|
when /\AOrigin\Z/i
|
|
@@ -566,16 +566,16 @@ module Fluent::Plugin
|
|
|
566
566
|
|
|
567
567
|
if @format_name != 'default'
|
|
568
568
|
params[EVENT_RECORD_PARAMETER] = @body
|
|
569
|
-
elsif
|
|
569
|
+
elsif /^application\/x-www-form-urlencoded/.match?(@content_type)
|
|
570
570
|
params.update WEBrick::HTTPUtils.parse_query(@body)
|
|
571
571
|
elsif @content_type =~ /^multipart\/form-data; boundary=(.+)/
|
|
572
572
|
boundary = WEBrick::HTTPUtils.dequote($1)
|
|
573
573
|
params.update WEBrick::HTTPUtils.parse_form_data(@body, boundary)
|
|
574
|
-
elsif
|
|
574
|
+
elsif /^application\/json/.match?(@content_type)
|
|
575
575
|
params['json'] = @body
|
|
576
|
-
elsif
|
|
576
|
+
elsif /^application\/msgpack/.match?(@content_type)
|
|
577
577
|
params['msgpack'] = @body
|
|
578
|
-
elsif
|
|
578
|
+
elsif /^application\/x-ndjson/.match?(@content_type)
|
|
579
579
|
params['ndjson'] = @body
|
|
580
580
|
end
|
|
581
581
|
path_info = uri.path
|
|
@@ -585,7 +585,7 @@ module Fluent::Plugin
|
|
|
585
585
|
query_params = WEBrick::HTTPUtils.parse_query(uri.query)
|
|
586
586
|
|
|
587
587
|
query_params.each_pair {|k,v|
|
|
588
|
-
params["QUERY_#{k.
|
|
588
|
+
params["QUERY_#{k.tr('-','_').upcase}"] = v
|
|
589
589
|
}
|
|
590
590
|
end
|
|
591
591
|
|
|
@@ -64,7 +64,7 @@ module Fluent::Plugin
|
|
|
64
64
|
def configure(conf)
|
|
65
65
|
super
|
|
66
66
|
@sample_index = 0
|
|
67
|
-
config = conf.elements.
|
|
67
|
+
config = conf.elements.find{|e| e.name == 'storage' }
|
|
68
68
|
@storage = storage_create(usage: 'suspend', conf: config, default_type: DEFAULT_STORAGE_TYPE)
|
|
69
69
|
end
|
|
70
70
|
|
|
@@ -53,10 +53,16 @@ module Fluent::Plugin
|
|
|
53
53
|
}
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
def unwatch_removed_targets(existing_targets)
|
|
57
|
+
@map.reject { |key, entry|
|
|
58
|
+
existing_targets.key?(key)
|
|
59
|
+
}.each_key { |key|
|
|
60
|
+
unwatch_key(key)
|
|
61
|
+
}
|
|
62
|
+
end
|
|
63
|
+
|
|
56
64
|
def unwatch(target_info)
|
|
57
|
-
|
|
58
|
-
entry.update_pos(UNWATCHED_POSITION)
|
|
59
|
-
end
|
|
65
|
+
unwatch_key(@follow_inodes ? target_info.ino : target_info.path)
|
|
60
66
|
end
|
|
61
67
|
|
|
62
68
|
def load(existing_targets = nil)
|
|
@@ -96,6 +102,7 @@ module Fluent::Plugin
|
|
|
96
102
|
end
|
|
97
103
|
|
|
98
104
|
entries = fetch_compacted_entries
|
|
105
|
+
@logger&.debug "Compacted entries: ", entries.keys
|
|
99
106
|
|
|
100
107
|
@file_mutex.synchronize do
|
|
101
108
|
if last_modified == @file.mtime && size == @file.size
|
|
@@ -117,17 +124,31 @@ module Fluent::Plugin
|
|
|
117
124
|
|
|
118
125
|
private
|
|
119
126
|
|
|
127
|
+
def unwatch_key(key)
|
|
128
|
+
if (entry = @map.delete(key))
|
|
129
|
+
entry.update_pos(UNWATCHED_POSITION)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
120
133
|
def compact(existing_targets = nil)
|
|
121
134
|
@file_mutex.synchronize do
|
|
122
|
-
entries = fetch_compacted_entries
|
|
135
|
+
entries = fetch_compacted_entries
|
|
136
|
+
@logger&.debug "Compacted entries: ", entries.keys
|
|
137
|
+
|
|
138
|
+
if existing_targets
|
|
139
|
+
entries = remove_deleted_files_entries(entries, existing_targets)
|
|
140
|
+
@logger&.debug "Remove missing entries.",
|
|
141
|
+
existing_targets: existing_targets.keys,
|
|
142
|
+
entries_after_removing: entries.keys
|
|
143
|
+
end
|
|
123
144
|
|
|
124
145
|
@file.pos = 0
|
|
125
146
|
@file.truncate(0)
|
|
126
|
-
@file.write(entries.join)
|
|
147
|
+
@file.write(entries.values.map(&:to_entry_fmt).join)
|
|
127
148
|
end
|
|
128
149
|
end
|
|
129
150
|
|
|
130
|
-
def fetch_compacted_entries
|
|
151
|
+
def fetch_compacted_entries
|
|
131
152
|
entries = {}
|
|
132
153
|
|
|
133
154
|
@file.pos = 0
|
|
@@ -145,31 +166,24 @@ module Fluent::Plugin
|
|
|
145
166
|
if pos == UNWATCHED_POSITION
|
|
146
167
|
@logger.debug "Remove unwatched line from pos_file: #{line}" if @logger
|
|
147
168
|
else
|
|
148
|
-
if entries.include?(path)
|
|
149
|
-
@logger.warn("#{path} already exists. use latest one: deleted #{entries[path]}") if @logger
|
|
150
|
-
end
|
|
151
|
-
|
|
152
169
|
if @follow_inodes
|
|
170
|
+
@logger&.warn("#{path} (inode: #{ino}) already exists. use latest one: deleted #{entries[ino]}") if entries.include?(ino)
|
|
153
171
|
entries[ino] = Entry.new(path, pos, ino, file_pos + path.bytesize + 1)
|
|
154
172
|
else
|
|
173
|
+
@logger&.warn("#{path} already exists. use latest one: deleted #{entries[path]}") if entries.include?(path)
|
|
155
174
|
entries[path] = Entry.new(path, pos, ino, file_pos + path.bytesize + 1)
|
|
156
175
|
end
|
|
157
176
|
file_pos += line.size
|
|
158
177
|
end
|
|
159
178
|
end
|
|
160
179
|
|
|
161
|
-
entries = remove_deleted_files_entries(entries, existing_targets)
|
|
162
180
|
entries
|
|
163
181
|
end
|
|
164
182
|
|
|
165
183
|
def remove_deleted_files_entries(existent_entries, existing_targets)
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
else
|
|
171
|
-
existent_entries
|
|
172
|
-
end
|
|
184
|
+
existent_entries.select { |path_or_ino|
|
|
185
|
+
existing_targets.key?(path_or_ino)
|
|
186
|
+
}
|
|
173
187
|
end
|
|
174
188
|
end
|
|
175
189
|
|