@@ -96,9 +96,9 @@ def initialize
96
96
config_param :enable_watch_timer , :bool , default : true
97
97
desc 'Enable the stat watcher based on inotify.'
98
98
config_param :enable_stat_watcher , :bool , default : true
99
- desc 'The encoding after conversion of the input.'
100
- config_param :encoding , :string , default : nil
101
99
desc 'The encoding of the input.'
100
+ config_param :encoding , :string , default : nil
101
+ desc "The original encoding of the input. If set, in_tail tries to encode string from this to 'encoding'. Must be set with 'encoding'. "
102
102
config_param :from_encoding , :string , default : nil
103
103
desc 'Add the log path being tailed to records. Specify the field name to be used.'
104
104
config_param :path_key , :string , default : nil
@@ -828,17 +828,27 @@ def statistics
828
828
private
829
829
830
830
def io_handler ( watcher , path )
831
- TailWatcher ::IOHandler . new (
832
- watcher ,
831
+ opts = {
833
832
path : path ,
834
833
log : log ,
835
834
read_lines_limit : @read_lines_limit ,
836
835
read_bytes_limit_per_second : @read_bytes_limit_per_second ,
837
836
open_on_every_update : @open_on_every_update ,
838
- from_encoding : @from_encoding ,
839
- encoding : @encoding ,
840
837
metrics : @metrics ,
841
838
max_line_size : @max_line_size ,
839
+ }
840
+ unless @encoding . nil?
841
+ if @from_encoding . nil?
842
+ opts [ :encoding ] = @encoding
843
+ else
844
+ opts [ :encoding ] = @from_encoding
845
+ opts [ :encoding_to_convert ] = @encoding
846
+ end
847
+ end
848
+
849
+ TailWatcher ::IOHandler . new (
850
+ watcher ,
851
+ **opts ,
842
852
&method ( :receive_lines )
843
853
)
844
854
end
@@ -1031,46 +1041,30 @@ def swap_state(pe)
1031
1041
end
1032
1042
1033
1043
class FIFO
1034
- def initialize ( from_encoding , encoding , log , max_line_size = nil )
1035
- @from_encoding = from_encoding
1036
- @encoding = encoding
1037
- @need_enc = from_encoding != encoding
1038
- @buffer = '' . force_encoding ( from_encoding )
1039
- @eol = "\n " . encode ( from_encoding ) . freeze
1044
+ def initialize ( encoding , log , max_line_size = nil , encoding_to_convert = nil )
1045
+ @buffer = '' . force_encoding ( encoding )
1046
+ @eol = "\n " . encode ( encoding ) . freeze
1047
+ @encoding_to_convert = encoding_to_convert
1040
1048
@max_line_size = max_line_size
1041
1049
@skip_current_line = false
1042
1050
@skipping_current_line_bytesize = 0
1043
1051
@log = log
1044
1052
end
1045
1053
1046
- attr_reader :from_encoding , :encoding , : buffer, :max_line_size
1054
+ attr_reader :buffer , :max_line_size
1047
1055
1048
1056
def <<( chunk )
1049
- # Although "chunk" is most likely transient besides String#force_encoding itself
1050
- # won't affect the actual content of it, it is also probable that "chunk" is
1051
- # a reused buffer and changing its encoding causes some problems on the caller side.
1052
- #
1053
- # Actually, the caller here is specific and "chunk" comes from IO#partial with
1054
- # the second argument, which the function always returns as a return value.
1055
- #
1056
- # Feeding a string that has its encoding attribute set to any double-byte or
1057
- # quad-byte encoding to IO#readpartial as the second arguments results in an
1058
- # assertion failure on Ruby < 2.4.0 for unknown reasons.
1059
- orig_encoding = chunk . encoding
1060
- chunk . force_encoding ( from_encoding )
1061
1057
@buffer << chunk
1062
- # Thus the encoding needs to be reverted back here
1063
- chunk . force_encoding ( orig_encoding )
1064
1058
end
1065
1059
1066
1060
def convert ( s )
1067
- if @need_enc
1068
- s . encode! ( @encoding , @from_encoding )
1061
+ if @encoding_to_convert
1062
+ s . encode! ( @encoding_to_convert )
1069
1063
else
1070
1064
s
1071
1065
end
1072
1066
rescue
1073
- s . encode! ( @encoding , @from_encoding , :invalid => :replace , :undef => :replace )
1067
+ s . encode! ( @encoding_to_convert , :invalid => :replace , :undef => :replace )
1074
1068
end
1075
1069
1076
1070
def read_lines ( lines )
@@ -1136,14 +1130,15 @@ class IOHandler
1136
1130
1137
1131
attr_accessor :shutdown_timeout
1138
1132
1139
- def initialize ( watcher , path :, read_lines_limit :, read_bytes_limit_per_second :, max_line_size : nil , log :, open_on_every_update :, from_encoding : nil , encoding : nil , metrics :, &receive_lines )
1133
+ def initialize ( watcher , path :, read_lines_limit :, read_bytes_limit_per_second :, max_line_size : nil , log :, open_on_every_update :, encoding : Encoding :: ASCII_8BIT , encoding_to_convert : nil , metrics :, &receive_lines )
1140
1134
@watcher = watcher
1141
1135
@path = path
1142
1136
@read_lines_limit = read_lines_limit
1143
1137
@read_bytes_limit_per_second = read_bytes_limit_per_second
1144
1138
@receive_lines = receive_lines
1145
1139
@open_on_every_update = open_on_every_update
1146
- @fifo = FIFO . new ( from_encoding || Encoding ::ASCII_8BIT , encoding || Encoding ::ASCII_8BIT , log , max_line_size )
1140
+ @encoding = encoding
1141
+ @fifo = FIFO . new ( encoding , log , max_line_size , encoding_to_convert )
1147
1142
@lines = [ ]
1148
1143
@io = nil
1149
1144
@notify_mutex = Mutex . new
@@ -1225,7 +1220,7 @@ def handle_notify
1225
1220
end
1226
1221
1227
1222
with_io do |io |
1228
- iobuf = '' . force_encoding ( 'ASCII-8BIT' )
1223
+ iobuf = '' . force_encoding ( @encoding )
1229
1224
begin
1230
1225
read_more = false
1231
1226
has_skipped_line = false
0 commit comments