لاگ ها
در جالنو از لاگها بجای کامنت ها استفاده میشود. استفاده از لاگ باعث افزایش خوانایی و بهبود UX سایر برنامه نویسان میشود. همچنین لاگ ها باعث سهولت در عیبیابی پروژه ها میشوند. در واقع لاگ ها توضیحاتی هستند که در بین کدها نوشته میشوند و هر کدام متتناسب با سطحی که دارند بیانگر اطلاعات خاصی از برنامه میباشند. اطلاعاتی از جمله روند اجرا ، اطلاعات دقیق و پایه ای مانند کوئری های ارسال شده به دیتابیس ، ارور های دریافت شده و ... میباشد.
برای کار با لاگها کلاس packages\base\Log
ایجاد شده است.
برای استفاده از لاگ ها باید ابتدا یک شی از کلاس Log از طریق متد getInstance()
ساخته شود.
$log = Log::getInstance();
لاگ ها در مسیر packages/base/storage/protected/logs
و به صورت خودکار لاگ های مربوط به هر روز در فایل جداگانه با تاریخ همان روز ذخیره میشوند.
هر لاگ یک خط مجزا در فایل لاگ است که به ترتیب از ستون های زمان ذخیره، سطح ومتن لاگ تشکیل میشود.
پیکربندی
تنظیمات مربوط به لاگ ها در فایل تنظیمات جالنو (config.php
) که در مسیر packages/base/libraries/config
قرار دارد ذخیره میشود.
تعیین سطح لاگ ها
با استفاده از تنظیم packages.base.logging.level
مشخص میشود کدام سطح از لاگ ها ذخیره شوند.
اگر بخواهیم تمامی لاگ ها در فایل ذخیره شوند مقدار تنظیم را برابر با debug
قرار میدهیم.
'packages.base.logging.level' => 'debug' // info, warn, error, fatal, off
نکته: با فعال سازی این تنظیم تمامی لاگ ها از ابتدای بارگذاری جالنو ذخیره خواهد شد. میتوانید با استفاده از متد setLevel(string $level): void
در ابتدای یک متد خواص، لاگ ها را فقط برای آن متد و متد هایی که بعد از آن فراخوانی میشوند، فعال نمایید. این متد در تنها آرگومان خود یکی از سطوح لاگ را دریافت میکند.
نمایش لاگ ها
با استفاده از تنظیم packages.base.logging.quiet
تعیین میشود لاگ ها در مرورگر نیز نمایش داده شوند یا خیر.
اگر برابر با true باشد لاگها فقط در فایل ذخیره شده و در مرورگر نمایش داده نمیشوند.
'packages.base.logging.quiet' => true // false
سطوح لاگ
لاگها دارای سطوح مختلفی هستند. که شامل موارد زیر میشوند :
نکته :
سطح بندی لاگ ها باعث میشود زمانی که بهطور مثال قصد بررسی روند اجرای برنامه را داریم سطح لاگ را برابر info
قراردهیم و یا زمانی که قصد بررسی دقیق برنامه و مشاهده اطلاعات پایهای تر را داریم سطح لاگ را برابر debug
تنظیم کنیم.
نکته : برای متدهای کار با سطوح لاگ میتوان به تعداد دلخواه آرگومان تعریف کرد. ارگومان ها به ترتیب در متن لاگ آورده میشوند.
سطح | کاربرد |
---|---|
debug | اطلاعات کامل برنامه که میتواند اطلاعات حساس و یا روند برنامه باشد |
info | توضیحات روند اجرا برنامه |
warn | توضیحاتی از روند برنامه که نیاز به بررسی و یا حساسیت بیشتری داشته باشد به حالت هشداری نمایش داده میشود |
error | برای نمایش خطاهای برنامه استفاده میشود |
fatal | خطاهایی که برنامه را متوقف میکند |
سطح debug
از سطح debug()
برای مشخص کردن اطلاعات پایه ای مانند کوئری ارسال شده به دیتابیس استفاده میشود. debug اطلاعات ریز و جزئی تر را در لاگ ذخیره میکند.
مثال
use packages\base\Log;
Log::setLevel("debug"); // Log::setLevel("info");
$log = Log::getInstance();
$log->debug("current service status: ", $service->service->status);
if ($service->service->status == Service::SUSPENDED) {
$log->info("unsuspending");
if ($this->dryRun) {
$log->reply("dry-Run");
} else {
$service->service->unsuspend();
$log->reply("Success");
}
}
return;
در مثال فوق روند برنامه با استفاده از متد های debug و info نوشته شده است. اگر سطع لاگ بر روی debug تنظیم شده باشد، تمامی روند برنامه و اگر سطح بر روی info تنظیم شده باشد، فقط روند های برنامه که با استفاده از متد info نوشته شده اند، ذخیره خواهند شد.
همچنین در جالنو به صورت خودکار تمامی اقدامات مهم و حیاتی که برای عیب یابی و دیباگ نیاز هستند، با استفاده از سطح لاگ debug نوشته شده اند. اگر سطع لاگ را بر روی debug تنظیم کرده باشید، این اطلاعات نیز ذخیره و یا نمایش داده میشوند.
مثال از نمونه فایل لاگ
2020-10-19 11:37:46.15401000 +00:00 [DEBUG] SQL Query: SELECT value AS retval FROM options WHERE name = 'packages.base.translator.active.langs' LIMIT 1
2020-10-19 11:37:46.15945600 +00:00 [DEBUG] SQL Query: SELECT value AS retval FROM options WHERE name = 'packages.base.cache' LIMIT 1
سطح info
از info()
برای ذخیره کردن توضیحاتی از روند اجرای برنامه استفاده میشود. در مثال زیر میخواهیم کاربری را طبق مشخصه شماره موبایل در دیتابیس پیدا کنیم;
این توضیحات را با استفاده از info در لاگ ذخیره میکنیم.
مثال 1
use packages\base\Log;
// Log::setLevel("info");
$log = Log::getInstance();
if (!$user and isset($parameters["inputs"]["cellphone"])) {
$log->info("try to find user by cellphone:", $parameters["inputs"]["cellphone"]);
$user = (new User)->where("cellphone", $parameters["inputs"]["cellphone"])->getOne();
if ($user) {
$log->reply("found, #", $user->id);
} else {
$log->reply("notfound");
}
}
نمونه info در فایل لاگ
2020-10-17 14:55:48.93523900 +00:00 [INFO] method: get
2020-10-17 14:55:48.93526500 +00:00 [INFO] scheme: http
2020-10-17 14:55:48.93529600 +00:00 [INFO] hostname: www.domain.com
2020-10-17 14:55:48.93533500 +00:00 [INFO] uri: /favicon.ico
2020-10-17 14:55:48.93536400 +00:00 [INFO] url parameters: []
2020-10-17 14:57:35.77234100 +00:00 [INFO] try to find user by cellphone: 09131234567 : notfound
اگر سطع لاگ بر روی debug تنظیم شده باشد، نمونه ف ایل به صورت زیر خواهد بود.
نمونه فایل
2020-10-17 14:57:35.77234100 +00:00 [INFO] try to find user by cellphone: 09131234567
2020-10-17 14:37:36.15945600 +00:00 [DEBUG] SQL Query: SELECT * FROM userpanel_users WHERE cellphone = '09131234567' LIMIT 1
2020-10-17 14:57:36.77234100 +00:00 [INFO] try to find user by cellphone: 09131234567 : notfound
مثال 2
use packages\base\Log;
Log::setLevel("info");
$l = Log::getInstance();
$l->info("change teacher name of class", $class->id);
if($inputs['name']){
$class->teacher_name = $inputs['name'];
}
مثال 3
use packages\base\Log;
Log::setLevel("info");
$l = Log::getInstance();
$l->info("get logs that has not title");
$type = db::subQuery();
$type->where("name", "userpanel_users_edit");
$types = $type->get("userpanel_usertypes_permissions", null, "userpanel_usertypes_permissions.type");
سطح error
از error()
برای ذخیره خطا های برنامه استفاده میشود. این خطا ها میتوانند خطاهای مهلک و یا میتوانند جواب های ناخواسته در روند برنامه باشند.
نکته: اگر سطح لاگ بر روی debug و یا حتی info تنظیم شده باشد، لاگ های این سطح نیز ذخیره خواهند شد.
مثال
use packages\base\Log;
use packages\base\View\Error;
$log = Log::getInstance();
$log->info("Get services");
$services = (new Service)->where("server_id", $data["server"])->get();
if (!$services) {
$log->error("Unable to find any service");
throw new Error("Unable to find any service");
}
نمونه فایل لاگ
2020-10-20 13:51:56.41038100 +00:00 [INFO] Get services
2020-10-20 13:51:56.41041900 +00:00 [ERROR] Unable to find any service
سطح fatal
از fatal()
برای ذخیره توضیح خطاهایی استفاده میشود که باعث میشوند اجرای برنامه متوقف شود.
در مثال زیر به دلیل تنظیم نشدن host برنامه متوقف میشود. توضیحات توقف برنامه با استفاده از fatal در لاگ ذخیره میشود.
نکته: اگر سطح لاگ بر روی debug، error و یا حتی info تنظیم شده باشد، لاگ های این سطح نیز ذخیره خواهند شد.
نکته: اگر سطح لاگ بر روی fatal تنظیم شده باشد، فقط لاگ های fatal ذخیره خواهند شد.
مثال
use packages\base\Log;
Log::setLevel("fatal");
$log = Log::getInstance();
if (empty($this->host)) {
$log->fatal('MySQL host is not set');
throw new \Exception('MySQL host is not set');
}
نمونه fatal در فایل لاگ
2020-10-17 19:11:17.43898700 +00:00 [FATAL] MySQL host is not set
سطح warn
از warn()
برای ذخیره روند هایی از برنامه استفاده میکنیم که حساسیت بیشتری داشته و یا نیاز به بررسی دارند.
مانند کوئری هایی که نتیجه ی آن چندان مورد قبول نیست.
نکته: اگر سطح لاگ بر روی debug و یا حتی info تنظیم شده باشد، لاگ های این سطح نیز ذخیره خواهند شد.
مثال
use packages\base\Log;
Log::setLevel("info");
$log = Log::getInstance();
$log->info("FOUND. ip", $dir->basename, "is blong to server", $param->server);
$server = (new Server)->where("status", Server::ACTIVE)->byId($param->server);
if (!$server) {
$log->reply()->warn("is not exists or is disabled");
return;
}