From 1e5bae71ded5b1c016a5d4474c3d95c6f24b20a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Garc=C3=ADa?= Date: Sat, 7 Mar 2026 00:59:31 +0100 Subject: [PATCH 1/4] feat: ellipsis for huge log lines --- forms-bridge/includes/class-logger.php | 35 +++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/forms-bridge/includes/class-logger.php b/forms-bridge/includes/class-logger.php index 732bfc9a..37586839 100644 --- a/forms-bridge/includes/class-logger.php +++ b/forms-bridge/includes/class-logger.php @@ -85,8 +85,7 @@ private static function logs( $lines = 500 ) { $buffer = 4096; $socket = fopen( $log_path, 'r' ); - $cursor = -1; - fseek( $socket, $cursor, SEEK_END ); + fseek( $socket, -1, SEEK_END ); if ( "\n" !== fread( $socket, 1 ) ) { --$lines; @@ -105,7 +104,37 @@ private static function logs( $lines = 500 ) { fseek( $socket, -mb_strlen( $chunk, '8bit' ), SEEK_CUR ); - $lines -= substr_count( $chunk, "\n" ); + $line_breaks = substr_count( $chunk, "\n" ); + while ( ! $line_breaks && ftell( $socket ) > 0 ) { + $seek = min( ftell( $socket ), $buffer ); + + fseek( $socket, -$seek, SEEK_CUR ); + $chunk = fread( $socket, $seek ); + fseek( $socket, -mb_strlen( $chunk, '8bit' ), SEEK_CUR ); + + $line_breaks = substr_count( $chunk, "\n" ); + + if ( $line_breaks ) { + // Then, read forward and concat to the output with an ellipsis. + fseek( $socket, strrpos( $chunk, "\n" ), SEEK_CUR ); + $chunk = fread( $socket, $buffer ); + fseek( $socket, -mb_strlen( $chunk, '8bit' ), SEEK_CUR ); + + $output = $chunk . ' (...) ' . $output; + break; + } + } + + if ( ! $line_breaks ) { + // End of file reached without any line break. + $chunk = fread( $socket, $buffer ); + fseek( $socket, 0, SEEK_SET ); + } else { + // Cursor is at the first line break occurrence. No line breaks added to the output. + $line_breaks = 0; + } + + $lines -= $line_breaks; } while ( $lines++ < 0 ) { From 451852742b2d778eed4f6ec8034065010248f85b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Garc=C3=ADa?= Date: Sat, 7 Mar 2026 01:37:10 +0100 Subject: [PATCH 2/4] fix: skip ellipsis for lines with less than 2 buffers length --- forms-bridge/includes/class-logger.php | 61 +++++++++++++++++--------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/forms-bridge/includes/class-logger.php b/forms-bridge/includes/class-logger.php index 37586839..dc3d6b2c 100644 --- a/forms-bridge/includes/class-logger.php +++ b/forms-bridge/includes/class-logger.php @@ -85,7 +85,8 @@ private static function logs( $lines = 500 ) { $buffer = 4096; $socket = fopen( $log_path, 'r' ); - fseek( $socket, -1, SEEK_END ); + $cursor = -1; + fseek( $socket, $cursor, SEEK_END ); if ( "\n" !== fread( $socket, 1 ) ) { --$lines; @@ -104,32 +105,52 @@ private static function logs( $lines = 500 ) { fseek( $socket, -mb_strlen( $chunk, '8bit' ), SEEK_CUR ); + $cursor = ftell( $socket ); $line_breaks = substr_count( $chunk, "\n" ); - while ( ! $line_breaks && ftell( $socket ) > 0 ) { - $seek = min( ftell( $socket ), $buffer ); - fseek( $socket, -$seek, SEEK_CUR ); - $chunk = fread( $socket, $seek ); - fseek( $socket, -mb_strlen( $chunk, '8bit' ), SEEK_CUR ); - - $line_breaks = substr_count( $chunk, "\n" ); + if ( ! $line_breaks ) { + while ( ftell( $socket ) > 0 ) { + $seek = min( ftell( $socket ), $buffer ); - if ( $line_breaks ) { - // Then, read forward and concat to the output with an ellipsis. - fseek( $socket, strrpos( $chunk, "\n" ), SEEK_CUR ); - $chunk = fread( $socket, $buffer ); + fseek( $socket, -$seek, SEEK_CUR ); + $chunk = fread( $socket, $seek ); fseek( $socket, -mb_strlen( $chunk, '8bit' ), SEEK_CUR ); - $output = $chunk . ' (...) ' . $output; - break; + $line_breaks = substr_count( $chunk, "\n" ); + + if ( $line_breaks ) { + // Then, read forward and concat to the output with an ellipsis. + fseek( $socket, strrpos( $chunk, "\n" ) + 1, SEEK_CUR ); + $chunk = fread( $socket, min( $buffer, $cursor - ftell( $socket ) ) ); + $chunk_len = mb_strlen( $chunk, '8bit' ); + + fseek( $socket, -$chunk_len, SEEK_CUR ); + + if ( ftell( $socket ) + $chunk_len === $cursor ) { + // If chunk ends at the start of the previous, don't add the ellipsis. + $output = $chunk . $output; + } else { + // Concat an ellipsis representation between the last chunk and the previous output. + $output = $chunk . ' (...) ' . $output; + } + + break; + } + } + + if ( ! $line_breaks ) { + // End of file reached without any line break. + $chunk = fread( $socket, min( $buffer, $cursor - ftell( $socket ) ) ); + + if ( ftell( $socket ) + mb_strlen( $chunk, '8bit' ) === $cursor ) { + $output = $chunk . $output; + } else { + $output = $chunk . ' (...) ' . $output; + } + + fseek( $socket, 0, SEEK_SET ); } - } - if ( ! $line_breaks ) { - // End of file reached without any line break. - $chunk = fread( $socket, $buffer ); - fseek( $socket, 0, SEEK_SET ); - } else { // Cursor is at the first line break occurrence. No line breaks added to the output. $line_breaks = 0; } From 971756ca4e3907dac4c2d55c48cedeb231af1b71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Garc=C3=ADa?= Date: Sat, 7 Mar 2026 09:12:12 +0100 Subject: [PATCH 3/4] feat: code optimitzation --- forms-bridge/includes/class-logger.php | 59 +++++++++++--------------- 1 file changed, 25 insertions(+), 34 deletions(-) diff --git a/forms-bridge/includes/class-logger.php b/forms-bridge/includes/class-logger.php index dc3d6b2c..3aca1e55 100644 --- a/forms-bridge/includes/class-logger.php +++ b/forms-bridge/includes/class-logger.php @@ -98,18 +98,20 @@ private static function logs( $lines = 500 ) { while ( ftell( $socket ) > 0 && $lines >= 0 ) { $seek = min( ftell( $socket ), $buffer ); + // Move pointer backward, then read and return to the initial position. fseek( $socket, -$seek, SEEK_CUR ); + $chunk = fread( $socket, $seek ); + fseek( $socket, -mb_strlen( $chunk, '8bit' ), SEEK_CUR ); - $chunk = fread( $socket, $seek ); + // Prepend chunk to the output as we're reading logs right to left. $output = $chunk . $output; - fseek( $socket, -mb_strlen( $chunk, '8bit' ), SEEK_CUR ); - $cursor = ftell( $socket ); $line_breaks = substr_count( $chunk, "\n" ); + // Ellipsis lines if no line breaks in a buffer to save memory. if ( ! $line_breaks ) { - while ( ftell( $socket ) > 0 ) { + while ( ! $line_breaks && ftell( $socket ) > 0 ) { $seek = min( ftell( $socket ), $buffer ); fseek( $socket, -$seek, SEEK_CUR ); @@ -117,47 +119,36 @@ private static function logs( $lines = 500 ) { fseek( $socket, -mb_strlen( $chunk, '8bit' ), SEEK_CUR ); $line_breaks = substr_count( $chunk, "\n" ); - - if ( $line_breaks ) { - // Then, read forward and concat to the output with an ellipsis. - fseek( $socket, strrpos( $chunk, "\n" ) + 1, SEEK_CUR ); - $chunk = fread( $socket, min( $buffer, $cursor - ftell( $socket ) ) ); - $chunk_len = mb_strlen( $chunk, '8bit' ); - - fseek( $socket, -$chunk_len, SEEK_CUR ); - - if ( ftell( $socket ) + $chunk_len === $cursor ) { - // If chunk ends at the start of the previous, don't add the ellipsis. - $output = $chunk . $output; - } else { - // Concat an ellipsis representation between the last chunk and the previous output. - $output = $chunk . ' (...) ' . $output; - } - - break; - } } - if ( ! $line_breaks ) { - // End of file reached without any line break. - $chunk = fread( $socket, min( $buffer, $cursor - ftell( $socket ) ) ); - - if ( ftell( $socket ) + mb_strlen( $chunk, '8bit' ) === $cursor ) { - $output = $chunk . $output; - } else { - $output = $chunk . ' (...) ' . $output; - } + // Move the cursor to the first line break match. + if ( $line_breaks ) { + $offset = strrpos( $chunk, "\n" ) + 1; + fseek( $socket, $offset, SEEK_CUR ); + } - fseek( $socket, 0, SEEK_SET ); + $new_cursor = ftell( $socket ); + $seek = min( $buffer, $cursor - $new_cursor ); + $chunk = fread( $socket, $seek ); + fseek( $socket, -mb_strlen( $chunk, '8bit' ), SEEK_CUR ); + + // If chunk ends at cursor, there is no gap between the current output + // and the last chunk. Skip ellipsis. + if ( $new_cursor + $seek === $cursor ) { + $output = $chunk . $output; + } else { + $output = $chunk . ' (...) ' . $output; } - // Cursor is at the first line break occurrence. No line breaks added to the output. + // Cursor is at the fist line break, or at the beginning of the file. + // In any cases, we didn't substract any line to the line counter. $line_breaks = 0; } $lines -= $line_breaks; } + // In case the loop reads more lines than required, shift lines from the output. while ( $lines++ < 0 ) { $output = substr( $output, strpos( $output, "\n" ) + 1 ); } From 013a4d25dd8e66eaea9426175c1d42f3dbe42ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Garc=C3=ADa?= Date: Sun, 8 Mar 2026 23:11:26 +0100 Subject: [PATCH 4/4] feat: right line ellipsis --- forms-bridge/includes/class-logger.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/forms-bridge/includes/class-logger.php b/forms-bridge/includes/class-logger.php index 3aca1e55..50d87f93 100644 --- a/forms-bridge/includes/class-logger.php +++ b/forms-bridge/includes/class-logger.php @@ -109,8 +109,17 @@ private static function logs( $lines = 500 ) { $cursor = ftell( $socket ); $line_breaks = substr_count( $chunk, "\n" ); - // Ellipsis lines if no line breaks in a buffer to save memory. - if ( ! $line_breaks ) { + // Ellipsis lines if no line breaks in a buffer span to save memory. + if ( ! $line_breaks && ftell( $socket ) > 0 ) { + // First, move the cursor to the last line break and remove the offset from the output. + $offset = strpos( $output, "\n" ); + if ( false !== $offset ) { + $output = substr( $output, $offset ); + fseek( $socket, $offset, SEEK_CUR ); + $cursor = ftell( $socket ); + } + + // Then loops until some line break is found, or the end of the file is reached. while ( ! $line_breaks && ftell( $socket ) > 0 ) { $seek = min( ftell( $socket ), $buffer ); @@ -127,6 +136,7 @@ private static function logs( $lines = 500 ) { fseek( $socket, $offset, SEEK_CUR ); } + // Read a new chunk starting at the new cursor. $new_cursor = ftell( $socket ); $seek = min( $buffer, $cursor - $new_cursor ); $chunk = fread( $socket, $seek ); @@ -137,7 +147,7 @@ private static function logs( $lines = 500 ) { if ( $new_cursor + $seek === $cursor ) { $output = $chunk . $output; } else { - $output = $chunk . ' (...) ' . $output; + $output = $chunk . '... ' . $output; } // Cursor is at the fist line break, or at the beginning of the file.