首页 > 开发 > PHP > 正文

PHP滚动日志的代码实现

2024-05-04 23:36:02
字体:大 中 小
来源:转载
供稿:网友

所谓滚动日志,顾名思义,就是记录一个模块的日志用一系列的日志文件,同一模块文件个数有限制,最多maxNum个,大小也有限制,最大maxSize字节,文件名有一定的命名方式,比如:testlog.log、testlog_1.log,testlog_2.log、、、、、、

PHP滚动日志类库

PHP记录日志,我之前接触过的有按照年月分文件夹,然后按照日分文件的日志记录方式,这种方式有利有弊,有他的使用场景,我今天要说的是另一种日志记录方式——文件滚动方式记录日志,当然了,这种滚动机制也可以加在前面那种日志记录方式中。

如何让日志滚动起来

滚动日志,顾名思义,记录一个模块的日志用一系列的日志文件,同一模块文件个数有限制,最多maxNum个,大小也有限制,最大maxSize字节,文件名有一定的命名方式,比如:testlog.log、testlog_1.log,testlog_2.log、、、、、、其中testlog.log是正在使用的日志文件,当testlog.log文件大小到达限制maxSize的时候就会向后滚动日志文件,就像下面这样:

代码如下:

testlog_2.log  -> testlog_3.log
testlog_1.log  -> testlog_2.log
testlog.log  -> testlog_1.log
testlog.log #0kb

当日志文件个数到达限制maxNum的时候就会启动淘汰机制,删除最老的日志,比如说maxNum设置为10,这个时候算上testlog.log一共最多有10个文件,当滚动的时候如果存在testlog_9.log就会从testlog_8.log开始滚动,覆盖掉testlog_9.log,这样就可以保证日志正常记录,而且不会出现很大很大的日志文件,保证日志系统的正常运行。

