PDA

View Full Version : PHP/App error logging



freeman99
یک شنبه 17 اسفند 1393, 22:36 عصر
میدونید که لاگ کردن خطاها و حتی هشدارها در فایل یا دیتابیس مهمه، چون ادمین میتونه اونا رو بررسی کنه و ببینه چه خطاها و هشدارهایی رخ دادن و علت رو پیگیری و رفع کنه (شاید باگی در برنامه باشه، شاید کسی میخواسته به سیستم حمله کنه، و غیره).
ولی نمیدونم چند درصد برنامه نویسان برنامه هاشون سیستم لاگ خطا داره :متفکر:

نکته: از این ببعد هرگاه بطور کلی از «خطا» صحبت میکنیم در مواقع منظورمون بطور کلی هرگونه اطلاعات غیرعادی درمورد کارکرد سیستم است، یعنی علاوه بر خطاها، هشدارها (Warning) و آگهی ها (Notice) هم منظور ما هستن.

البته دو نوع خطا داریم؛ یکی خطاهایی که خود PHP متوجه میشه و صادر میکنه و دیگر خطاهایی که مختص خود برنامه هستن و به PHP ربطی ندارن و لزوما موجب متوجه شدن و خطا دادن توسط PHP نمیشن. مثلا یک دیتایی به سیستمی در برنامه میرسه که مطابق فرمت قابل قبول برای اون سیستم نیست (دقت کنید که این دیتاها میتونن مستقیما توسط کاربران هم تولید نشده باشن و مربوط به منطق و کارکردهای داخلی خود برنامه هم باشن)، و سیستم اگر درست و امن طراحی شده باشه ممکنه درصورت صلاحدید و محتمل و لازم دیده شدن از جانب برنامه نویس، اول این فرمت رو چک کنه و اگر نادرست باشه متوجه میشه و میتونه لاگ کنه. میگم درصورت صلاحدید و محتمل و لازم دیدن، چون معمولا تمام داده ها و جریانات در برنامه لازم نیست یا نمیشه که تحت بررسی گسترده قرار داد، و بیشتر در بعضی موارد خاص هست که احتمال پیدایش باگ یا مشکلات امنیتی در اونها میره و بنابراین اون موارد از منطق و جریان داخلی برنامه چک میشن. البته سطح چک های برنامه و دقت و مفصل و محکم کار بودن اون در این زمینه به پارامترهای متعدد دیگری هم بستگی داره (ولی بهرحال بازم مثلا دیگه نمیایم هرجا یه متغییر و داده های داخلی خود برنامه رو مدام چک بکنیم که!).

میدونید که صرف نمایش خطاها در مرورگر کافی نیست، چون اولا طبیعتا تمام خطاها در حضور مسئول سیستم تولید نمیشن که بتونه متوجه بشه و علت رو پیدا و رفع کنه، دوما به دلایل امنیتی و غیره معمولا روی سیستمهای عملیاتی (و نه آزمایشی و تحت توسعه و تست) نمایش خطاها در مرورگر رو خاموش یا محدود میکنن چون این خطاها نباید به کاربران عادی و سوء استفاده کنندگان یا نفوذگران/هکرهای احتمالی ارسال بشن.

بنابراین بنظر میرسه لازمهء هر سیستم اصولی داشتن یک سیستم لاگ خطاست.

حالا میخواستم از تجربیات و اطلاعات شما در این زمینه استفاده کنم و ایده ها و نکاتی رو که در این مورد میدونید یا بنظرتون میرسه بگید.

من فعلا در مراحل اولیهء تحقیق به این چند دستور ساده رسیدم:


ini_set("log_errors", 1);
ini_set("error_log", "path/error.log");
دستور اول سیستم لاگ خطای درونی php رو فعال میکنه و دستور دوم فایل مورد نظر که خطاها در اون نوشته میشن رو مشخص میکنه.

حالا در همین قدم اول بنظر من رسید که فایل مورد نظر رو کجا ذخیره کنیم و طبیعتا نکات امنیتیش مثل اینکه دسترسی مستقیم از طریق وب بهش نباشه (که البته جواب اینا و روش حل کردنشون نسبتا ساده و روشن بنظر میرسه)، و اما دیگر اینکه ممکنه پرمیشن فایلها و دایرکتوری ها طوری باشه که بصورت پیشفرض php نتونه در این فایل بنویسه و بخاطر همین به فکر افتادم که شاید اگر یک سیستمی درست کنیم و این خطاها رو بجای فایل در دیتابیس ذخیره کنیم از نظر کمتر شدن مشکلات و کاهش نیاز به دخالت دستی و تغییر کانفیگ ها بهتر باشه. هرچند شاید همون فایل بهتر باشه چون بهرحال خیلی ساده تره و شاید برای برای چنین هدف ساده و پشت پرده ای که مستقیما به کارکرد برنامه و تجربهء کاربری مربوط نمیشه ما نمیخوایم زیاد کار کنیم.

