اقرأ سجلات سيرفرك وشخّص العطل في أقل من 5 دقائق

دليل عملي لقراءة access log و error log: وين تلقاها، كيف تفكّك السطر حقلاً حقلاً، وعشرة أنماط أخطاء شائعة مع أوامر grep وawk وtail جاهزة تنسخها.
وين تلقى سجلات السيرفر وكيف تبدأ التشخيص
لما يوقف موقعك أو يصير بطيء، أول مكان تروح له هو السجلات، لا لوحة التحكم ولا التخمين. السيرفر يكتب كل طلب وكل خطأ في ملفين أساسيين: access log يسجّل كل طلب HTTP وصل للسيرفر، وerror log يسجّل كل ما فشل داخلياً. على Apache في cPanel تلقى سجلات الوصول لكل مجال في /home/USER/access-logs/ وسجل الأخطاء في /home/USER/logs/، والسجل العام في /usr/local/apache/logs/access_log. على Nginx المسار الافتراضي /var/log/nginx/access.log و/var/log/nginx/error.log، وأخطاء PHP لها سجل منفصل غالباً في /home/USER/logs/php_errors.log أو حسب قيمة error_log في php.ini.
القاعدة اللي توفّر عليك ساعات: افتح error log أولاً لتعرف ماذا فشل، وافتح access log ثانياً لتعرف من طلب ومتى. 80% من مشاكل المواقع تنكشف من السطر الأخير في error log وحده. الأمر الأسرع لمتابعة الأخطاء لحظياً هو tail -f على ملف الخطأ، يخليك تشوف كل خطأ جديد وهو يُكتب مباشرة. في هذا الدليل بنفكّك سطر access log وسطر error log كلمة كلمة، ونمرّ على أوامر جاهزة تنسخها، وأشهر عشرة أنماط أخطاء وتشخيص كل واحد. على سيرفرات كلاود في الرياض تصلك هذي السجلات بزمن استجابة قريب من 8ms، فتقرأها وأنت متصل من داخل المملكة بلا تأخير خارجي يقارب 120ms.
تشريح سطر access log
سطر access log الافتراضي يتبع صيغة Combined Log Format، وهي نفسها في Apache وNginx تقريباً. خذ هذا المثال الحقيقي:
203.0.113.45 - - [14/Aug/2026:09:23:11 +0300] "GET /api/orders?id=52 HTTP/1.1" 200 1843 "https://cloud.net.sa/" "Mozilla/5.0"
نفكّكه حقلاً حقلاً حتى تقرأ أي سطر بثقة:
- 203.0.113.45 عنوان IP لصاحب الطلب. لو تكرر آلاف المرات في دقيقة فأنت أمام هجوم أو بوت.
- [14/Aug/2026:09:23:11 +0300] الوقت بتوقيت السيرفر، والفرق 0300+ يعني توقيت الرياض. انتبه للفرق لو سيرفرك بتوقيت UTC.
- "GET /api/orders?id=52 HTTP/1.1" نوع الطلب والمسار المطلوب. هنا تشوف بالضبط أي رابط ضُرب.
- 200 رمز حالة HTTP، وهو أهم رقم في السطر. 200 يعني نجاح، و500 يعني فشل داخلي.
- 1843 حجم الرد بالبايت. لو صفر مع رمز نجاح فغالباً الاتصال انقطع.
- Referer وUser-Agent مصدر الزيارة ونوع المتصفح أو البوت.
رموز الحالة تنقسم إلى عائلات: عائلة 2xx نجاح، وعائلة 3xx إعادة توجيه، وعائلة 4xx خطأ من العميل مثل 404 صفحة غير موجودة و403 ممنوع و429 طلبات كثيرة، وعائلة 5xx خطأ من السيرفر مثل 500 و502 و503 و504. أي قفزة مفاجئة في عدد 5xx تعني أن مشكلة عندك أنت لا عند الزائر، وهذي أول إشارة تلاحقها.
تشريح سطر error log
error log أقل انتظاماً من access log لأنه يكتب رسائل من مصادر مختلفة، لكن كل سطر يحمل ثلاث معلومات ثمينة: الوقت، ومستوى الخطورة، والرسالة. مثال من Apache:
[Thu Aug 14 09:23:11 2026] [error] [client 203.0.113.45] PHP Fatal error: Uncaught Error: Call to undefined function get_orders() in /home/user/app/index.php:88
هنا تقرأ فوراً أن الخطأ من نوع Fatal يعني أوقف التنفيذ، وأن الملف والسطر المذنب هو index.php سطر 88. مستويات الخطورة ترتّب أولوياتك: Fatal وerror توقف الصفحة وتستحق تدخلاً فورياً، وwarning وnotice ما توقف التنفيذ لكنها تكشف كوداً ضعيفاً، وعلى سيرفر مزدحم قد تولّد ملايين الأسطر شهرياً وتملأ القرص. رأينا حسابات يمتلئ فيها سجل الأخطاء بمعدل يتجاوز 2GB في اليوم بسبب notice متكرر لم ينتبه له المطوّر.
الفرق بين خطأ التطبيق وخطأ السيرفر
ميّز دائماً: لو الرسالة تبدأ بـ PHP أو تذكر ملف كودك فالمشكلة في التطبيق وحلّها عند مطوّرك. أما لو الرسالة من nginx أو apache نفسه مثل connect() failed (111: Connection refused) while connecting to upstream فالمشكلة في طبقة السيرفر أو الخدمة الخلفية مثل PHP-FPM المتوقفة.
أوامر جاهزة تنسخها لقراءة السجلات بسرعة
الأدوات هنا كلها موجودة في أي سيرفر Linux بلا تثبيت. احفظ هذي الخمسة وستغطي 90% من احتياجك اليومي:
- tail -f error_log يعرض الأخطاء وهي تُكتب لحظياً، مثالي وأنت تعيد إنتاج المشكلة.
- tail -n 100 error_log يعرض آخر مئة سطر، بداية أي تشخيص.
- grep " 500 " access_log يصفّي كل الطلبات اللي رجعت خطأ 500 فقط.
- grep "203.0.113.45" access_log يتتبع كل ما فعله IP معيّن.
- awk '{print $9}' access_log | sort | uniq -c | sort -rn يعطيك جدول توزيع رموز الحالة مرتباً تنازلياً.
الأمر الأخير هو سلاحك الأقوى: في ثانية واحدة يقول لك كم طلب رجع 200 وكم رجع 404 وكم رجع 500. لو شفت 4x700 مثلاً بجانب 404 فأنت أمام روابط مكسورة كثيرة أو بوت يفحص مسارات وهمية، ولمعرفة أكثر IP إزعاجاً استخدم awk '{print $1}' access_log | sort | uniq -c | sort -rn | head، يطلع لك أعلى عشرة عناوين طلباً، وغالباً أول سطر هو مصدر الحمل أو الهجوم. كل هذي الأوامر تشتغل مباشرة على سيرفر سعودي عبر SSH بلا وسيط خارجي.
عشرة أنماط شائعة وكيف تشخّصها
قفزة في رموز 500
لو زادت أخطاء 500 فجأة بعد نشر تحديث، فالسبب دايماً كود جديد. افتح error log على طول، وأول سطر Fatal بيعطيك الملف والسطر. أكثر من 60% من أعطال ما بعد النشر تنكشف من أول سطر خطأ.
502 و504 من upstream
رمز 502 أو 504 مع رسالة upstream يعني أن الويب سيرفر شغّال لكن PHP-FPM أو الخدمة الخلفية توقفت أو تأخرت. افحص حالة الخدمة وذاكرتها، وغالباً الحل إعادة تشغيل PHP-FPM أو رفع مهلة الانتظار.
موجة 404 لمسارات غريبة
لو شفت مئات طلبات 404 لمسارات مثل wp-login و.env وphpmyadmin وموقعك أصلاً ما يستخدمها، فهذا بوت يفحص ثغرات معروفة. سجّل الـ IP واحظره على مستوى الجدار الناري.
403 على ملفات يفترض أنها متاحة
خطأ 403 غالباً مشكلة صلاحيات ملفات أو قاعدة في htaccess. تأكد أن صلاحيات المجلدات 755 والملفات 644 وأن المالك صحيح.
بطء بلا خطأ
أحياناً الموقع بطيء ورموز الحالة كلها 200. هنا أضف حقل زمن الاستجابة في صيغة السجل، ثم رتّب أبطأ الطلبات. أي طلب يتجاوز ثانية واحدة يستحق مراجعة، والاستعلامات غير المفهرسة في قاعدة البيانات هي المتهم الأول في 70% من حالات البطء.
خطأ 429 أو حجب مفاجئ
رمز 429 يعني أن حداً لعدد الطلبات ضرب، وغالباً بسبب سكربت عندك يستدعي API بلا توقف، أو زائر واحد يفتح مئات الطلبات في الثانية. راجع أعلى IP في access log وقارنه بالوقت، فلو كل الطلبات من عنوان واحد خلال ثوانٍ فالمصدر واضح.
ردود فارغة بحجم صفر
لو شفت رمز 200 لكن حجم الرد صفر بايت متكرراً، فغالباً السكربت يموت في منتصف التنفيذ بسبب نفاد الذاكرة أو مهلة PHP. افتح php_errors.log وابحث عن رسالة memory size exhausted أو maximum execution time، وهذي وحدها تكشف قرابة ثلث حالات الصفحة البيضاء.
أدوات متقدمة تسرّع القراءة
بعد ما تتقن grep وawk وtail، ثلاث أدوات ترفع سرعتك أكثر. الأولى grep -c يعطيك عدد التطابقات فقط بدل عرضها، مفيد لعدّ أخطاء 500 خلال دقيقة. الثانية zcat يقرأ السجلات المضغوطة بامتداد gz دون فك ضغطها يدوياً، لأن السجلات القديمة تُضغط تلقائياً بعد التدوير وتوفّر حتى 90% من المساحة. الثالثة الجمع بين الأدوات في أنبوب واحد، مثل تمرير مخرجات grep إلى awk ثم إلى sort، فتبني تقريراً كاملاً في سطر واحد، ولمن يريد لوحة بصرية جاهزة، أدوات مثل GoAccess تقرأ نفس ملف access log وتبني تقريراً حياً بأكثر الصفحات زيارة ورموز الحالة والدول خلال ثوانٍ، وتشتغل محلياً على سيرفرك دون إرسال بياناتك لأي طرف خارجي.
اربط السجلات بالأمن والأداء
السجلات ليست للتشخيص وقت العطل فقط، بل نظام إنذار مبكر. راقب معدل 401 و403 لاكتشاف محاولات دخول متكررة، وراقب طلبات POST المتتالية على صفحة الدخول لكشف هجمات كسر كلمة المرور. على سيرفرات كلاود يُحفظ السجل داخل المملكة، وهذا مهم للامتثال والنفاذ الوطني لأن بيانات الوصول تبقى تحت السيادة السعودية ولا تغادر لمراكز خارجية. اضبط دوران السجلات عبر logrotate حتى لا يمتلئ القرص، فسجل بلا تدوير قد يوقف السيرفر لما تمتلئ المساحة، وقد رأينا سيرفرات تتوقف بالكامل بسبب سجل تجاوز 40GB.
خلاصة عملية
ثبّت هذا الترتيب في ذهنك عند أي عطل: افتح error log واقرأ آخر سطر، حدّد إن كان الخطأ من التطبيق أو من السيرفر، ثم انتقل إلى access log لتعرف من الطلب ومتى وكم مرة. استخدم grep للتصفية وawk للإحصاء وtail للمتابعة اللحظية. مع التمرين تختصر تشخيصاً كان يأخذ ساعة إلى أقل من خمس دقائق، ومن يشغّل على بنية سعودية قريبة يقرأ سجلاته بزمن استجابة 8ms ويتصرّف قبل أن يشعر عملاؤه بالمشكلة أصلاً.
