Laravel 5.7 Как зарегистрировать 404 с URL-адресом

Я хочу регистрировать 404 ошибки в Laravel 5.7, но не понимаю, как это включить. В дополнение к регистрации ошибок 404 я хотел бы зарегистрировать запрошенный URL-адрес. Другие ошибки регистрируются корректно.

.env

APP_DEBUG=true
LOG_CHANNEL=stack

конфиг/logging.php

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

Согласно Документация по обработке ошибок:

The $dontReport property of the exception handler contains an array of exception types that will not be logged. For example, exceptions resulting from 404 errors, as well as several other types of errors, are not written to your log files. You may add other exception types to this array as needed:

В app/Exceptions/Handler массив $dontReport пуст.

Я настроил представление 404 с помощью Blade-файла resources/views/errors/404.blade.php.

На основе этот ответ я попробовал этот код в 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);
}

ОБНОВЛЕНИЕ после принятия ответа Мозаммила, который отлично работает. Я сократил его ответ до приведенного ниже. Не забудьте добавить use Illuminate\Support\Facades\Log в файл Handler.

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);
}

🤔 А знаете ли вы, что...
Laravel активно обновляется и совершенствуется, чтобы соответствовать современным стандартам.


4
3 064
3

Ответы:

Решено

У меня аналогичное требование. Вот как я этого добился.

У меня есть вспомогательный метод, чтобы определить, является ли это ошибкой 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. Однако во всех случаях моя реализация работала для меня :)


Я использую Телескоп

Ларавель Телескоп
Laravel Telescope — элегантный помощник по отладке фреймворка Laravel. Telescope предоставляет информацию о запросах, поступающих в ваше приложение, исключениях, записях журнала, запросах к базе данных, заданиях в очереди, почте, уведомлениях, операциях кэширования, запланированных задачах, дампах переменных и многом другом.

https://laravel.com/docs/5.7/телескоп


Я стараюсь отлавливать все виды ошибок 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);
    }
}

P.S. Я использую laravel 8, но уверен, что он будет работать в большинстве популярных версий.