تا اینجا این درمورد خطاهای در سطح php که اولویت و قدم اول در توسعه و تست و نگهداری هر برنامه ایه.
اما درمورد خطاهای در سطح خود اپلیکیشن (برنامهء خودمون)، یه راه ساده فکر میکنم این باشه که خطاهای خود برنامه رو هم توسط تابع error_log به لاگ خطای php بفرستیم (البته طبیعتا با فرمتی که در لاگ خطا از خطاهای php براحتی قابل تمیز باشه).

راستی سیستم لاگ خطا میتونه موقع روی دادن خطاها برای ادمین یا مسئول سیستم ایمیل اطلاع رسانی هم بفرسته یا حتی SMS بفرسته. البته لزوما این کار رو برای همه نوع و همه سطح از خطاها و هشدارها انجام نمیدیم، بخصوص که ممکنه منجر به ارسال تعداد بیش از حد پیام و ایجاد آزار و مشکل بشه.

منتظر نظرات و تجربیات شما هستم :چشمک:

freeman99
یک شنبه 17 اسفند 1393, 22:39 عصر
ضمنا فعلا میخوام برای برنامهء خودم یه سیستم لاگ خطای ساده درست کنم و زیاد نمیخوام در سطح مفصل و سفارشی کار کنم. پس هدف من شخصا اینه که زیاد پیچیدش نکنیم و کار زیادی نبره، ولی البته اگر اطلاعات و تجربیات یا ایده های خوبی دارید حالا به هر شکلی و از نوع مفصل و سفارشی هم بود میتونید در این تاپیک بیان کنید تا با این جنبه از اصول برنامه نویسی که ظاهرا زیاد بهش پرداخته نمیشه و اکثرا مورد غفلت/اهمال واقع میشه بیشتر آشنا بشیم.

MH.S.dev
یک شنبه 17 اسفند 1393, 23:16 عصر
بحث خوبیه ادامه بده:چشمک: فقط خواهشا مثل بحث های قبل جنجال نشه!
یک مورد دیگه هم هست که اگه بشه خطاها و مشکلاتی که در سمت سرور پیش میاد،مثل قطعی، افزایش حافظه رم و موارد دیگه رو به این اضافه کرد خیلی خوب میشه.

prans.info
دوشنبه 18 اسفند 1393, 01:31 صبح
من یک فانکشن برای نشون دادن خطا ها دارم به اسم nook و این فانکشن اینطوری هست :


function nook ($text) {
echo ($text==''?'<div class="nook">خطایی در اجرای عملیات رخ داد</div>':'<div class="nook">'.$text.'</div>');
}

خب حالا میشه اینو اینطوری نوشت :


function nook ($text) {
if ($text==''){
$text = 'خطایی در اجرای عملیات رخ داد';
//ارسال ایمیل یا اس ام اس و ثبت ارور ناشناخته ...
}else{
//ثبت ارور
}
echo '<div class="nook">'.$text.'</div>';
}

وقتی تکس رو نفرستی مثل : nook () می نویسه خطایی در اجرای عملیات رخ داد و این یعنی یک مشکل تقریبا ناشناخته و ارور ثبت و ایمیل ارسال میشه
در واقع هم با اینکار ارور هات رو ثبت می کنی هم به کاربر پیام میدی

freeman99
دوشنبه 18 اسفند 1393, 23:26 عصر
چی شد دیگه کسی نظر و تجربه ای نداره؟
شاید اکثرا برنامه هاتون بدون این حساب و تشکیلات بوده تاحالا؟
حداقل یه نظری میدادید که آیا این مسئله رو رعایت میکنید یا نه، که یه آمار و دید کلی در مورد وضعیت این موارد بدست بیاد.

freeman99
پنج شنبه 21 اسفند 1393, 22:49 عصر
تا اینجا من کدم رو اینطوری نوشتم:

متغییرهای کانفیگش به این شکله:


$log_errors=E_ALL;//set to E_ERROR, E_ALL, E_ERROR|E_WARNING, etc. set to false/0 to disable error logging

$error_log_file='log/error_log.txt';
متغییر log_errors یا 0/false هست که در این صورت لاگ کردن پیامهای خطا در فایل خاموشه، یا با ثابت های تعیین شده PHP برای سطح خطای گزارش شده بهش مقدار میدیم که در نتیجه سیستم لاگینگ فعال میشه و اون نوع خطاها در فایل لاگ میشن.

متغییر error_log_file هم که فایل لاگ رو مشخص میکنه.

بقیهء کد به این شکله:


