Yii2日志:自定义日志目录和文件

代码如下,如果使用在注释里面有说明:

<?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]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值