الانتقال إلى المحتوى
البنية التحتية لتقنية المعلومات

لماذا نرسل سجلات الحاويات إلى stdout وليس إلى ملفات

إعادة بناء عادية لحاوية nginx محت أدلة لم نكن نعرف أننا سنحتاجها. الإصلاح كان سطرين فقط، لكن اكتشاف الحاجة إليه أخذ وقتًا أطول مما ينبغي.

H
Hamze Zare Nasiri
15 سبتمبر 2026
لماذا نرسل سجلات الحاويات إلى stdout وليس إلى ملفات

الأسبوع الماضي، محت إعادة بناء روتينية لحاوية nginx أدلة لم نكن نعرف أننا سنحتاجها. الإصلاح كان سطرين فقط، لكن اكتشاف الحاجة إليه أخذ وقتًا أطول مما ينبغي.

ما الذي لاحظناه

كنا نراجع أرقام Google Analytics لنتابع الزيارات العضوية، فلفت نظرنا شيء غير طبيعي: قرابة ربع جلسات قناة "Direct" كانت تهبط على /customer/login?returnTo=/payment/<plan>/<period>، وعلى كل خطط التسعير التي نبيعها تقريبًا، لا على خطتين أو ثلاث. البصمة نفسها في كل مرة: متصفح غير معروف، جهاز مكتبي، بلد واحد بعينه. ولا أي تفاعل في أي جلسة منها.

هذا ليس عميلًا يتصفح الخطط. هذا سكربت يمرّ على كل رابط دفع وجده، وعلى الأرجح جمعها مباشرة من صفحة الأسعار عندنا.

الأدلة كانت قد اختفت

ذهبنا إلى سجل الوصول في nginx لنعرف عنوان IP المصدر، فلم نجد شيئًا. كانت الحاوية قد أُعيد بناؤها قبل أيام لإصلاح لا علاقة له بالأمر، وكان access_log يكتب إلى ملف داخل الحاوية بدل stdout، فمسحته إعادة البناء بالكامل. أمر docker logs لم يُظهر شيئًا، لأنه لم يكن هناك ما يُكتب على stdout أصلًا. أما خط نقل السجلات الذي كان يعمل عندنا بالفعل ويرسل مخرجات الحاويات إلى مخزن سجلات مركزي، فلم يرَ سطرًا واحدًا من هذا كله، لأنه لا يلتقط إلا ما تكتبه الحاويات على stdout وstderr.

عنوان IP الخاص بالبرنامج الآلي ضاع، ولا سبيل لاسترجاعه الآن.

الإصلاح

access_log /dev/stdout main;
error_log /dev/stderr warn;

يتعامل nginx مع /dev/stdout و/dev/stderr كملفات عادية يكتب فيها، فلا حاجة لأي تكامل خاص. أسطر السجل نفسها التي كانت تُحفظ في ملف صارت تمر عبر المخرج القياسي للحاوية، وهو ما كان نظام نقل السجلات يقرؤه أصلًا من كل حاوية أخرى نشغّلها.

الدرس الحقيقي

البرنامج الآلي نفسه لم يكن مثيرًا للاهتمام. المرور البطيء على روابط أسعار منشورة للعموم ليس تهديدًا كبيرًا في حد ذاته. المهم أن منظومة المراقبة عندنا بدت مكتملة، بينما كانت حاوية واحدة خارجها بصمت، لأن إعداداتها الأساسية ظلت تكتب السجلات إلى ملفات كما كان يحدث على خادم فعلي قبل عشر سنوات. إن أُعيد بناء تلك الحاوية الشهر القادم، فسنرى هذه المرة ما تفعله أيًّا كان.

إن كنت تشغّل nginx داخل Docker، فراجع توجيهَي access_log وerror_log عندك. منظومة المراقبة لا تكتمل إلا بقدر الحاويات التي تكتب إليها فعلًا.

كل خدماتنا، ومنها نظام إدارة المحتوى الذي ينشر هذه المقالة، تعمل كحاويات على خوادم نديرها بأنفسنا. شرحنا ذلك الإعداد في مقالة فان‌بينو CMS على Docker ومستضاف ذاتيًا.

نقل السجلات إلى stdout هو ما كشف لنا لاحقًا حركة بوت كاملة؛ اقرأ كيف كان ربع زيارات Direct بوتًا.

الأسئلة الشائعة

لماذا يجب أن يكتب nginx داخل Docker سجلاته إلى stdout؟

لأن أدوات سجلات الحاويات لا ترى إلا stdout وstderr. إذا أشار access_log إلى ملف داخل الحاوية فلن يُظهر docker logs شيئاً، ولن تجمعه أدوات شحن السجلات، وسيُمحى الملف عند إعادة البناء. كتابة access_log إلى /dev/stdout وerror_log إلى /dev/stderr ترسل الأسطر نفسها عبر مسار سجلات الحاويات المعتاد.

كيف أرسل سجلات nginx إلى stdout؟

ضع توجيهين في إعدادات nginx: access_log /dev/stdout main; وerror_log /dev/stderr warn;. يتعامل nginx مع /dev/stdout و/dev/stderr كملفات عادية يكتب إليها، فلا حاجة إلى إضافة أو تكامل خاص، وسيرى docker logs وأي أداة تقرأ مخرجات الحاوية كل الطلبات.

ماذا يحدث لملفات السجلات داخل الحاوية عند إعادة بنائها؟

تضيع. الملف المكتوب في نظام ملفات الحاوية يختفي عند إعادة إنشائها ما لم يكن على وحدة تخزين مركّبة. وبهذه الطريقة فقدنا عنوان IP لروبوت كان يمرّ على كل روابط الدفع في صفحة الأسعار لدينا، إذ أُعيد بناء الحاوية قبل أيام لإصلاح لا علاقة له.

هل تحتاج إلى بنية تشغيل إنتاجية مضبوطة؟

نبني ونشغّل منظومة Docker وnginx والمراقبة التي تعمل عليها منتجاتنا بأحمال حقيقية، ويمكننا فعل الشيء نفسه لمنتجك.

تعرّف على خدمة DevOps

شارك هذا المقال