if($log_errors) {
error_reporting($log_errors);
ini_set('log_errors', 1);
ini_set('error_log', $error_log_file);
if(file_exists($error_log_file)) {
if(!is_writable($error_log_file)) echo func::tr('Warning: Error log file not writable!', true);
}
else if(!is_writable(dirname($error_log_file))) echo func::tr('Warning: Error log directory not writable!', true);
}
یه چیزی که خودم اضافه کردم اینه که چک میکنم فایل لاگ وجود داره یا نه، اگر وجود داشت چک میکنم که قابل نوشتن هست یا نه (پرمیشن های لازم ممکنه وجود نداشته باشن)، اگر قابل نوشتن نبود یک پیام هشدار چاپ میکنه که متوجه این قضیه بشیم.
در حالتی که فایل لاگ از قبل وجود نداشت، یعنی باید ایجاد بشه، و این در سیستمهای لینوکس نیازمند مجوز نوشتن برای دایرکتوری مربوطه است، پس چک میکنیم که دایرکتوری قابل نوشتن باشه، اگر نبود یک پیام هشدار چاپ میکنیم.

خب فکر کنم همین کافی باشه. هرچند من دوست ندارم برنامه نیاز به دخالتهای دستی و تغییر مجوز دایرکتوری های مختلف داشته باشه، دوست دارم راحت نصب بشه، ولی چون سیستم لاگ اونقدرها هم جزو موارد حیاتی نیست و فعلا نمیخوام زیاد روش وقت و انرژی صرف کنم، فعلا در همین حد فایل و استفاده فقط از امکانات آمادهء PHP بنظرم کافیه، وگرنه باید یک سیستمی درست میکردم که بتونه خطاها رو در دیتابیس هم ذخیره کنه.

نظری نکته ای چیزی؟ :متفکر:

H:Shojaei
پنج شنبه 21 اسفند 1393, 23:59 عصر
چی شد دیگه کسی نظر و تجربه ای نداره؟
شاید اکثرا برنامه هاتون بدون این حساب و تشکیلات بوده تاحالا؟
حداقل یه نظری میدادید که آیا این مسئله رو رعایت میکنید یا نه، که یه آمار و دید کلی در مورد وضعیت این موارد بدست بیاد.
من اسمشو نمیدونستم ولی همیشه به این فکر میکردم که تو کلاس کار با دیتابیس بیام و خطاهای احتمالی رو تو یه تیبل ذخیره کنم و بررسی کنم... ولی به این که تو هر سطحی خطا رخ بده فکر نکرده بودم...
واقعا نیاز هر برنامه ای هست این مورد...
ممنون...

freeman99
شنبه 23 اسفند 1393, 20:58 عصر
همیشه موقع تست و توسعه این کدها رو ابتدای همهء اسکریپت ها باید داشت:

error_reporting(E_ALL);
ini_set('display_errors', '1');
بعد این error logging رو هم باید فعال کرد.

من الان به یک باگی در برنامم پی بردم که بدون اینکه error logging داشته باشم احتمال داشت متوجهش نشم، چون پیام خطا بعد از تگ ‎</html>‎ آخر صفحه چاپ میشد و در مرورگر دیده نمیشد و بخاطر همین تاحالا متوجهش این باگ نشده بودم. ولی چون error logging فعال داشتم دیدم یه پیام خطا توی فایل لاگ تازگی ثبت شده، دقت کردم و علتش رو دنبال کردم دیدم بله یه باگی یجایی وجود داشته!
این تجربه اهمیت error logging رو نه تنها برای بعد از راه اندازی برنامه روی وب، بلکه حتی موقع توسعه و تست که برنامه فقط زیر دست خودمون هست و دائم بالای سرش هستیم نشون میده.

freeman99
شنبه 23 اسفند 1393, 21:22 عصر
من یک فانکشن برای نشون دادن خطا ها دارم به اسم nook و این فانکشن اینطوری هست :
...
وقتی تکس رو نفرستی مثل : nook () می نویسه خطایی در اجرای عملیات رخ داد و این یعنی یک مشکل تقریبا ناشناخته و ارور ثبت و ایمیل ارسال میشه
در واقع هم با اینکار ارور هات رو ثبت می کنی هم به کاربر پیام میدی
اگر بخوایم کاری بکنیم مثل ارسال ایمیل، باید هوشمندتر و حساب شده تر باشه و امکان کانفیگ مربوطه رو هم داشته باشه.
چون فرضا اگر برنامه رو بذاریم روی وب و برنامه جایی باگی داشته باشه یا بعلت شرایط خاصی که بعدا پیش میاد (ممکنه شرایط و مشکلی در خارج از برنامهء ما هم باعثش بشه)، بعد سایت ترافیک قابل توجهی هم داشته باشه، اونوقت زرت و زرت ایمیل ارسال نشه، چون ممکنه تعداد زیادی ایمیل ارسال کنه و این میتونه از جهات مختلف مشکل ساز بشه. پس باید مثلا جوری باشه که هوشمند عمل کنه و از ارسال تعداد زیادی ایمیل در فاصلهء زمانی کوتاه خودداری کنه. من در برنامه خودم هرجا که به هر علتی ایمیل ارسال میشه، براش محدودیت هایی و امکان کانفیگ منعطف اونا رو قرار دادم به همین خاطر.