عندما يمتلئ نظام الملفات الجذري في خادم لينكس تتوقف قواعد البيانات عن الكتابة، وتفشل ترقيات الحزم، وقد يتعذر الدخول عبر SSH. والسجلات من أكثر الأسباب شيوعاً لذلك، لأنها تكبر بهدوء حتى يأتي يوم لا تتسع فيه. يشرح هذا الدليل النظامين اللذين يديران السجلات في Debian وUbuntu، وهما سجل systemd (الـ journal) وأداة logrotate، وكيف تضع حدوداً تُبقي السجلات مفيدة دون أن تستولي على القرص.
أين توجد السجلات الآن
منذ Debian 12 (bookworm) لم تعد الحزمة rsyslog تُثبَّت افتراضياً. وتوضح ملاحظات إصدار bookworm أن الرسائل يحفظها سجل systemd بصيغة ثنائية تحت /var/log/journal وتُقرأ بالأمر journalctl. وما تزال الخوادم المرقّاة من إصدارات أقدم وتثبيتات أخرى كثيرة تشغّل rsyslog أيضاً وتكتب ملفات نصية مثل /var/log/syslog. كما تحتفظ التطبيقات، مثل خوادم الويب وPHP وقواعد البيانات، عادةً بسجلات نصية خاصة بها تحت /var/log. لذلك يوجد في الغالب نظامان يجب إدارتهما: الـ journal الذي يدير حجمه بنفسه، والملفات النصية التي تدوّرها أداة logrotate.
أولاً: اعرف ما الذي يستهلك المساحة
df -h /
sudo du -xh /var/log --max-depth=1 | sort -h | tail
journalctl --disk-usage
# space held by files that were deleted but are still open
sudo lsof +L1الأمر الأخير أهم مما يبدو؛ فإذا حذف أحدهم سجلاً كبيراً بينما ما تزال عملية ما تفتحه، فلن تتحرر المساحة حتى تغلق العملية الملف أو يُعاد تشغيلها. ويعرض lsof +L1 هذه الملفات المحذوفة المفتوحة (lsof(8)).
ضع حدوداً للـ journal
بحسب journald.conf(5) يمكن لـ journald افتراضياً أن يستخدم حتى 10% من نظام الملفات للسجلات الدائمة، ويحاول ترك 15% منه فارغاً، على ألا تتجاوز كل قيمة منهما 4G. وقد يبقى ذلك أكثر مما تريده على قرص VPS صغير، كما أن الإعداد الافتراضي لا يحذف المدخلات بحسب عمرها أبداً. ضع حدودك في ملف إضافي (drop-in) بدلاً من تعديل الملف الرئيسي:
# /etc/systemd/journald.conf.d/50-limits.conf
[Journal]
SystemMaxUse=500M
SystemKeepFree=1G
MaxRetentionSec=1month
sudo systemctl restart systemd-journald
journalctl --disk-usage- يحدد
SystemMaxUseالحجم الكلي الأقصى، ويحافظSystemKeepFreeعلى مساحة فارغة لبقية النظام، ويلتزم journald بالحدّين معاً ويأخذ الأصغر منهما. - يحذف
MaxRetentionSecملفات السجل التي تحتوي على مدخلات أقدم من المدة المحددة. وهو معطّل افتراضياً، ففعّله إذا كانت سياسة الاحتفاظ لديك تحدد مدة بقاء السجلات. - لا تُحذف إلا ملفات السجل المؤرشفة، لذا قد يبقى الاستهلاك فوق الحد لفترة قصيرة.
- القيمة الافتراضية
Storage=autoتحفظ السجل على القرص فقط إذا كان المجلد/var/log/journalموجوداً. فلا تحذف هذا المجلد لتوفير المساحة، وإلا اختفت السجلات مع كل إعادة تشغيل.
ولاستعادة المساحة فوراً نفّذ التدوير والتنظيف يدوياً (journalctl(1)):
sudo journalctl --rotate --vacuum-size=500M
sudo journalctl --vacuum-time=30daysدوّر السجلات النصية بأداة logrotate
تعيد logrotate تسمية ملفات السجل وتضغطها وتحذفها في النهاية وفق قواعد موجودة في /etc/logrotate.conf و/etc/logrotate.d/. ومعظم الحزم، مثل nginx وخوادم قواعد البيانات، تثبّت ملف قواعد خاصاً بها هناك، أما تطبيقاتك فعادةً لا تفعل. وقد تبدو قاعدة لسجلات تطبيق PHP هكذا:
# /etc/logrotate.d/myapp
/var/www/myapp/storage/logs/*.log {
daily
rotate 14
maxsize 200M
compress
delaycompress
missingok
notifempty
su www-data www-data
create 0640 www-data www-data
}وظيفة كل جزء بحسب logrotate(8):
- يحتفظ
dailyمعrotate 14بسجل أسبوعين. - يدوّر
maxsize 200Mالملف مبكراً إذا تجاوز 200 ميغابايت، لكن فقط عندما تعمل logrotate فعلاً. - يضغط
compressمعdelaycompressالملفات القديمة، ويترك أحدث ملف مدوَّر دون ضغط، مما يفيد البرامج التي ما تزال تكتب فيه. - يشغّل
suالتدوير بصلاحيات مالك المجلد، وهو ما تحتاجه logrotate عندما يكون المجلد قابلاً للكتابة من مستخدم غير الجذر. - وللبرامج التي لا تستطيع إعادة فتح ملف السجل يوجد الخيار
copytruncateالذي ينسخ الملف ثم يفرّغه في مكانه، وينبّه الدليل إلى احتمال ضياع بضعة أسطر بين الخطوتين.
اختبر القاعدة دون أي تغيير، ثم افرض التشغيل عند الحاجة:
sudo logrotate -d /etc/logrotate.d/myapp
sudo logrotate -f /etc/logrotate.d/myappويذكر الدليل أن logrotate تعمل عادةً مرة يومياً من cron أو من logrotate.timer في الأنظمة التي تستخدم systemd، وتحقق من ذلك بالأمر systemctl list-timers logrotate.timer. وإذا كان سجلٌّ ما يكبر بعدة غيغابايت في ساعات قليلة فالتشغيل اليومي بطيء جداً حتى مع maxsize؛ فأصلح مصدر التسجيل المفرط، أو شغّل logrotate بوتيرة أعلى.
سجلات الحاويات
يحفظ مشغّل التسجيل الافتراضي في Docker، وهو json-file، مخرجات الحاويات داخل مجلد بيانات Docker، والقيمة الافتراضية لخياره max-size غير محدودة (مشغّل json-file). ضع حدوداً في الملف /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": { "max-size": "10m", "max-file": "3" }
}أعد تشغيل Docker بعد ذلك، وستحتفظ الحاويات الحالية بإعداداتها القديمة حتى يُعاد إنشاؤها.
إبعاد السجلات عن قرص الجذر
في الخوادم المزدحمة ضع /var/log على نظام ملفات مستقل حتى لا تملأ موجةُ سجلات قرصَ الجذر، أو أرسل السجلات إلى خادم سجلات مركزي واحتفظ محلياً بتاريخ قصير فقط. وأياً كان اختيارك، دوّن سياسة الاحتفاظ: كم من الوقت تُحفظ سجلات التطبيقات والوصول والأمان، وأين تُحفظ. فقد تفرض سياسات الأمان وحماية البيانات لديك حدوداً دنيا وعليا.
ما الذي ينبغي فعله
- شغّل اليوم الأوامر
df -hوduعلى/var/logوjournalctl --disk-usageوlsof +L1على كل خادم. - أضف ملفاً إضافياً لإعدادات journald يحدد
SystemMaxUseوSystemKeepFree، وMaxRetentionSecإذا تطلبت سياستك ذلك. - اكتب قواعد logrotate لكل سجل تطبيق لا تديره حزمة، واختبرها بالأمر
logrotate -d. - حدّد حجم سجلات حاويات Docker بالخيارين
max-sizeوmax-file. - أنشئ تنبيهاً لاستخدام القرص قبل أن يبلغ 100%، واحتفظ بمدة احتفاظ موثّقة لكل نوع من السجلات.
المصادر
- manpages.debian.org/trixie/systemd/journald.conf.5.en.html
- manpages.debian.org/trixie/systemd/journalctl.1.en.html
- manpages.debian.org/trixie/logrotate/logrotate.8.en.html
- manpages.debian.org/trixie/lsof/lsof.8.en.html
- debian.org/releases/bookworm/amd64/release-notes/ch-information.en.html
- docs.docker.com/engine/logging/drivers/json-file
Comments
0 total · 0 threads