امیر کارآموز پیاچپی در کوئرا است. اخیرا طراحی یکی از سیستمهای کوئرا را به امیر سپردن اما از آنجایی که این پروژه، اولین پروژه بزرگ امیر هستش، در عیبیابی پروژه دچار مشکل شده است.
امیر از محمدمهدی که از برنامهنویسای قدیمی کوئراست راهنمایی خواست و محمدمهدی هم به امیر توضیح داد که لاگ و سیستم ثبت لاگ چیه و پیشنهاد داد که امیر برای پروژهاش یک سیستم ثبت لاگ طراحی کند و برای عیبیابی از آن استفاده کند. محمدمهدی یک پروژه اولیه هم برای طراحی سیستم ثبت لاگ به امیر ارسال کرد و به او گفت که اگر میخواهد سیستم ثبت لاگ خوبی داشته باشد، باید این پروژه را کامل کند.
اما از آنجایی که امیر هنوز به پیاچپی مسلط نیست، از شما برای انجام این کار کمک خواسته است.
پروژه اولیه
پروژه اولیه را از اینجا دانلود کنید. ساختار فایلهای این پروژه به صورت زیر است.
logger
├── LogException.php
├── Logger.php
└── LoggerInterface.php
جزئیات
کلاسها
\Quera\LoggerInterface
این کلاس interfaceای است که کلاس Logger باید آن را پیادهسازی کند.
این کلاس از PHP Standards Recommendations برداشته شدهاست.
\Quera\Logger
این کلاس کلاسِ اصلی ما است که دارای توابع زیر است:
- تابع کانستراکتور : دو ورودی میگیرد که اولی آدرسی است که لاگ باید در آن ذخیره شود و دومی گزینههای مرتبط با روش ذخیره است.
 
آدرس میتواند لینک یک API یا آدرس کامل یک فایل باشد که از طریق type در گزینهها مشخص میشود.
آرایهی گزینهها میتواند شامل موارد زیر باشد:
type: نشاندهنده نوع ذخیره لاگ هست که میتواندfileیاapiباشد و در صورتی که هیچکدام از این دو نباشد تابع باید یک خطا از نوعLogExceptionپرتاب کند.
dateFormat: فرمت مورد نظر برای درج تاریخ در لاگ را نشان میدهد و از نوع فرمت استاندارد در پیاچپی است.
logFormat: فرمت مورد نظر برای ذخیره لاگ را نشان میدهد. این فرمت میتواند دارای متغیرهایی باشد که میتوانندdate,levelوmessageباشند یا از طریق متغیرcontextدر توابع لاگ ارسال شوند. همچنین ممکن است درmessageنیز مانندlogFormatمتغیر وجود داشته باشد.dateبا تاریخ با فرمت مورد نظر درdateFormatجایگزین میشود.levelبا اهمیت لاگ با حروف بزرگ جایگزین میشود. messageبا پیام ارسالی هنگام فراخوانی توابع لاگ جایگزین میشود. متغیرها با علامت{}دورشان مشخص میشوند.
threshold: نشاندهنده حداقل اهمیت مورد نیاز لاگ برای ذخیره شدن است. اهمیت لاگها به ترتیب از زیاد به کم از چپ به راست بهصورتEMERGENCY, ALERT, CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUGاست. اگر برابرALLقرار داده شود همه سطوح را ذخیره میکند. اگر مقداری متفاوت از ۹ مقدار ذکر شده قرار داده شود، باید یک خطا از نوعLogExceptionپرتاب کند.
append: در صورت انتخاب شدن نوعfile، اگر مقدار این متغیر برابرtrueباشد، لاگها را به انتهای فایل مشخص شده اضافه میکند و در غیر این صورت از ابتدای فایل شروع به نوشتن لاگها میکند.
در صورتی که هرکدام از متغیرها در آرایه ورودی وجود نداشته باشد، مقدار آن از روی جدول زیر باید تعیین شود.
| کلید | مقدار پیشفرض در صورت تعیین نشدن | 
|---|---|
| type | 'file' | 
| dateFormat | 'Y-m-d H' | 
| logFormat | '[{date}]-[{level}]-{message}' | 
| threshold | 'ALL' | 
| append | true | 
- توابع موجود در 
LoggerInterfaceکه شاملemergency,alert,critical,error,warning,notice,info,debugکه هر کدام یک لاگ با سطح متفاوت ذخیره میکنند، میباشد. علاوه بر آنها تابعlogنیز مانند آنها وجود دارد با این تفاوت که سطح لاگ را با حروف بزرگ به عنوان ورودی دریافت میکند. 
با صدا شدن هرکدام ازین ۹ تابع مرتبط به لاگ، باید لاگ در همان زمان طبق گزینههای انتخاب شده در کانستراکتور کلاس، در فایل ذخیره شده یا به فرمت POST به API ارسال شود.
\Quera\LogException
این کلاس خطایی است که در صورت وجود اشتباه در آپشنهای ورودی سازنده کلاس Logger پرتاب میشود.
مثال
یک نمونه از اجرای این کلاس به شکل زیر است:
$options = [
    'dateFormat' => 'Y-m-d H',
    'logFormat' => '[{date}] {level}-{message}',
    'threshold' => 'ERROR',
    'append' => true,
];
$logger =  new Quera\Logger("~/debug.log", $options);
$logger->critical('oh oh');
$logger->emergency('system is down');
$logger->notice('change variable name');
$logger->log('ERROR', 'error in line 2');
$logger->error('error in line {variable1}', ['variable1' => '6']);
/* file ~/debug.log:
[2019-10-03 10] CRITICAL-oh oh
[2019-10-03 10] EMERGENCY-system is down
[2019-10-03 10] ERROR-error in line 2
[2019-10-03 10] ERROR-error in line 6
*/
نکات
- 
پروژه اولیه دارای ۳ فایل است که شما تنها میتوانید در فایل
Logger.phpتغییرات ایجاد کنید. - 
کلاس
Loggerلزوما بایدLoggerInterfaceرا پیادهسازی کند. - 
TimeZoneراAsia/Tehranقرار دهید. - 
در هنگام ارسال به
APIپیام باید با عنوانmessageارسال شود، به شکلی که با استفاده از$_POST['message']قابل دسترسی باشد و برای مثال با فرمت اولیه، اگر به شکل 
 $logger->emergency('something went wrong...')
فراخوانی شده باشد محتوای $_POST['message'] به شکل
[2019-10-02 21]-[EMERGENCY]-something went wrong...
دریافت میشود.
بارگذاری
در انتها فایل های زیر را به صورت یک فایل zip آپلود نمایید. نام فایل zip اهمیتی ندارد.
[your-zip-file-name].zip
├── LogException.php
├── Logger.php
└── LoggerInterface.php
ارسال پاسخ برای این سؤال