> 백엔드 개발 > PHP 튜토리얼 > PHP 롤링 log_php 기술의 코드 구현

PHP 롤링 log_php 기술의 코드 구현

WBOY
풀어 주다: 2016-05-16 20:14:20
원래의
1447명이 탐색했습니다.

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를 덮어쓰게 됩니다. 이렇게 하면 정상적인 로그 기록이 이루어지며 대용량 로그 파일이 나타나지 않아 로그 시스템이 정상적으로 작동됩니다.

코드 구현

<&#63;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(지금은 디버그 정보가 기록되지 않음)로 설정하고, 로그 파일 개수는 5개, 크기는 200바이트(테스트하기에 편리함), 파일 이름은 테스트로그입니다

$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.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