Yii2 捕获错误日志


在技术开发中,捕获程序框架错误,是非常必要的一件事情,我们公司使用Yii2框架,简单说下Yii2的错误捕获处理

Yii2 web应用

1 配置如下

  其中errorHandler就是错误处理配置,执行ErrorController的actionError

'components' => [
    "urlManager" => require (__DIR__ . '/router.php'),
    'errorHandler' => [
        'errorAction' => 'error/error',
    ],
]


2 ErrorContrller代码示例

<?php

namespace blog\controllers;

use common\service\applog\ApplogService;
use Yii;

class ErrorController extends \yii\web\Controller{
    public $enableCsrfValidation = false;
    public function actionError() {

        $code = 404;
        $msg = 'Page Not Found';

        $error = Yii::$app->errorHandler->exception;
        if ($error) {
            $code = $error->getCode();
            $msg = $error->getMessage();
            $file = $error->getFile();
            $line = $error->getLine();

            $err_msg = $msg . " [file: {$file}][line: {$line}][err code:$code.][url:{$_SERVER['REQUEST_URI']}][post:".http_build_query($_POST)."]";
            ApplogService::add(Yii::$app->id,$err_msg);//我这里存入数据库
        }
        
    }


}


命令行应用

1 配置如下,配置指定使用ErrorController(命令行应用和web应用还是有区别的)

'components' => [
    "urlManager" => require (__DIR__ . '/router.php'),
    'errorHandler' => [
        'class' => 'console\controllers\ErrorController'
    ]
]

2 ErrorController代码示例

<?php

namespace console\controllers;;

use common\service\applog\ApplogService;
use Yii;
use yii\base\ErrorException;
use yii\base\UserException;
use yii\helpers\Console;
use yii\console\Exception;


class ErrorController extends \yii\base\ErrorHandler{

    protected function renderException($exception){
        if ($exception instanceof Exception && ($exception instanceof UserException || !YII_DEBUG)) {
            $message = $this->formatMessage($exception->getName() . ': ') . $exception->getMessage();
        } else{
            if ($exception instanceof Exception) {
                $message = $this->formatMessage("Exception ({$exception->getName()})");
            } elseif ($exception instanceof ErrorException) {
                $message = $this->formatMessage($exception->getName());
            } else {
                $message = $this->formatMessage('Exception');
            }
            $message .= $this->formatMessage(" '" . get_class($exception) . "'", [Console::BOLD, Console::FG_BLUE])
                . " with message " . $this->formatMessage("'{$exception->getMessage()}'", [Console::BOLD]) //. "\n"
                . "\n\nin " . dirname($exception->getFile()) . DIRECTORY_SEPARATOR . $this->formatMessage(basename($exception->getFile()), [Console::BOLD])
                . ':' . $this->formatMessage($exception->getLine(), [Console::BOLD, Console::FG_YELLOW]) . "\n";
            if ($exception instanceof \yii\db\Exception && !empty($exception->errorInfo)) {
                $message .= "\n" . $this->formatMessage("Error Info:\n", [Console::BOLD]) . print_r($exception->errorInfo, true);
            }
            $message .= "\n" . $this->formatMessage("Stack trace:\n", [Console::BOLD]) . $exception->getTraceAsString();
        }

        ApplogService::add(Yii::$app->id,$message);//存到数据库中

        if (PHP_SAPI === 'cli') {
            Console::stderr($message . "\n");
        } else {
            echo $message . "\n";
        }
    }

    protected function formatMessage($message, $format = [Console::FG_RED, Console::BOLD]){
        $stream = (PHP_SAPI === 'cli') ? \STDERR : \STDOUT;
        // try controller first to allow check for --color switch
        if (Yii::$app->controller instanceof \yii\console\Controller && Yii::$app->controller->isColorEnabled($stream)
            || Yii::$app instanceof \yii\console\Application && Console::streamSupportsAnsiColors($stream)) {
            $message = Console::ansiFormat($message, $format);
        }
        return $message;
    }
}



对比下 命令行应用 和 web应用,ErrorController继承的不一样,并且实现的方法也不一样的

yii2 console error capture
编程浪子走四方:CodeRonin