I'm a bit late, but my solution (it also supports stack traces):
<?php
use DateTime;
use DateTimeZone;
class ErrorLog {
private $logFilePath;
public function __construct($logFilePath) {
$this->logFilePath = $logFilePath;
}
public function getParsedLogFile() {
$parsedLogs = [];
$contents = file_get_contents($this->logFilePath);
$lines = explode("\n", $contents);
for ($currentLineNumber = 0; $currentLineNumber < count($lines); $currentLineNumber++) {
$currentLine = trim($lines[$currentLineNumber]);
if ('[' === substr($currentLine, 0, 1)) {
$dateArr = [];
preg_match('~^\[(.*?)\]~', $currentLine, $dateArr);
$currentLine = str_replace($dateArr[0], '', $currentLine);
$currentLine = trim($currentLine);
$dateArr = explode(' ', $dateArr[1]);
$dateTimeUtc = DateTime::createFromFormat('j-M-Y H:i:s', $dateArr[0] . ' ' . $dateArr[1]);
$dateTimeUtc = $dateTimeUtc->format('Y-m-d H:i:s');
$errorDateTime = new DateTime($dateTimeUtc, new DateTimeZone('UTC'));
$errorDateTime->setTimezone(new DateTimeZone('Europe/Berlin'));
$errorDateTime = $errorDateTime->format('Y-m-d H:i:s');
$errorType = '';
if (false !== strpos($currentLine, 'PHP Warning')) {
$currentLine = str_replace('PHP Warning:', '', $currentLine);
$currentLine = trim($currentLine);
$errorType = 'WARNING';
} else if (false !== strpos($currentLine, 'PHP Notice')) {
$currentLine = str_replace('PHP Notice:', '', $currentLine);
$currentLine = trim($currentLine);
$errorType = 'NOTICE';
} else if (false !== strpos($currentLine, 'PHP Fatal error')) {
$currentLine = str_replace('PHP Fatal error:', '', $currentLine);
$currentLine = trim($currentLine);
$errorType = 'FATAL';
} else if (false !== strpos($currentLine, 'PHP Parse error')) {
$currentLine = str_replace('PHP Parse error:', '', $currentLine);
$currentLine = trim($currentLine);
$errorType = 'SYNTAX';
} else if (false !== strpos($currentLine, 'PHP Exception')) {
$currentLine = str_replace('PHP Exception:', '', $currentLine);
$currentLine = trim($currentLine);
$errorType = 'EXCEPTION';
}
if (false !== strpos($currentLine, ' on line ')) {
$errorLine = explode(' on line ', $currentLine);
$errorLine = trim($errorLine[1]);
$currentLine = str_replace(' on line ' . $errorLine, '', $currentLine);
} else {
$errorLine = substr($currentLine, strrpos($currentLine, ':') + 1);
$currentLine = str_replace(':' . $errorLine, '', $currentLine);
}
$errorFile = explode(' in /', $currentLine);
$errorFile = '/' . trim($errorFile[1]);
$currentLine = str_replace(' in ' . $errorFile, '', $currentLine);
$errorMessage = trim($currentLine);
$parsedLogs[] = [
'dateTime' => $errorDateTime,
'type' => $errorType,
'file' => $errorFile,
'line' => (int)$errorLine,
'message' => $errorMessage,
'stackTrace' => []
];
}
else if ('Stack trace:' === $currentLine) {
$stackTraceLineNumber = 0;
for ($currentLineNumber++; $currentLineNumber < count($lines); $currentLineNumber++) {
$currentLine = trim($lines[$currentLineNumber]);
if ('#' === substr($currentLine, 0, 1)) {
$parsedLogsLastKey = end(array_keys($parsedLogs));
$currentLine = str_replace('#' . $stackTraceLineNumber, '', $currentLine);
$parsedLogs[$parsedLogsLastKey]['stackTrace'][] = trim($currentLine);
$stackTraceLineNumber++;
}
else {
break;
}
}
}
}
return $parsedLogs;
}
}