PHP Classes

File: engine/class.www-logger.php

Recommend this page to a friend!
  Classes of Kristo Vaher   Wave Framework   engine/class.www-logger.php   Download  
File: engine/class.www-logger.php
Role: Class source
Content type: text/plain
Description: Logger Class
Class: Wave Framework
MVC framework for building Web sites and APIs
Author: By
Last change: Fixed tiny errors as a result of PHP version updates
Date: 14 days ago
Size: 8,139 bytes
 

Contents

Class file image Download
<?php

/**
 * Wave Framework <http://github.com/kristovaher/Wave-Framework>
 * Logger Class
 *
 * This is an optional class that is used to log requests on system by Index Gateway. WWW_Logger
 * is used to keep track of performance of requests made to Index Gateway files, it keeps track
 * of how long the request took, what data it included, how high was the memory use, server load,
 * CPU usage and so on. If this logger is used, then every single request is logged as serialized
 * arrays in filesystem in /filesystem/log/ subfolders. It is a good idea to clean that folder
 * every now and then. There is a separate log-reader.php script for reading those log files
 * situated in /tools/ subfolder.
 *
 * @package Logger
 * @author Kristo Vaher <kristo@waher.net>
 * @copyright Copyright (c) 2012, Kristo Vaher
 * @license GNU Lesser General Public License Version 3
 * @tutorial /doc/pages/logger.htm
 * @since 1.0.0
 * @version 3.6.4
 */

