代码如下,如果使用在注释里面有说明:
<?php
namespace common\log;
use yii;
use yii\base\InvalidConfigException;
use yii\log\LogRuntimeException;
use yii\log\Logger;
use yii\helpers\FileHelper;
use yii\helpers\VarDumper;
use yii\helpers\StringHelper;
/**
使用如下:
$logger = new NewLogger(\Yii::getAlias('@admin') . "/runtime/logs/test/" . date('Ymd') . '.log');
$logger->write("这是日志信息");
* Class NewLogger
* @package common\log
*/
class NewLogger {
public $maxFileSize;
public $logFile;
public $enableRotation;
public $maxLogFiles = 5;
public function __construct($logFile, $maxFileSize = 10240, $maxFileNum = 5, $enableRotation = true) {
$this->maxFileSize = $maxFileSize;
$this->logFile = $logFile;
$this->maxLogFiles = $maxFileNum;
$this->enableRotation = $enableRotation;
}
public function write($message, $level = Logger::LEVEL_INFO, $category = '')
{
$logPath = dirname($this->logFile);
FileHelper::createDirectory($logPath, 0755, true);
$time = microtime(true);
$message = [$message, $level, $category, $time, memory_get_usage()];
$text = $this->formatMessage($message) . "\n";
if (($fp = @fopen($this->logFile, 'a')) === false) {
throw new InvalidConfigException("Unable to append to log file: {$this->logFile}");
}
@flock($fp, LOCK_EX);
if ($this->enableRotation) {
clearstatcache();
}
if (@filesize($this->logFile) > $this->maxFileSize * 1024) {
$this->rotateFiles();
@flock($fp, LOCK_UN);
@fclose($fp);
$writeResult = @file_put_contents($this->logFile, $text, FILE_APPEND | LOCK_EX);
if ($writeResult === false) {
$error = error_get_last();
throw new LogRuntimeException("Unable to export log through file!: {$error['message']}");
}
$textSize = strlen($text);
if ($writeResult < $textSize) {
throw new LogRuntimeException("Unable to export whole log through file! Wrote $writeResult out of $textSize bytes.");
}
} else {
$writeResult = @fwrite($fp, $text);
if ($writeResult === false) {
$error = error_get_last();
throw new LogRuntimeException("Unable to export log through file!: {$error['message']}");
}
$textSize = strlen($text);
if ($writeResult < $textSize) {
throw new LogRuntimeException("Unable to export whole log through file! Wrote $writeResult out of $textSize bytes.");
}
@flock($fp, LOCK_UN);
@fclose($fp);
}
}
protected function rotateFiles() {
$file = $this->logFile;
for ($i = $this->maxLogFiles; $i >= 0; --$i) {
// $i == 0 is the original log file
$rotateFile = $file . ($i === 0 ? '' : '.' . $i);
if (is_file($rotateFile)) {
// suppress errors because it's possible multiple processes enter into this section
if ($i === $this->maxLogFiles) {
@unlink($rotateFile);
continue;
}
$newFile = $this->logFile . '.' . ($i + 1);
$this->rotateByCopy($rotateFile, $newFile);
if ($i === 0) {
$this->clearLogFile($rotateFile);
}
}
}
}
/***
* Copy rotated file into new file
* @param string $rotateFile
* @param string $newFile
*/
private function rotateByCopy($rotateFile, $newFile) {
@copy($rotateFile, $newFile);
}
/***
* Clear log file without closing any other process open handles
* @param string $rotateFile
*/
private function clearLogFile($rotateFile) {
if ($filePointer = @fopen($rotateFile, 'a')) {
@ftruncate($filePointer, 0);
@fclose($filePointer);
}
}
/**
* 格式化内容
* Formats a log message for display as a string.
* @param array $message the log message to be formatted.
* The message structure follows that in [[Logger::messages]].
* @return string the formatted message
*/
public function formatMessage($message)
{
list($text, $level, $category, $timestamp) = $message;
$level = Logger::getLevelName($level);
if (!is_string($text)) {
// exceptions may not be serializable if in the call stack somewhere is a Closure
if ($text instanceof \Throwable || $text instanceof \Exception) {
$text = (string) $text;
} else {
$text = VarDumper::export($text);
}
}
$prefix = $this->getMessagePrefix();
return $this->getTime($timestamp) . " {$prefix}[$level][$category] $text";
}
/**
* 内容前缀
* @return string
* @throws \Exception
* @throws \Throwable
*/
public function getMessagePrefix(){
if (Yii::$app === null) {
return '';
}
/* @var $user \yii\web\User */
$user = Yii::$app->has('user', true) ? Yii::$app->get('user') : null;
if ($user && ($identity = $user->getIdentity(false))) {
$userID = $identity->getId();
} else {
$userID = '-';
}
/* @var $session \yii\web\Session */
$session = Yii::$app->has('session', true) ? Yii::$app->get('session') : null;
$sessionID = $session && $session->getIsActive() ? $session->getId() : '-';
return "[][$userID][$sessionID]";
}
/**
* 获取时间
* @param $timestamp
* @return bool|string
*/
protected function getTime($timestamp){
$parts = explode('.', StringHelper::floatToString($timestamp));
return date('Y-m-d H:i:s', $parts[0]);
}
}