PHP滚动日志的代码实现


Posted in PHP onJune 10, 2015

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,这样就可以保证日志正常记录,而且不会出现很大很大的日志文件,保证日志系统的正常运行。

代码实现

<?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");
 }
 }
}

看个例子

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

$logs = LOGS::getInstance();
$logs->init(1, 5, 200, "./", 'testlog');

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

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

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

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

PHP 相关文章推荐
PHP 防恶意刷新实现代码
May 16 PHP
在php中判断一个请求是ajax请求还是普通请求的方法
Jun 28 PHP
ThinkPHP与PHPExcel冲突解决方法
Aug 08 PHP
PHP连接MongoDB示例代码
Sep 06 PHP
php实现判断访问来路是否为搜索引擎机器人的方法
Apr 15 PHP
Yii基于CActiveForm的Ajax数据验证用法示例
Jul 14 PHP
php常用字符函数实例小结
Dec 29 PHP
php实现用户注册密码的crypt加密
Jun 08 PHP
Thinkphp开发--集成极光推送
Sep 15 PHP
PHP类与对象后期静态绑定操作实例详解
Dec 20 PHP
PHP中上传文件打印错误错误类型分析
Apr 14 PHP
thinkphp框架表单数组实现图片批量上传功能示例
Apr 04 PHP
简单谈谈favicon
Jun 10 #PHP
简单谈谈php中的unicode和utf8编码
Jun 10 #PHP
PHP中生成UUID自定义函数分享
Jun 10 #PHP
php使用for语句输出三角形的方法
Jun 09 #PHP
php生成图片验证码
Jun 09 #PHP
php判断用户是否手机访问代码
Jun 08 #PHP
浅谈PHP中Stream(流)
Jun 08 #PHP
You might like
php不写闭合标签的好处
2014/03/04 PHP
PHP目录与文件操作技巧总结(创建,删除,遍历,读写,修改等)
2016/09/11 PHP
Yii2框架实现利用mpdf创建pdf文件功能示例
2019/02/08 PHP
Javascript Global对象
2009/08/13 Javascript
jQuery EasyUI API 中文文档 - NumberSpinner数值微调器使用介绍
2011/10/21 Javascript
常用jQuery选择器总结
2014/07/11 Javascript
JS实现鼠标点击展开或隐藏表格行的方法
2015/03/03 Javascript
JavaScript实现点击按钮就复制当前网址
2015/12/14 Javascript
浅谈angularJS中的事件
2016/07/12 Javascript
js判断文件格式及大小的简单实例(必看)
2016/10/11 Javascript
ES6 javascript的异步操作实例详解
2017/10/30 Javascript
jquery在启动页面时,自动加载数据的实例
2018/01/22 jQuery
webpack-dev-server自动更新页面方法
2018/02/22 Javascript
JavaScrip数组去重操作实例小结
2019/06/20 Javascript
重置Redux的状态数据的方法实现
2019/11/18 Javascript
手机浏览器唤起微信分享(JS)
2020/10/11 Javascript
解决vue项目中遇到 Cannot find module ‘chalk‘ 报错的问题
2020/11/05 Javascript
[03:43]TI9战队采访——PSG.LGD
2019/08/22 DOTA
用Python写冒泡排序代码
2016/04/12 Python
python中学习K-Means和图片压缩
2017/11/20 Python
Python中的pygal安装和绘制直方图代码分享
2017/12/08 Python
python 按照固定长度分割字符串的方法小结
2018/04/30 Python
python+selenium定时爬取丁香园的新型冠状病毒数据并制作出类似的地图(部署到云服务器)
2020/02/09 Python
基于matplotlib xticks用法详解
2020/04/16 Python
python 如何设置守护进程
2020/10/29 Python
HTML5 audio标签使用js进行播放控制实例
2015/04/24 HTML / CSS
西班牙香水和化妆品购物网站:Arenal Perfumerías
2019/03/01 全球购物
Monica Vinader官网:英国轻奢珠宝品牌
2020/02/05 全球购物
个人简历自我鉴定
2013/10/11 职场文书
开学典礼策划方案
2014/05/28 职场文书
学校领导班子对照检查材料
2014/08/28 职场文书
个人收入证明范本
2014/09/18 职场文书
学校副校长四风对照检查材料整改措施
2014/09/25 职场文书
一条 SQL 语句执行过程
2022/03/17 MySQL
把77A收信机改造成收音机
2022/04/05 无线电
Java实现简单小画板
2022/06/10 Java/Android