خطاها و لاگ

پیکربندی

کلاس راه انداز (bootstrapper) Illuminate\Foundation\Bootstrap\ConfigureLogging مکانیست که میتوانید پیکربندی امکانات لاگ کردن برای نرم افزار را در آن انجام دهید. این کلاس از گزینه پیکربندی log که در فایل config/app.php تعریف شده استفاده میکند.

به صورت پیش فرض لاگر برای استفاده از ایجاد لاگ روزانه تنظیم شده است؛ هرچند شما میتوانید این تنظیمات را براساس نیاز خود تغییر دهید. از آنجا که لاراول از کتابخانه شناخته شده Monolog استفاده میکند، میتوانید از هندلرهای بسیاری که Monolog ارائه میکند استفاده نمایید.

برای مثال، اگر بخواهید به جای استفاده از فایلهای روزانه از یک فایل استفاده کنید، میتوانید گزینه زیر را در فایل پیکربندی config/app.php قرار دهید:

'log' => 'single'

به طور کلی لاراول مُدهای لاگ گیری single، daily، syslog، و errorlog را پشتیبانی مینماید. میتوانید با بازنویسی کلاس راه انداز ConfigureLogging رفتار لاگ گیری اختصاصی مربوط به نرم افزار خود را ایجاد نمایید.

جزئیات خطا

میزان جزیئاتی که نرم افزار در مرورگر نمایش میدهد به مقدار گزینه app.debug در فایل تنظیمات بستگی دارد. به صورت پیش فرض، این گزینه مقدار خود را از متغیر محلی APP_DEBUG در فایل .env میگیرد.

برای توسعه بر روی ماشین محلی، باید مقدار متغیر محلی APP_DEBUG را با true مقداردهی کنید. در محیط تجاری این مقدار باید همیشه false باشد.

مدیریت خطاها - Handling Errors

تمامی اکسپشنها با استفاده از کلاس App\Exceptions\Handler مدیریت می شوند. این کلاس دو متد دارد: report و render.

متد report برای لاگ کردن اکسپشنها یا فرستادن آنها به یک سرویس خارجی مانند BugSnag استفاده میشود. به صورت پیش فرض متد report اکسپشن را به پیاده سازی پایه از کلاس پدر میفرستد. کلاس پدر اکسپشن را لاگ میکند. شما آزادید اکسپشنها را به روش خودتان لاگ کنید. اگر میخواهید اکسپشنهای مختلف را به روشهای مختلف لاگ کنید از اپراتور مقایسه instanceof در PHP استفاده کنید:

/**
 * Report or log an exception.
 *
 * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
 *
 * @param  \Exception  $e
 * @return void
 */
public function report(Exception $e)
{
    if ($e instanceof CustomException)
    {
        //
    }

    return parent::report($e);
}

متد render مسئول تبدیل اکسپشن به یک پاسخ HTTP است، این پاسخ به مرورگر بازگردانده می شود. به صورت پیش فرض، اکسپشن به کلاس پایه که یک پاسخ برای شما ایجاد میکند فرستاده می شود. هرچند شما میتوانید نوع اکسپشن را چک کرده و پاسخ متناسب خود را بازگردانید.

متغیر dontReport از مدیر اکسپشن (Exception Handler) آرایه ی اکسپشنهایی که لاگ نمی شوند را نگاه میدارد. به صورت پیش فرض، اکسپشنهایی که از خطای 404 ایجاد می شوند در فایل لاگ ثبت نمیشوند. شما میتوانید اکسپشنهای دیگری را هم به این آرایه بیافزایید.

اکسپشنهای HTTP

برخی اکسپشنها کدهای خطای HTTP از سرور را توصیف میکنند. برای مثال، این اکسپشن میتواند یک خطای "صفحه موجود نیست - Page not found" (404)، خطای "غیرمجاز - unauthorized" (401) یا حتی یک خطای 500 تولید شده توسط توسعه دهنده باشد. برای برگرداندن پاسخهای اینگونه از روش زیر استفاده کنید:

abort(404);

میتوانید یک پاسخ اختیاری ارائه نمایید:

abort(403, 'Unauthorized action.');

این متد میتواند در هر لحطه از چرخه عمر درخواست استفاده شود.

صفحه خطای اختصاصی خطای 404

برای بازگرداندن یک view اختصاصی برای تمامی خطاهای 404، یک فایل resources/views/errors/404.blade.php ایجاد کنید. این view برای تمامی خطاهای 404 ایجاد شده توسط نرم افزار شما نمایش داده می شود.

لاگ کردن

لاراول از کتابخانه شناخته شده Monolog استفاده میکند. به صورت پیش فرض لاراول تنظیم شده تا به ازای هر روز یک فایل لاگ ایجاد کند. این فایلها دردایرکتوری storage/logs ذخیره می شوند. میتوانید اطلاعات را به شکل زیر لاگ کنید:

Log::info('This is some useful information.');

Log::warning('Something could be going wrong.');

Log::error('Something is really going wrong.');

لاگر 7 سطح لاگ معرفی شده در RFC 5424 را پشتیبانی میکند:

آرایه ای از داده های مرتبط را نیز میتوان به متدهای لاگ فرستاد:

Log::info('Log message', ['context' => 'Other helpful information']);

Monolog هندلرهای زیادی دارد که میتوانید برای لاگ کردن استفاده کنید. در صورت نیاز میتوانید به نمونه های کلاس پایه ای تر Monolog که لاراول از آنها استفاده میکند دسترسی داشته باشد:

$monolog = Log::getMonolog();

همچنین میتوانید رویدادی (event) برای گرفتن تمامی پیامهای فرستاده شده به لاگ استفاده کنید:

ثبت event listener لاگ

Log::listen(function($level, $message, $context)
{
    //
});