@@ -98,66 +98,57 @@ private static function logs( $lines = 500 ) {
9898 while ( ftell ( $ socket ) > 0 && $ lines >= 0 ) {
9999 $ seek = min ( ftell ( $ socket ), $ buffer );
100100
101+ // Move pointer backward, then read and return to the initial position.
101102 fseek ( $ socket , -$ seek , SEEK_CUR );
103+ $ chunk = fread ( $ socket , $ seek );
104+ fseek ( $ socket , -mb_strlen ( $ chunk , '8bit ' ), SEEK_CUR );
102105
103- $ chunk = fread ( $ socket , $ seek );
106+ // Prepend chunk to the output as we're reading logs right to left.
104107 $ output = $ chunk . $ output ;
105108
106- fseek ( $ socket , -mb_strlen ( $ chunk , '8bit ' ), SEEK_CUR );
107-
108109 $ cursor = ftell ( $ socket );
109110 $ line_breaks = substr_count ( $ chunk , "\n" );
110111
112+ // Ellipsis lines if no line breaks in a buffer to save memory.
111113 if ( ! $ line_breaks ) {
112- while ( ftell ( $ socket ) > 0 ) {
114+ while ( ! $ line_breaks && ftell ( $ socket ) > 0 ) {
113115 $ seek = min ( ftell ( $ socket ), $ buffer );
114116
115117 fseek ( $ socket , -$ seek , SEEK_CUR );
116118 $ chunk = fread ( $ socket , $ seek );
117119 fseek ( $ socket , -mb_strlen ( $ chunk , '8bit ' ), SEEK_CUR );
118120
119121 $ line_breaks = substr_count ( $ chunk , "\n" );
120-
121- if ( $ line_breaks ) {
122- // Then, read forward and concat to the output with an ellipsis.
123- fseek ( $ socket , strrpos ( $ chunk , "\n" ) + 1 , SEEK_CUR );
124- $ chunk = fread ( $ socket , min ( $ buffer , $ cursor - ftell ( $ socket ) ) );
125- $ chunk_len = mb_strlen ( $ chunk , '8bit ' );
126-
127- fseek ( $ socket , -$ chunk_len , SEEK_CUR );
128-
129- if ( ftell ( $ socket ) + $ chunk_len === $ cursor ) {
130- // If chunk ends at the start of the previous, don't add the ellipsis.
131- $ output = $ chunk . $ output ;
132- } else {
133- // Concat an ellipsis representation between the last chunk and the previous output.
134- $ output = $ chunk . ' (...) ' . $ output ;
135- }
136-
137- break ;
138- }
139122 }
140123
141- if ( ! $ line_breaks ) {
142- // End of file reached without any line break.
143- $ chunk = fread ( $ socket , min ( $ buffer , $ cursor - ftell ( $ socket ) ) );
144-
145- if ( ftell ( $ socket ) + mb_strlen ( $ chunk , '8bit ' ) === $ cursor ) {
146- $ output = $ chunk . $ output ;
147- } else {
148- $ output = $ chunk . ' (...) ' . $ output ;
149- }
124+ // Move the cursor to the first line break match.
125+ if ( $ line_breaks ) {
126+ $ offset = strrpos ( $ chunk , "\n" ) + 1 ;
127+ fseek ( $ socket , $ offset , SEEK_CUR );
128+ }
150129
151- fseek ( $ socket , 0 , SEEK_SET );
130+ $ new_cursor = ftell ( $ socket );
131+ $ seek = min ( $ buffer , $ cursor - $ new_cursor );
132+ $ chunk = fread ( $ socket , $ seek );
133+ fseek ( $ socket , -mb_strlen ( $ chunk , '8bit ' ), SEEK_CUR );
134+
135+ // If chunk ends at cursor, there is no gap between the current output
136+ // and the last chunk. Skip ellipsis.
137+ if ( $ new_cursor + $ seek === $ cursor ) {
138+ $ output = $ chunk . $ output ;
139+ } else {
140+ $ output = $ chunk . ' (...) ' . $ output ;
152141 }
153142
154- // Cursor is at the first line break occurrence. No line breaks added to the output.
143+ // Cursor is at the fist line break, or at the beginning of the file.
144+ // In any cases, we didn't substract any line to the line counter.
155145 $ line_breaks = 0 ;
156146 }
157147
158148 $ lines -= $ line_breaks ;
159149 }
160150
151+ // In case the loop reads more lines than required, shift lines from the output.
161152 while ( $ lines ++ < 0 ) {
162153 $ output = substr ( $ output , strpos ( $ output , "\n" ) + 1 );
163154 }
0 commit comments