php - Reverse log like tail -


i reverse system log.

my system log looks this:

[ 2016-03-17t15:52:00+08:00 ] 0.0.0.0 /pwebshell/index.php/log/getlog info: [ route_check ] --start-- info: checkroute behavior ::run [ runtime:0.001000s ] info: [ route_check ] --end-- [ runtime:0.001000s ] info: [ app_begin ] --start-- info: readhtmlcache behavior ::run [ runtime:0.001000s ] info: [ app_begin ] --end-- [ runtime:0.001000s ]  [ 2016-03-17t15:52:16+08:00 ] 0.0.0.0 /pwebshell/index.php/log/getlog info: [ route_check ] --start-- info: checkroute behavior ::run [ runtime:0.000000s ] info: [ route_check ] --end-- [ runtime:0.001000s ] info: [ app_begin ] --start-- info: readhtmlcache behavior ::run [ runtime:0.000000s ] info: [ app_begin ] --end-- [ runtime:0.000000s ] 

i print this:

[ 2016-03-17t15:52:16+08:00 ] 0.0.0.0 /pwebshell/index.php/log/getlog info: [ route_check ] --start-- info: checkroute behavior ::run [ runtime:0.000000s ] info: [ route_check ] --end-- [ runtime:0.001000s ] info: [ app_begin ] --start-- info: readhtmlcache behavior ::run [ runtime:0.000000s ] info: [ app_begin ] --end-- [ runtime:0.000000s ]  [ 2016-03-17t15:52:00+08:00 ] 0.0.0.0 /pwebshell/index.php/log/getlog info: [ route_check ] --start-- info: checkroute behavior ::run [ runtime:0.001000s ] info: [ route_check ] --end-- [ runtime:0.001000s ] info: [ app_begin ] --start-- info: readhtmlcache behavior ::run [ runtime:0.001000s ] info: [ app_begin ] --end-- [ runtime:0.001000s ] 

what have tried far:

1 first of read log using file_get_contents

$content = file_get_contents('log'); 

2 used regular expression select entries.

preg_match_all('#(\[\s+\d{4}\-\d{2}\-\d{2}.*\].*?)\[\s+\d{4}\-\d{2}\-\d{2}#s', $content, $matches); 

3 use array_reverse reverse log.

but $matches not selected correctly regex.

there 3 separate issues regular expression:

  • you'd need first .* ungreedy otherwise match final ] in file.
  • your regular expression won't match final entry because isn't followed entry.
  • each match "captures" text matched, including following \[\s+\d{4}\-\d{2}\-\d{2} (ie captures start of next entry). means of matches returned. correct this, need convert final part lookahead assertion using (?=...).

something following should fix these 3 problems.

preg_match_all('#(\[\s+\d{4}\-\d{2}\-\d{2}.*?\].*?)(?=\[\s+\d{4}\-\d{2}\-\d{2}|$)#s', $content, $matches); 

however entries appear separated double line feeds. why not split log on these? assuming don't double line feeds naturally in log data, easier read, faster, , less error prone.

the following work on linux:

$lines = explode("\n\n", $content); $lines = array_reverse($lines); echo implode("\n\n", $lines); 

on windows might need replace \n\n \r\n\r\n.

an improved solution work regardless of type of line feeds, allow white space between line feeds, , output using system's default end of line might like:

$lines = preg_split("#\r?\n\s*\n#", $content); $lines = array_reverse($lines); echo implode(php_eol . php_eol, $lines); 

this handle fact log content appears contain more 2 line feeds separating entries.


Comments

Popular posts from this blog

java - Run spring boot application error: Cannot instantiate interface org.springframework.context.ApplicationListener -

python - pip wont install .WHL files -

Excel VBA "Microsoft Windows Common Controls 6.0 (SP6)" Location Changes -