@@ -191,7 +191,7 @@ def _get_ignore_regex(
191191 return "|" .join (regex_set ) or "nothing_to_ignore"
192192
193193
194- def _search_log_lines (
194+ def _search_log_lines ( # noqa: C901
195195 logfile : pl .Path ,
196196 rotated_logs : list [RotableLog ],
197197 errors_re : re .Pattern ,
@@ -210,15 +210,23 @@ def _search_log_lines(
210210 infile .seek (logfile_rec .seek - 1 )
211211 # Check if the byte is a newline, which means that the offset starts at
212212 # the beginning of a line.
213- if infile .read (1 ) != "\n " :
214- # Skip the first line if the line is not complete
213+ if infile .read (1 ) not in ( "\n " , " \r " ) :
214+ # Skip the first line if the line is incomplete
215215 infile .readline ()
216216
217217 look_back_buf = ["" ] * ERRORS_LOOK_BACK_LINES
218+ incomplete_line = ""
218219
219220 # Read the file in chunks
220221 while chunk := infile .read (BUFFER_SIZE ):
222+ # Prepend any leftover from the last chunk
223+ if incomplete_line :
224+ chunk = incomplete_line + chunk
221225 lines = chunk .splitlines (keepends = True ) # Preserve line endings
226+
227+ # Check if the last line is incomplete
228+ incomplete_line = lines .pop () if not lines [- 1 ].endswith (("\n " , "\r " )) else ""
229+
222230 for line in lines :
223231 look_back_buf .append (line )
224232 look_back_buf .pop (0 )
@@ -236,7 +244,11 @@ def _search_log_lines(
236244
237245 # Get offset for the "live" log file
238246 if logfile_rec .logfile == logfile :
239- last_line_pos = infile .tell ()
247+ if incomplete_line :
248+ # Adjust the offset to point before the incomplete line
249+ last_line_pos = infile .tell () - len (incomplete_line .encode ("utf-8" ))
250+ else :
251+ last_line_pos = infile .tell ()
240252
241253 # Record last search offset for the "live" log file
242254 if last_line_pos >= 0 :
0 commit comments