التسجيل في Spring Boot
التسجيل في Spring Boot
كل تطبيق Spring Boot في مرحلة الإنتاج يُولّد مخرجات تسجيل. إتقان هذه المخرجات — منظّمة، بمستوى تفصيل مناسب، موجَّهة إلى الوجهة الصحيحة — هو ما يُفرّق بين تطبيق تستطيع تشغيله وتطبيق لا تفعل سوى التخمين حين تسوء الأمور. يتناول هذا الدرس مكدّس التسجيل الافتراضي الذي يمنحك إياه Spring Boot، وكيفية عمل مستويات التسجيل، وكيفية ضبط كل شيء عبر application.properties أو application.yml.
المكدّس الافتراضي: SLF4J + Logback
يستخدم Spring Boot SLF4J واجهةً للتسجيل (logging facade) وLogback التنفيذَ الفعلي خلفها. يصلان معًا إلى مسار الفئات تلقائيًا عند تضمين spring-boot-starter (الذي يُعدّ تبعيةً انتقاليةً لكل starter آخر). لا تحتاج إلى إضافة أي تبعية تسجيل يدويًا في معظم التطبيقات.
org.slf4j.Logger) عن وقت التشغيل الذي ينتج المخرجات الفعلية. يمكنك استبدال Logback بـ Log4j 2 أو java.util.logging لاحقًا دون لمس سطر واحد من كود تطبيقك. يستخدم Spring Boot هذه الواجهة نفسها داخليًا، لذا تتدفق جميع سجلات الإطار عبر نفس خط الأنابيب.
يأتي Spring Boot أيضًا مع ملفات JAR جسرية (jcl-over-slf4j وlog4j-to-slf4j وjul-to-slf4j) تُحوّل مسارات التسجيل القديمة إلى خط أنابيب SLF4J. هذا يعني أن المكتبات الخارجية التي تستخدم Commons Logging أو Log4j 1.x أو java.util.logging تنتهي جميعها في Logback تلقائيًا.
الحصول على Logger
أعلن عن logger كحقل private static final في كل فئة. النمط المتعارف عليه مع SLF4J هو:
محددات {} هي صيغة التسجيل المُعلمَّة في SLF4J. تحدث عملية دمج السلسلة النصية فقط إذا كان مستوى التسجيل مُفعَّلًا، لذا لا تكلفة أداء لاستدعاء log.debug(...) حين يكون تسجيل debug معطلًا.
@Slf4j من Lombok للتخلص من الكود الزائد. إضافة @Slf4j من org.projectlombok:lombok يُولّد حقل private static final Logger log = LoggerFactory.getLogger(...); وقت الترجمة، مما يُبقي فئتك نظيفة. الحقل المُولَّد مطابق تمامًا لما ستكتبه يدويًا.
مستويات التسجيل
يُعرّف SLF4J خمسة مستويات بترتيب تصاعدي للخطورة:
- TRACE — أدق مستوى تفصيلي؛ يشمل عادةً استدعاءات الطرق المفردة أو تكرارات الحلقات أو إطارات البروتوكول منخفضة المستوى. غالبًا معطّل في الإنتاج.
- DEBUG — معلومات تشخيصية مفيدة أثناء التطوير واستكشاف الأخطاء. عادةً معطّل في الإنتاج أو مُفعَّل لحزم محددة فقط.
- INFO — أحداث التشغيل العادية: بدء التطبيق، استقبال طلب، تنفيذ طلب. المستوى الافتراضي لكودك.
- WARN — حدث شيء غير متوقع لكن التطبيق تعافى: نجاح إعادة المحاولة، استدعاء واجهة برمجية مُهملة، تعيين قيمة إعداد افتراضية.
- ERROR — فشل يستدعي الانتباه: استثناء غير معالج، فشل استدعاء خارجي، كشف تلف في البيانات.
حين تضبط logger على مستوى معين، يكون ذلك المستوى وكل المستويات الأعلى مُفعَّلة. ضبط حزمة على DEBUG يُفعّل DEBUG و INFO و WARN و ERROR لكل فئة في تلك الحزمة.
الإعدادات الافتراضية في Spring Boot
بشكل افتراضي، يُهيّئ Spring Boot:
- المستوى الجذري:
INFO— كود تطبيقك وجميع المكتبات الخارجية تُسجّل عند INFO وما فوق. - Spring الداخلية:
INFOلحزمorg.springframework. - Hibernate SQL:
WARN— لا يُسجَّل SQL المُولَّد ما لم تُفعّله صراحةً. - مخرج وحدة التحكم: مخرج ملوّن بالطابع الزمني ومستوى التسجيل والخيط واسم الـ logger والرسالة.
تبدو صيغة وحدة التحكم الافتراضية هكذا:
ضبط مستويات التسجيل في application.properties
الطريقة الأساسية لتغيير مستويات التسجيل هي عبر application.properties (أو application.yml) باستخدام البادئة logging.level. متبوعةً بالاسم المؤهل كليًا للحزمة أو الفئة:
org.hibernate.orm.jdbc.bind=TRACE مُفعَّلًا في الإنتاج أبدًا. يُسجّل هذا الإعداد كل قيمة معاملة مُرتبطة، مما يكشف عن كلمات مرور وبيانات شخصية ومعلومات حساسة في ملفات السجل. استخدمه فقط أثناء التطوير المحلي لتصحيح مشاكل الاستعلامات، ثم احذفه قبل commit.
ضبط ملف السجل
افتراضيًا، يُسجّل Spring Boot فقط في وحدة التحكم. للكتابة أيضًا في ملف، اضبط إحدى الخصائص التالية:
يطبّق Spring Boot تلقائيًا سياسة التدوير (rolling policy) عند الكتابة في ملف: تُدوَّر ملفات السجل عند وصولها إلى 10 ميغابايت، وتُحتفظ بما يصل إلى 7 أيام من السجل افتراضيًا. يمكنك ضبط الاثنين:
تخصيص نمط المخرجات
نمطا وحدة التحكم والملف قابلان للتخصيص أيضًا دون الحاجة للمس أي ملف XML:
التسجيل المُهيكَل (JSON) — Spring Boot 3.4 فأحدث
من Spring Boot 3.4، التسجيل المُهيكَل بصيغة JSON مدمج ويتطلب خاصية واحدة فقط:
يُنتج هذا مخرجات JSON وفق مخطط Elastic Common Schema (ECS) في وحدة التحكم — مثالي لمنصات تجميع السجلات مثل OpenSearch أو Elasticsearch أو Loki. الصيغ البديلة هي logstash وgelf. كل حدث تسجيل هو كائن JSON واحد، مما يجعله قابلًا للتحليل بسهولة من قِبَل أي مجمّع سجلات.
الملف logback-spring.xml الكامل — حين تحتاج تحكمًا أعمق
إذا لم تكفِ application.properties — مُخرجات مخصصة، ملفات متعددة، أنماط مختلفة لكل بيئة — أنشئ src/main/resources/logback-spring.xml. يكتشفه Spring Boot ويستخدمه تلقائيًا. اللاحقة -spring (مقابل logback.xml العادي) تتيح لـ Spring معالجة عناصر <springProfile>:
مجموعات التسجيل (Log Groups)
يتيح لك Spring Boot تعريف مجموعات تسجيل — أسماء مستعارة لمجموعة من الحزم — ثم التحكم في المجموعة كلها بخاصية واحدة. مجموعتان مُعرَّفتان مسبقًا: web وsql.
الخلاصة
يأتي Spring Boot مُجهَّزًا بـ SLF4J فوق Logback، مُهيَّئًا مسبقًا عند مستوى INFO مع مخرجات وحدة تحكم ملوّنة وتدوير تلقائي للملفات. تتحكم في كل شيء عبر خصائص logging.level.* وlogging.file.* وlogging.pattern.* — لا حاجة لـ XML في معظم التطبيقات. حين تحتاج مُخرجات خاصة بالبيئة أو توجيهًا دقيقًا، أنشئ ملف logback-spring.xml في src/main/resources. في الدرس القادم ستتعرف على كيفية تسريع دورة التطوير باستخدام Spring Boot DevTools مع إعادة التشغيل التلقائية والتحديث الفوري.