Home  >  Article  >  Backend Development  >  PHP rolling log

PHP rolling log

WBOY
WBOYOriginal
2016-08-08 09:24:231352browse

PHP rolling log library

PHP log recording. I have been exposed to the logging method of dividing folders according to year and month, and then dividing files according to day. This method has advantages and disadvantages and has its usage scenarios. What I want to talk about today is another one. Logging method - file rolling method records logs. Of course, this rolling mechanism can also be added to the previous logging method.

How to make the log scroll

Rolling log, as the name suggests, records the log of a module using a series of log files. The number of files in the same module is limited, up to maxNum, and the size is also limited, up to maxSize bytes. The file name has a certain naming method, such as: testlog .log, testlog_1.log, testlog_2.log,,,,,, where testlog.log is the log file in use. When the size of the testlog.log file reaches the limit maxSize, the log file will be rolled backwards, as shown below :

<code>testlog_2.log 	-> testlog_3.log
testlog_1.log 	-> testlog_2.log
testlog.log 	-> testlog_1.log
testlog.log #0kb</code>

When the number of log files reaches the limit maxNum, the elimination mechanism will be started and the oldest log will be deleted. For example, if maxNum is set to 10, there will be a maximum of 10 files including testlog.log at this time. If it exists when scrolling testlog_9.log will start rolling from testlog_8.log and overwrite testlog_9.log. This will ensure normal log recording and no very large log files will appear, ensuring the normal operation of the log system.

Code implementation

<code><?php
final class LOGS {
	private $level;
	private $maxFileNum;
	private $maxFileSize;
	private $logPath;
	private $file;

	//日志的级别DEBUG,MSG,ERR
	const LOGS_DEBUG = 0;
	const LOGS_MSG = 1;
	const LOGS_ERR = 2;

	private static $instance = null;

	private function __construct(){}

	public static function getInstance()
	{
		if(self::$instance == null)
		{
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * @Desc 初始化
	 * @Param $level int 记录级别
	 * @Param $maxNum int 最大日志文件数目
	 * @Param $maxSize int 最大日志文件大小
	 * @Param $logPath string 日志文件保存路径
	 * @Param $file string 日志文件名称前缀
	 * @Return boolean
	 */
	public function init($level, $maxNum, $maxSize, $logPath, $file)
	{
		$level = intval($level);
		$maxNum = intval($maxNum);
		$maxSize = intval($maxSize);
		!is_dir($logPath) && mkdir($logPath, 0777, true);
		if(!in_array($level, array(self::LOGS_DEBUG, self::LOGS_MSG, self::LOGS_ERR)) || $maxNum <= 0 || $maxSize <= 0 || !is_dir($logPath))
		{
			return false;
		}
		$this->level = $level;
		$this->maxFileNum = $maxNum;
		$this->maxFileSize = $maxSize;
		$this->logPath = $logPath;
		$this->file = $file;
		return true;
	}

	/**
	 * @Desc 获取格式化时间串
	 */
	public function formatTime()
	{
        $ustime = explode ( " ", microtime () );
        return "[" . date('Y-m-d H:i:s', time()) .".". ($ustime[0] * 1000) . "]";
	}

	/**	
	 * @Desc 滚动方式记录日志文件
	 */
	public function log($str)
	{
		$path = $this->logPath.DIRECTORY_SEPARATOR.$this->file.".log";
		clearstatcache();
		if(file_exists($path))
		{
			if(filesize($path) >= $this->maxFileSize)
			{
				$index = 1;
				//获取最大的滚动日志数目
				for(;$index < $this->maxFileNum; $index++)
				{
					if(!file_exists($this->logPath.DIRECTORY_SEPARATOR.$this->file."_".$index.".log"))
					{
						break;
					}
				}
				//已经存在maxFileNum个日志文件了
				if($index == $this->maxFileNum)
				{
					$index--;
				}
				//滚动日志
				for(;$index > 1; $index--)
				{
					$new = $this->logPath.DIRECTORY_SEPARATOR.$this->file."_".$index.".log";
					$old = $this->logPath.DIRECTORY_SEPARATOR.$this->file."_".($index - 1).".log";
					rename($old, $new);
				}

				$newFile = $this->logPath.DIRECTORY_SEPARATOR.$this->file."_1.log";
				rename($path, $newFile);
			}
		}
		$fp = fopen($path, "a+b");
		fwrite($fp, $str, strlen($str));
		fclose($fp);
		return true;
	}

	/**
	 * @Desc 记录调试信息
	 * @Param string 日志信息
	 * @Param string 日志所在文件
	 * @Param string 日志所在行
	 */
	public function debug($msg, $file, $line)
	{
		if($this->level <= self::LOGS_DEBUG)
		{
			$this->log($this->formatTime()."[{$file}:{$line}]DEBUG: ${msg}\n");
		}
	}

	/**
	 * @Desc 记录信息
	 * @Param string 日志信息
	 * @Param string 日志所在文件
	 * @Param string 日志所在行
	 */
	public function msg($msg, $file, $line)
	{
		if($this->level <= self::LOGS_MSG)
		{
			$this->log($this->formatTime()."[{$file}:{$line}]MSG: ${msg}\n");
		}
	}

	/**
	 * @Desc 记录错误信息
	 * @Param string 日志信息
	 * @Param string 日志所在文件
	 * @Param string 日志所在行
	 */
	public function err($msg, $file, $line)
	{
		if($this->level <= self::LOGS_ERR)
		{
			$this->log($this->formatTime()."[{$file}:{$line}]ERR: ${msg}\n");
		}
	}
}</code>

Look at an example

<code>#例子中设置记录级别为msg(此时debug信息是不会纪录的),日志文件个数为5,大小为200个字节(测试方便),文件名称为testlog
$logs = LOGS::getInstance();
$logs->init(1, 5, 200, "./", 'testlog');

$logs->msg("YRT", __FILE__, __LINE__);
$logs->debug("YRT", __FILE__, __LINE__);</code>

When we run this example continuously, 5 files will be generated in the folder where the code is located, like the following:

<code>testlog_4.log
testlog_3.log
testlog_2.log
testlog_1.log
testlog.log			#最新的日志在这个文件中</code>

The above introduces the PHP rolling log, including aspects of the content. I hope it will be helpful to friends who are interested in PHP tutorials.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn