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
Post a Comment