drew.d.lenhart

programming, software, technology, anything on my mind...

Simple PHP Text Logging Class

2016/06/03

I recently helped a friend troubleshoot issues with an old PHP application and needed the ability to log messages/errors to log files. More specifically around AJAX requests to PHP files and other various issues. I could have spent two minutes searching Google to find a library already made, but I thought it would be fun to create my own!

I made use of PHP's Filesystem Functions such as fwrite, fopen, and is_writable. At the time I didn't spend much time on it, but since then I've made it a bit more usable. Here's the flow of the class:

  • Constructor
  • Open or create file if it doesnt exist
  • Methods for info, warning, error, debug
  • Write to file
  • Destructor (close file)

Code


<?php
/**
* st-PHP-Logger - Simple PHP logging class. Log info, warning, error messages to log files.
*/
namespace snowytech\stphplogger;
/**
* @author  Drew D. Lenhart - snowytech
* @since   May 29, 2016
* @link    https://github.com/dlenhart/st-php-logger
* @version 1.0.0
*/
class logWriter {
    /**
    * $log_file - path and log file name
    * @var string
    */
    protected $log_file;
    /**
    * $file - file
    * @var string
    */
    protected $file;
    /**
    * $options - settable options - future use - passed through constructor
    * @var array
    */
    protected $options = array(
        'dateFormat' => 'd-M-Y H:i:s'
    );
    /**
    * Class constructor
    * @param string $log_file - path and filename of log
    * @param array $params
    */
    public function __construct($log_file = 'error.txt', $params = array()){
        $this->log_file = $log_file;
        $this->params = array_merge($this->options, $params);
        //Create log file if it doesn't exist.
        if(!file_exists($log_file)){               
            fopen($log_file, 'w') or exit("Can't create $log_file!");
        }
        //Check permissions of file.
        if(!is_writable($log_file)){   
            //throw exception if not writable
            throw new Exception("ERROR: Unable to write to file!", 1);
        }
    }
    /**
    * Info method (write info message)
    * @param string $message
    * @return void
    */
    public function info($message){
        $this->writeLog($message, 'INFO');
    }
    /**
    * Debug method (write debug message)
    * @param string $message
    * @return void
    */
    public function debug($message){
        $this->writeLog($message, 'DEBUG');
    }
    /**
    * Warning method (write warning message)
    * @param string $message
    * @return void
    */
    public function warning($message){
        $this->writeLog($message, 'WARNING');
    }
    /**
    * Error method (write error message)
    * @param string $message
    * @return void
    */
    public function error($message){
        $this->writeLog($message, 'ERROR');
    }
    /**
    * Write to log file
    * @param string $message
    * @param string $severity
    * @return void
    */
    public function writeLog($message, $severity) {
        // open log file
        if (!is_resource($this->file)) {
            $this->openLog();
        }
        // grab the url path ( for troubleshooting )
        $path = $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
        //Grab time - based on timezone in php.ini
        $time = date($this->params['dateFormat']);
        // Write time, url, & message to end of file
        fwrite($this->file, "[$time] [$path] : [$severity] - $message" . PHP_EOL);
    }
    /**
    * Open log file
    * @return void
    */
    private function openLog(){
        $openFile = $this->log_file;
        // 'a' option = place pointer at end of file
        $this->file = fopen($openFile, 'a') or exit("Can't open $openFile!");
    }
    /**
     * Class destructor
     */
    public function __destruct(){
        if ($this->file) {
            fclose($this->file);
        }
    }
}

It's actually quite simple to use. Simply call either the info, debug, warning, error methods with your message as the parameter!

Here's an example. Initiate the new object $log and define log path and file name as parameter. In this case I'm using a time stamp in the log file name ( e.g. log-02-Jun-2016.txt ):


<?php

require 'st-php-logger.php';

$time = date('d-M-Y');

$log = new snowytech\stphplogger\logWriter('logs/log-' . $time . '.txt');

$log->warning('this is the warning message');

$log->info('this is the info message');


Output:


[03-Jun-2016 14:19:15] [localhost/st-php-logger/example.php] : [WARNING] - this is the warning message
[03-Jun-2016 14:19:15] [localhost/st-php-logger/example.php] : [INFO] - this is the info message

TODO

If I were to work on this longer, I would add another parameter option to log data from a SQL query as JSON. I'd also add an option to display arrays in the logs.

Thanks for reading! --Drew

View code on Github!