代码实现

 

 
  1. <?php 
  2. final class LOGS { 
  3. private $level; 
  4. private $maxFileNum; 
  5. private $maxFileSize; 
  6. private $logPath; 
  7. private $file; 
  8.  
  9. //日志的级别DEBUG,MSG,ERR 
  10. const LOGS_DEBUG = 0; 
  11. const LOGS_MSG = 1; 
  12. const LOGS_ERR = 2; 
  13.  
  14. private static $instance = null; 
  15.  
  16. private function __construct(){} 
  17.  
  18. public static function getInstance() 
  19. { 
  20. if(self::$instance == null) 
  21. { 
  22. self::$instance = new self(); 
  23. } 
  24. return self::$instance; 
  25. } 
  26.  
  27. /** 
  28. * @Desc 初始化 
  29. * @Param $level int 记录级别 
  30. * @Param $maxNum int 最大日志文件数目 
  31. * @Param $maxSize int 最大日志文件大小 
  32. * @Param $logPath string 日志文件保存路径 
  33. * @Param $file string 日志文件名称前缀 
  34. * @Return boolean 
  35. */ 
  36. public function init($level, $maxNum, $maxSize, $logPath, $file) 
  37. { 
  38. $level = intval($level); 
  39. $maxNum = intval($maxNum); 
  40. $maxSize = intval($maxSize); 
  41. !is_dir($logPath) && mkdir($logPath, 0777, true); 
  42. if(!in_array($level, array(self::LOGS_DEBUG, self::LOGS_MSG, self::LOGS_ERR)) || $maxNum <= 0 || $maxSize <= 0 || !is_dir($logPath)) 
  43. { 
  44. return false; 
  45. } 
  46. $this->level = $level; 
  47. $this->maxFileNum = $maxNum; 
  48. $this->maxFileSize = $maxSize; 
  49. $this->logPath = $logPath; 
  50. $this->file = $file; 
  51. return true; 
  52. } 
  53.  
  54. /** 
  55. * @Desc 获取格式化时间串 
  56. */ 
  57. public function formatTime() 
  58. { 
  59. $ustime = explode ( " ", microtime () ); 
  60. return "[" . date('Y-m-d H:i:s', time()) .".". ($ustime[0] * 1000) . "]"; 
  61. } 
  62.  
  63. /**  
  64. * @Desc 滚动方式记录日志文件 
  65. */ 
  66. public function log($str) 
  67. { 
  68. $path = $this->logPath.DIRECTORY_SEPARATOR.$this->file.".log"; 
  69. clearstatcache(); 
  70. if(file_exists($path)) 
  71. { 
  72. if(filesize($path) >= $this->maxFileSize) 
  73. { 
  74. $index = 1; 
  75. //获取最大的滚动日志数目 
  76. for(;$index < $this->maxFileNum; $index++) 
  77. { 
  78. if(!file_exists($this->logPath.DIRECTORY_SEPARATOR.$this->file."_".$index.".log")) 
  79. { 
  80. break; 
  81. } 
  82. } 
  83. //已经存在maxFileNum个日志文件了 
  84. if($index == $this->maxFileNum) 
  85. { 
  86. $index--; 
  87. } 
  88. //滚动日志 
  89. for(;$index > 1; $index--) 
  90. { 
  91. $new = $this->logPath.DIRECTORY_SEPARATOR.$this->file."_".$index.".log"; 
  92. $old = $this->logPath.DIRECTORY_SEPARATOR.$this->file."_".($index - 1).".log"; 
  93. rename($old, $new); 
  94. } 
  95.  
  96. $newFile = $this->logPath.DIRECTORY_SEPARATOR.$this->file."_1.log"; 
  97. rename($path, $newFile); 
  98. } 
  99. } 
  100. $fp = fopen($path, "a+b"); 
  101. fwrite($fp, $str, strlen($str)); 
  102. fclose($fp); 
  103. return true; 
  104. } 
  105.  
  106. /** 
  107. * @Desc 记录调试信息 
  108. * @Param string 日志信息 
  109. * @Param string 日志所在文件 
  110. * @Param string 日志所在行 
  111. */ 
  112. public function debug($msg, $file, $line) 
  113. { 
  114. if($this->level <= self::LOGS_DEBUG) 
  115. { 
  116. $this->log($this->formatTime()."[{$file}:{$line}]DEBUG: ${msg}/n"); 
  117. } 
  118. } 
  119.  
  120. /** 
  121. * @Desc 记录信息 
  122. * @Param string 日志信息 
  123. * @Param string 日志所在文件 
  124. * @Param string 日志所在行 
  125. */ 
  126. public function msg($msg, $file, $line) 
  127. { 
  128. if($this->level <= self::LOGS_MSG) 
  129. { 
  130. $this->log($this->formatTime()."[{$file}:{$line}]MSG: ${msg}/n"); 
  131. } 
  132. } 
  133.  
  134. /** 
  135. * @Desc 记录错误信息 
  136. * @Param string 日志信息 
  137. * @Param string 日志所在文件 
  138. * @Param string 日志所在行 
  139. */ 
  140. public function err($msg, $file, $line) 
  141. { 
  142. if($this->level <= self::LOGS_ERR) 
  143. { 
  144. $this->log($this->formatTime()."[{$file}:{$line}]ERR: ${msg}/n"); 
  145. } 
  146. } 
  147. } 

看个例子

#例子中设置记录级别为msg(此时debug信息是不会纪录的),日志文件个数为5,大小为200个字节(测试方便),文件名称为testlog

 

 
  1. $logs = LOGS::getInstance(); 
  2. $logs->init(1, 5, 200, "./", 'testlog'); 
  3.  
  4. $logs->msg("YRT", __FILE__, __LINE__); 
  5. $logs->debug("YRT", __FILE__, __LINE__); 

当我们不停的运行这个例子的时候,会在代码所在文件夹下生成5个文件就像下面这样:

 

 
  1. testlog_4.log 
  2. testlog_3.log 
  3. testlog_2.log 
  4. testlog_1.log 
  5. testlog.log #最新的日志在这个文件中 

以上所述就是本文的全部内容了,希望大家能够喜欢。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表