Wednesday 29 September 2021

Logging in PHP

How Logging works in Apache & PHP

Apache and php maintain the logs in the error.log file which is the default file for logging. 

File path to error.log is /var/log/apache2/error.log

PHP allows us to log into a different file using 

ini_set(‘error_log’, ‘path/to/log/file.log’)


Following are different methods for logging available


Here's a PHP function to create period wise logs


    <?php


    class ErrorLog {

       private $logFilePath;


       /**

        * ErrorLog constructor.

        *

        * @param string $logFilePath

        */

       public function __construct(string $logFilePath) {

           $this->logFilePath = $logFilePath;

       }


       /**

        * Parses the PHP error log to an array.

        *

        * @return \Generator

        */

       public function getParsedLogFile($sLogType = null, $dStartDate = null, $dEndDate = null): \Generator {

           $parsedLogs = [];

           $logFileHandle = fopen($this->logFilePath, 'rb');


           while (!feof($logFileHandle)) {

               $currentLine = str_replace(PHP_EOL, '', fgets($logFileHandle));


               // Normal error log line starts with the date & time in []

               if ('[' === $currentLine[0]) {

                   if (10000 === \count($parsedLogs)) {

                       yield $parsedLogs;

                       $parsedLogs = [];

                   }


                   // Get the datetime when the error occurred and convert it to berlin timezone

                   try {

                       $dateArr = [];

                       preg_match('~^\[(.*?)\]~', $currentLine, $dateArr);

                       $currentLine = str_replace($dateArr[0], '', $currentLine);

                       $currentLine = trim($currentLine);

                       $dErrorDateTime = new DateTime($dateArr[1]);

                       $dErrorDateTime->setTimezone(new DateTimeZone('Asia/Kolkata'));

                       $errorDateTime = $dErrorDateTime->format('Y-m-d H:i:s');

                   } catch (\Exception $e) {

                       $errorDateTime = '';

                   }


                   // Get the type of the error

                   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';

                   } else {

                       $errorType = 'UNKNOWN';

                   }


                   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);


                   // The message of the error

                   $errorMessage = trim($currentLine);


                   if ($sLogType != null && $sLogType != $errorType) {

                       continue;

                   }

                   echo "<pre>";

                   if ($dStartDate != null && $dStartDate > $dErrorDateTime) {

                       continue;

                   }

                   if ($dEndDate != null && $dEndDate < $dErrorDateTime) {

                       continue;

                   }


                   $parsedLogs[] = [

                       'dateTime'   => $errorDateTime,

                       'type'       => $errorType,

                       'file'       => $errorFile,

                       'line'       => (int)$errorLine,

                       'message'    => $errorMessage,

                       'stackTrace' => []

                   ];

               } // Stack trace beginning line

               else if ('Stack trace:' === $currentLine) {

                   $stackTraceLineNumber = 0;


                   while (!feof($logFileHandle)) {

                       $currentLine = str_replace(PHP_EOL, '', fgets($logFileHandle));


                       // If the current line is a stack trace line

                       if ('#' === $currentLine[0]) {

                           $parsedLogsLastKey = key($parsedLogs);

                           $currentLine = str_replace('#' . $stackTraceLineNumber, '', $currentLine);

                           $parsedLogs[$parsedLogsLastKey]['stackTrace'][] = trim($currentLine);


                           $stackTraceLineNumber++;

                       } // If the current line is the last stack trace ('thrown in...')

                       else {

                           break;

                       }

                   }

               }

           }


           yield $parsedLogs;

       }

    }


    $oErrorLog = new ErrorLog(ini_get('error_log'));


    foreach ($oErrorLog->getParsedLogFile('SYNTAX',new DateTime('2021-04-25 12:15:30'), new DateTime('2021-04-25 16:00:05')

    ) as $key => $value) {

       var_dump($value);

    }



    Ref: From Internal memo provided by Kaveri Bhumkar



Check the amount of free disk space in Ubuntu

df -h --total