Laravel 5.7如何使用URL登录404

时间:2019-01-27 19:43:17

标签: laravel laravel-5.7 laravel-exceptions

我想在Laravel 5.7中记录404错误,但是我不知道如何打开它。除了记录404错误外,我还要记录所请求的URL。其他错误已正确记录。

.env

APP_DEBUG=true
LOG_CHANNEL=stack

config / logging.php

'stack' => [
    'driver' => 'stack',
    'channels' => ['daily'],
],

根据Error Handling documentation

  

异常处理程序的$ dontReport属性包含一个数组   不会记录的异常类型。例如,例外   是由于404错误以及其他几种错误导致的,   不会写入您的日志文件。您可以添加其他异常类型   根据需要添加到该数组:

app/Exceptions/Handler中,$dontReport数组为空。

我通过拥有Blade文件resources/views/errors/404.blade.php

自定义了404视图

基于this answer,我已经在app/Exceptions/Handler,中尝试过此代码,但是日志中没有任何显示内容:

public function report(Exception $exception)
{
    if ($this->isHttpException($exception)) {
        if ($exception instanceof NotFoundHttpException) {
            Log::warning($message);
            return response()->view('error.404', [], 404);
        }
        return $this->renderHttpException($exception);
    }

    parent::report($exception);
}

接受Mozammil的回答后更新,效果很好。 我已将他的回答简化如下。不要忘记将use Illuminate\Support\Facades\Log添加到处理程序文件中。

public function render($request, Exception $exception)
{
    if ($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) {
        Log::warning('404: ' . $request->url());
        return response()->view('errors.404', [], 404);
    }
    return parent::render($request, $exception);
}

3 个答案:

答案 0 :(得分:1)

我有类似的要求。这是我实现它的方式。

我有一个辅助方法来确定它是否是404。

private function is404($exception)
{
    return $exception instanceof \Illuminate\Database\Eloquent\ModelNotFoundException
            || $exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
}

我还有另一种方法来实际记录404。

private function log404($request) 
{
    $error = [
        'url'    => $request->url(),
        'method' => $request->method(),
        'data'   => $request->all(),
    ];

    $message = '404: ' . $error['url'] . "\n" . json_encode($error, JSON_PRETTY_PRINT);

    Log::debug($message);
}

然后,要记录错误,我只是在render()方法中做类似的事情:

public function render($request, Exception $exception)
{
    if($this->is404($exception)) {
        $this->log404($request);
    }

    return parent::render($request, $exception);
}

我不知道$internalDontReport。但是,在所有情况下,我的实现都对我有用:)

答案 1 :(得分:1)

我注意捕捉所有类型的 4xx 错误,因此,我通过在渲染函数中添加以下代码来编辑 app/Exceptions/Handler.php 文件

if($exception instanceof \Illuminate\Database\Eloquent\ModelNotFoundException ||
        $exception instanceof \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException ||
        $exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException){
        $error = [
            'message'=> $exception->getMessage(),
            'type'   => \get_class($exception),
            'url'    => $request->url(),
            'method' => $request->method(),
            'data'   => $request->all(),
        ];

        $message = $exception->getStatusCode().' : ' . $error['url'] . "\n" . \json_encode($error, JSON_PRETTY_PRINT);
        //Store the object in DB or log file
        \Log::debug($message);
    }

此代码将捕获 [ModelNotFoundException, MethodNotAllowedHttpException, NotFoundHttpException] 的异常 - 简而言之,这将捕获 404 错误、数据库中未找到模型和错误方法 - 并创建一个名为 $error 的对象,您将能够存储它随心所欲。

所以 app/Exceptions/Handler.php 会像

<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that are not reported.
     *
     * @var array
     */
    protected $dontReport = [
        //
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array
     */
    protected $dontFlash = [
        'password',
        'password_confirmation',
    ];

    /**
     * Report or log an exception.
     *
     * @param  \Throwable  $exception
     * @return void
     *
     * @throws \Exception
     */
    public function report(Throwable $exception)
    {
        parent::report($exception);
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Throwable  $exception
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @throws \Throwable
     */
    public function render($request, Throwable $exception)
    {

        if($exception instanceof \Illuminate\Database\Eloquent\ModelNotFoundException ||
            $exception instanceof \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException ||
            $exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException){
            $error = [
                'message'=> $exception->getMessage(),
                'type'   => \get_class($exception),
                'url'    => $request->url(),
                'method' => $request->method(),
                'data'   => $request->all(),
            ];

            $message = $exception->getStatusCode().' : ' . $error['url'] . "\n" . \json_encode($error, JSON_PRETTY_PRINT);

            \Log::debug($message);
        }
        return parent::render($request, $exception);
    }
}

附言我使用的是 laravel 8,但我相信它可以在大多数流行版本中使用。

答案 2 :(得分:0)

我使用望远镜

Laravel望远镜
Laravel Telescope是Laravel框架的优雅调试助手。 Telescope可以洞察进入您的应用程序的请求,异常,日志条目,数据库查询,排队的作业,邮件,通知,缓存操作,计划任务,变量转储等。

https://laravel.com/docs/5.7/telescope