class WWW_Logger {

   
/**
     * This stores microtime of the request at the moment Logger object was created. This
     * microtime is used by Logger to calculate execution time of the script. If this value
     * is not defined at the moment Logger object is created, then it is defined automatically.
     */
   
private $requestMicrotime=false;
   
   
/**
     * This is the main address of the folder where log files will be stored. This folder
     * should be writable by PHP. Logger creates subfolders under this folder and stores log
     * files in those subfolders.
     */
   
private $logDir='./';
   
   
/**
     * This array variable stores custom data sent to logger. Keys of this array will be stored
     * as keys in the log entry.
     */
   
public $logData=array('response-code'=>200);
   
   
/**
     * Construction method of Logger requires just one variable: $logDir, which is the folder
     * where log files will be stored. Second variable, $microTime, is used to calculate the
     * execution time of the script. This microtime should be the microtime from the very start
     * of the script, if it is not defined then Logger defines it by itself.
     *
     * @param string $logDir location of directory to store log files at
     * @param boolean|float $microTime starting microtime
     * @return WWW_Logger
     */
   
public function __construct($logDir='./',$microTime=false){
   
       
// Defining IP
       
if(!defined('__IP__')){
           
define('__IP__',$_SERVER['REMOTE_ADDR']);
        }
   
       
// We record the start time of the request
       
if(!$microTime){
           
$this->requestMicrotime=microtime(true);
        } else {
           
$this->requestMicrotime=$microTime;
        }
       
       
// Checking if log directory is valid
       
if(is_dir($logDir)){
           
// Log directory is assigned
           
$this->logDir=$logDir;
        } else {
           
// Assigned folder is not detected as being a folder
           
trigger_error('Assigned log folder does not exist or is not writable',E_USER_ERROR);
        }
       
    }
   
   
/**
     * This method is used to add data to objects $logData array. Key will be the same key defined
     * in the log entry array and value will be the value of this key. It is also possible to send
     * multiple keys and values in the same method, if $key is an array of keys and values, instead
     * of a string.
     *
     * @param string|array $key single key or array of log keys and values
     * @param boolean|string $value this is the value written to the log
     * @return boolean
     */
   
public function setCustomLogData($key,$value=true){
   
       
// Log data can be sent as an array
       
if(is_array($key)){
           
$this->logData=$key+$this->logData;
        } else {
           
$this->logData[$key]=$value;
        }
        return
true;
       
    }
   
   
/**
     * This is the main method of Logger. This method attempts to gather a lot of data about the
     * HTTP request and calculate things such as execution time, memory usage and more. It also
     * creates a logger entry array and combines it with custom log array of $logData. It also
     * creates subfolder in the log folder directory, if it doesn't exist, and writes serialized
     * log entry array in that folder.
     *
     * @return boolean
     */
   
public function writeLog(){
   
       
// All log data is gathered to this variable
       
$logData=array();
       
       
// STATIC LOG DATA
       
            // Unique request identifier set by the server (this is not supported on Windows and Nginx servers)
           
if(isset($_SERVER['UNIQUE_ID'])){ $logData['request-id']=$_SERVER['UNIQUE_ID']; }
           
// This stores the URI that user agent requested.
           
$logData['request']=$_SERVER['REQUEST_URI'];
           
// Timestamp of the request in milliseconds.
           
$logData['microtime']=$this->requestMicrotime;
           
// UNIX timestamp of the request time.
           
$logData['time']=$_SERVER['REQUEST_TIME'];
           
// Stores request datetime in format 'Y-m-d H:i:s'.
           
$logData['datetime']=date('Y-m-d H:i:s').' GMT '.date('P');
           
// Stores IP of the user agent that made the request.
           
$logData['ip']=__IP__;
           
// Additional IP's
           
if(isset($_SERVER['HTTP_CLIENT_IP'])){
               
$logData['forwarded-client-ip']=$_SERVER['HTTP_CLIENT_IP'];
            }
            if(isset(
$_SERVER['HTTP_X_FORWARDED_FOR'])){
               
$logData['forwarded-client-ip']=$_SERVER['HTTP_X_FORWARDED_FOR'];
            }
            if(
__IP__!=$_SERVER['REMOTE_ADDR']){
               
$logData['remote-addr']=$_SERVER['REMOTE_ADDR'];
            }
           
// This stores user agent string of the user agent.
           
$logData['user-agent']=(isset($_SERVER['HTTP_USER_AGENT']))?$_SERVER['HTTP_USER_AGENT']:'Unknown';
           
// This stores user agent string of the user agent.
           
if(isset($_SERVER['HTTP_REFERER'])){
               
$logData['referrer']=$_SERVER['HTTP_REFERER'];
            }
           
// GET variables submitted by user agent.
           
if(!empty($_GET)){
               
$logData['get']=$_GET;
            }
           
// POST variables submitted by user agent
           
if(!empty($_POST)){
               
$logData['post']=$_POST;
            }
           
// Checking for HTTP input
           
$httpInput=file_get_contents('php://input');
            if(
$httpInput!=''){
               
$logData['http-input']=$httpInput;
            }
           
// FILES variables submitted by user agent
           
if(!empty($_FILES)){
               
$logData['files']=$_FILES;
            }
           
// COOKIE variables submitted by user agent
           
if(!empty($_COOKIE)){
               
$logData['cookie']=$_COOKIE;
            }
           
// This stores how long the request took in seconds.
           
$logData['execution-time']=number_format((microtime(true)-$this->requestMicrotime),6);
           
// This stores the peak usage of memory during the request.
           
$logData['memory-peak-usage']=memory_get_peak_usage(); // In bytes, divide by 1048576 to get megabytes

            // CPU load - This is not available on Windows
           
if(function_exists('getrusage')){
               
$load=getrusage();
               
$logData['cpu-user-usage']=number_format($load['ru_utime.tv_sec']+$load['ru_utime.tv_usec']/1000000,6);
               
// Disregarding potentially incorrectly reported numbers
               
if($logData['cpu-user-usage']>$logData['execution-time']){
                    unset(
$logData['cpu-user-usage']);
                }
               
$logData['cpu-system-usage']=number_format($load['ru_stime.tv_sec']+$load['ru_stime.tv_usec']/1000000,6);
               
// Disregarding potentially incorrectly reported numbers
               
if($logData['cpu-system-usage']>$logData['execution-time']){
                    unset(
$logData['cpu-system-usage']);
                }
            }
           
           
// This stores system load number (that is one minute old).
            // This is not supported on Windows
           
if(function_exists('sys_getloadavg')){
               
$load=sys_getloadavg(); //last 1, 5 and 15 minutes (number of processes in run queue)
               
$logData['system-load']=$load[0];
            }
       
       
// WRITING LOG
       
            // Log filename is current time-based with present hour in the end
           
$logFileName=date('Y-m-d-H');
           
// Finding the subfolder of the log file, if subfolder does not exist then it is created
           
$logSubfolder=substr($logFileName,0,10);
            if(!
is_dir($this->logDir.$logSubfolder.DIRECTORY_SEPARATOR)){
                if(!
mkdir($this->logDir.$logSubfolder.DIRECTORY_SEPARATOR,0755)){
                   
trigger_error('Cannot create log folder',E_USER_ERROR);
                }
            }
           
// Appending the log data at the end of log file or creating it if it does not exist
           
if(!file_put_contents($this->logDir.$logSubfolder.DIRECTORY_SEPARATOR.$logFileName.'.tmp',json_encode($logData)."\n",FILE_APPEND)){
               
trigger_error('Cannot write log file',E_USER_ERROR);
            }
       
       
// Logging process is finished
       
return true;
       
    }
}
   
?>