日志对象
<?php
class Logger {
private $FileName, $When, $Size, $BackupCount;
private $SuffixFormat = [
'H' => 'Y-m-d_H',
'D' => 'Y-m-d',
'W' => 'Y-m-d',
'M' => 'Y-m'
];
public static function getLogger($fileName) {
return new Logger($fileName);
}
public static function getTimedRotatingLogger($fileName, $when = 'D', $backupCount = 0) {
$logger = new Logger($fileName);
$logger->setTimedRotating($when, abs( intval($backupCount) ) );
return $logger;
}
public static function getSizedRotatingLogger($fileName, $size = 1024, $backupCount = 0) {
$logger = new Logger($fileName);
$logger->setSizedRotating( abs( intval($size) ), abs( intval($backupCount) ) );
return $logger;
}
private function setTimedRotating($when, $backupCount) {
$this->When = $when;
$this->BackupCount = $backupCount;
}
private function setSizedRotating($size, $backupCount) {
$this->Size = $size;
$this->BackupCount = $backupCount;
}
public function __construct($fileName) {
$this->FileName = $fileName;
}
public function info($msg){
return $this->write('INFO', $msg);
}
public function warn($msg){
return $this->write('WARN', $msg);
}
public function debug($msg){
return $this->write('DEBUG', $msg);
}
public function error($msg){
return $this->write('ERROR', $msg);
}
private function write($type, $msg){
$fileName = $this->FileName;
$this->When && $fileName = $this->getTimedFileName();
$this->Size && $fileName = $this->getSizedFileName();
$this->BackupCount && $this->clearLogFile();
$isCreate = $this->createLogPath();
$msg = sprintf('[%s] %-5s %s : %s'.PHP_EOL, date('Y-m-d H:i:s'), $type, get_current_user(), $msg);
if($isCreate){
return file_put_contents($fileName, $msg, FILE_APPEND);
}
return false;
}
private function clearLogFile() {
$files = $this->getAsortFileByTime();
$fileCnt = count($files);
if ($fileCnt <= $this->BackupCount) {
return true;
}
$cnt = 0;
$result = true;
foreach ($files as $file) {
$result &= unlink($file['name']);
if ( ++$cnt == $fileCnt - $this->BackupCount ) {
break;
}
}
return $result;
}
private function getAsortFileByTime() {
$name = explode('.', basename($this->FileName))[0];
$fold = dirname($this->FileName);
$result = glob("$fold/$name*");
$files = [];
foreach ($result as $i => $file) {
$files[$i]['name'] = $file;
$files[$i]['time'] = filemtime($file);
}
uasort($files, function ($f1, $f2){
return $f1['time'] - $f2['time'];
});
return $files;
}
private function getTimedFileName() {
$name = basename($this->FileName);
$pos = strrpos($name, '.');
!isset($this->SuffixFormat[$this->When]) && $this->When = 'D';
$suffix = date($this->SuffixFormat[$this->When]);
$files = $this->getAsortFileByTime();
$lastFile = end($files);
$newFileName = dirname($this->FileName) . '/' . ($pos ? substr($name, 0, $pos) . $suffix . substr($name, $pos) : $name . $suffix);
return $this->When == 'W' && $lastFile && time() - $lastFile['time'] > 7 * 24 * 3600 || $this->When != 'W' ? $newFileName : $lastFile['name'];
}
private function getSizedFileName() {
$files = $this->getAsortFileByTime();
$lastFile = end($files);
$fileName = $this->FileName;
if ($lastFile && filesize($lastFile['name']) > 1024 * $this->Size) {
$this->When = 'S';
$this->SuffixFormat['S'] = 'Y-m-d_H-i-s';
$fileName = $this->getTimedFileName();
} else if ($lastFile) {
$fileName = $lastFile['name'];
}
return $fileName;
}
private function createLogPath(){
$path = dirname($this->FileName);
if(!is_dir($path)){
return mkdir($path, 0777, true);
}
return true;
}
}
?>
获取日志对象
$fileName = 'logging/test.log';
$logger = Logger::getLogger($fileName);
$sizedLogger = Logger::getSizedRotatingLogger($fileName, 5, 3);
$timedLogger = Logger::getTimedRotatingLogger($fileName, 'H');
普通日志测试
for ($i = 0;$i < 10;$i++) {
$logger->info('test info');
$logger->warn('test warn');
$logger->error('test error');
$logger->debug('test debug');
}
按文件大小分割的日志测试
for ($i = 0;$i < 600;$i++) {
$sizedLogger->info('test info');
$i % 100 == 0 && sleep(1);
}
按时间分割的日志测试
for ($i = 0;$i < 100;$i++) {
$timedLogger->info('test info');
}