مستوى المقال: مبتدئ. لو عندك سيرفر واحد وبتتعامل مع لوجات لينكس لأول مرة، المقال ده مكتوب ليك بالظبط. مش محتاج تكون مهندس DevOps.
لو المساحة الفاضية في قرص سيرفرك بتقل كل أسبوع من غير ما تزوّد أي حاجة، غالبًا السبب ملف لوج واحد بيكبر بلا حدود. في آخر المقال هتعرف تخلّي السيرفر يدوّر اللوجات لوحده كل ليلة، وتقفل المشكلة دي للأبد في أقل من 10 دقايق.
المشكلة باختصار
أي تطبيق بيكتب لوج باستمرار: كل طلب، كل خطأ، كل تحذير بيتسجّل في ملف زي /var/log/app.log. الملف ده مبيوقفش لوحده. بيفضل يكبر طول ما التطبيق شغّال.
الافتراض إن عندك تطبيق بيخدم 50 ألف طلب في اليوم، وكل طلب بيسجّل سطر أو اتنين. ده بيوصل لـ 1.9 جيجابايت في اليوم بسهولة. قرص 40 جيجا هيمتلئ في أقل من 3 أسابيع. وأول ما يمتلئ، التطبيق نفسه بيقع، لأنه مش قادر يكتب ولا سطر جديد.
يعني إيه تدوير اللوجات؟ (بمثال بسيط الأول)
تخيّل حارس عقار بيكتب كل اللي بيحصل في دفتر واحد. لو عمره ما بدأ صفحة جديدة، الدفتر هيبقى كتاب ضخم، والدُرج اللي بيحطه فيه هيمتلئ، ومحدش هيقدر يلاقي حدث قديم وسط آلاف الصفحات المتلزقة.
الحل اللي أي إدارة منظمة بتعمله بسيط: كل ليلة نبدأ دفتر جديد، نكتب على الدفتر القديم تاريخه ونحطه مضغوط في الأرشيف، وأي دفتر أقدم من أسبوعين نتخلّص منه. كده الدُرج بيفضل نضيف، واللوج القريب لسه موجود لو احتجته.
ده بالظبط اللي بيعمله logrotate: أداة موجودة أصلاً في أغلب توزيعات لينكس، بتشتغل مرة كل يوم عن طريق cron، وبتطبّق نفس المنطق على ملفات اللوج بدل الدفاتر.
إزاي بيشتغل فعلاً (الشرح الدقيق)
logrotate بيقرأ قواعد من /etc/logrotate.conf ومن ملفات صغيرة جوه /etc/logrotate.d/. لكل ملف لوج، القاعدة بتحدد: امتى ندوّر (يومي، أسبوعي، أو عند حجم معيّن)، كام نسخة نحتفظ بيها، ونضغط ولا لأ.
لما شرط القاعدة يتحقق، logrotate بيعمل الخطوات دي بالترتيب: يعيد تسمية app.log إلى app.log.1، يفتح ملف app.log جديد فاضي، يضغط النسخة القديمة بـ gzip (بتوفّر حوالي 90% من الحجم لأن النص بيتضغط كويس جدًا)، وأخيرًا يمسح أقدم نسخة لو عدّينا حد الاحتفاظ.
نقطة خفية لازم تعرفها: التطبيق لازم يعرف إن الملف اتغيّر
هنا بيقع أغلب المبتدئين. معظم التطبيقات بتفتح ملف اللوج مرة واحدة وبتفضل ماسكاه في الذاكرة. لما logrotate يعيد تسمية الملف، التطبيق بيفضل بيكتب في الملف القديم (اللي اتسمى دلوقتي app.log.1)، وملف app.log الجديد بيفضل فاضي للأبد. النتيجة: القرص لسه بيمتلئ وانت فاكر إنك حليت المشكلة.
الحل له طريقتين. الأولى نبعت للتطبيق إشارة يقفل الملف ويفتحه من جديد بعد التدوير (postrotate). الثانية، الأسهل للمبتدئ، نستخدم copytruncate: بينسخ محتوى الملف ثم يفرّغ الملف الأصلي في مكانه من غير ما يعيد تسميته، فالتطبيق يفضل بيكتب في نفس الملف بشكل طبيعي.
الخطوات: فعّلها في أقل من 10 دقايق
هنفترض إن تطبيقك بيكتب لوجاته في /var/log/myapp/. اعمل قاعدة جديدة بالأمر ده: