Skip to content

easy-framework/easy-log

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EASY LOG

Write log easily

How to use?

 composer require easy-framework/easy-log

Code

<?php
/****************************************************
 *                    Easy Log                      *
 *                                                  *
 *                    TIERGB                        *
 *           <https://github.com/TIGERB>            *
 *                                                  *
 ****************************************************/

namespace Easy;

use Exception;

/**
 * log class
 * 
 * 特点相比其他日志类一起请求只会最终打印一次日志从而降低到一次磁盘I/O
 * 
 * 使用说明
 * Log::debug(...) -> debug日志
 * Log::notice(...) -> 提醒日志
 * Log::warning(...) -> 警告日志
 * Log::error(...)  -> 错误日志 
 */
class Log
{
	/**
	 * log buffer
	 *
	 * @var array
	 */
    private $buffer = [
        "\n"
        // "\n---date---|---level---|---pid---|---memeory---|---log---\n"
    ];
    

    /**
	 * log method support
	 *
	 * @var array
	 */
    private $methodSupport = [
        'debug',
        'notice',
        'warning',
        'error'
    ];
    
    /**
	 * class private variable change allow list
	 *
	 * @var array
	 */
	private $variablesAllow = [
        'logPath',
        'logFileSize',
        'logFileName'
    ];

	/**
	 * the log file name
	 *
	 * @var string
	 */
    private $logFileName = '';

    /**
	 * the final log name include the path
	 *
	 * @var string
	 */
    private $finalFileName = '';

    /**
	 * the log path
	 *
	 * @var string
	 */
    private $logPath = '/tmp/easy';

    /**
	 * the log file size
	 *
	 * @var int unit/M
	 */
    private $logFileSize = 512;

    /**
	 * log
	 *
	 * @var string
	 */
    private $log = '';

    /**
     * instance
     * 
     * @var object
     */
    private static $_instance;
  
    /**
     * construct function
     * 
     * @return void
     */
    private function __construct()
    {
        register_shutdown_function([$this, 'write']);
    }

    /**
     * set log path function
     * 
     * @return void
     */
    public function __set($name = '', $value = '')
    {
        if (! in_array($name, $this->variablesAllow)) {
            throw new Exception('Operate is forbidden for this variable ' . $name, 401);    
        }
        $this->$name = $value;
    }
    
    /**
     * the magic function
     * clone is forbidden
     * 
     * @return string
     */
    public function __clone()
    {
        throw new Exception('Clone is forbidden', 401);
    }
  
    /**
     * get instance
     * 
     * @return object
     */
    public static function getInstance()
    {
      if (!self::$_instance instanceof self) {
        self::$_instance = new self;
      }
      return self::$_instance;
    }
	
	/**
	 * the magic __callStatics function
	 *
	 * @param string $method
	 * @param array $log
	 * @return void
	 */
	public static function __callstatic($method = '', $log = [])
	{
        $instance = self::getInstance();
		if (! in_array($method, $instance->methodSupport)) {
			throw new Exception('log method not support', 500);
		}
        $instance->decorate($method, $log);
		$instance->pushLog();
	}

	/**
	 * decorate log msg
	 *
	 * @param string $rank
	 * @param array $log
	 * @return void
	 */
	private function decorate($rank = 'info', $log = [])
	{
        if (! $log) {
            $log = [];
        }
		$time        = date('Y-m-d H: i: s', time());
		$pid         = posix_getpid();
		$memoryUsage = round(memory_get_usage()/1024, 2) . ' kb';
		switch ($rank) {
            case 'debug':
                $rank = "\033[32m{$rank}\033[0m";
            break;
			case 'notice':
				$rank = "\033[36m{$rank} \033[0m";
			break;
			case 'warning':
				$rank = "\033[33m{$rank}\033[0m";
            break;
            case 'error':
                $rank = "\033[31m{$rank}\033[0m";
            break;
			
			default:
			
			break;
        }
        
		$default = [
			$time,
			$rank,
			$pid,
			$memoryUsage
        ];
        
        if ($log) {
            foreach ($log as &$v) {
                if (is_array($v)) {
                    if (defined('JSON_UNESCAPED_UNICODE')) {
                        $v = json_encode($v, JSON_UNESCAPED_UNICODE);
                    } else {
                        $v = json_encode($v);
                    }
                }
            }
            unset($v);
        }

		$log  = array_merge($default, $log);
        $tmp  = '';
		foreach ($log as $k => $v) {
			if ($k === 0) {
				$tmp = "{$v}";
				continue;
			}
			$tmp .= " | {$v}";
        }
        $this->log = $tmp;
    }

    /**
     * the finally write
     */
    public function write()
    {
        if (! $this->buffer) {
            return;
        }
        $msg = '';
        foreach ($this->buffer as $v) {
            $msg .= $v . PHP_EOL; 
        }

        // check file path
        if (! file_exists($this->logPath)) {
            mkdir($this->logPath, 0777, true);
        }
        $this->finalFileName = $this->logPath . "{$this->logFileName}." . date('Y-m-d', time()) . '.log';

        // check file size
        if (file_exists($this->finalFileName)) {
            $filesize = filesize(realpath($this->finalFileName));
            if ($filesize >= $this->logFileSize*1024*1024) {
                $this->finalFileName = $this->logPath . "{$this->logFileName}." . date('Y-m-d', time());
                $this->finalFileName .= '.' . date('H-i-s', time()) . '.log';
            }
        }
            
        // write
        error_log(
            $msg, 
            3, 
            $this->finalFileName
        );
    }

    /**
     * push the log msg to the buffer
     */
    public function pushLog()
    {
        $this->buffer[] = $this->log;
    }
}