إدارة السجلات (Logs) في الخدمات المصغرة (Microservices): دليل شامل لتسجيل فعال ومنظم
مقدمة إلى عالم السجلات في الخدمات المصغرة
تُعد السجلات (Logs) جزءًا لا يتجزأ من أي نظام برمجي، وتكتسب أهمية بالغة في بيئات الخدمات المصغرة (Microservices) المعقدة. سواء كنت في بداية تطوير نظام جديد أو تدير بيئة إنتاج واسعة النطاق، ستجد نفسك دائمًا بحاجة ماسة إلى ملفات السجلات. إنها الملاذ الأول للمطورين عند حدوث خطأ غير متوقع أو عدم عمل شيء كما هو متوقع.
إن تسجيل المعلومات الصحيحة بالطريقة الصحيحة يسهل حياة المطورين بشكل كبير، ويقلل من الوقت والجهد المبذول في استكشاف الأخطاء وإصلاحها (Debugging). لتحقيق أقصى استفادة من سجلاتك، يجب أن تفهم بوضوح ما يجب تسجيله وكيفية تسجيله. في هذا المقال، سنستعرض بعض المبادئ الأساسية للتسجيل الفعال التي ستساعدك على استغلال سجلاتك إلى أقصى حد ممكن.
ماذا يجب أن نسجل وكيف تعمل عملية التسجيل؟
لنبدأ بمثال عملي من نظام تجارة إلكترونية، ونركز على عملية التسجيل في خدمة إدارة الطلبات (Order Management Service - OMS) الخاصة به. لنفترض أن طلب عميل قد فشل بسبب خطأ صادر من خدمة إدارة المخزون (Inventory Management Service - IMS)، وهي خدمة فرعية تعتمد عليها خدمة OMS للتحقق من توفر المنتج.
افترض أن خدمة OMS قد قبلت الطلب بالفعل، ولكن أثناء خطوة التحقق النهائية، أعادت خدمة IMS الخطأ التالي لأن المنتج لم يعد متاحًا في المخزون:
404 Product Not Available
ماذا نسجل؟
في الوضع الطبيعي، قد تقوم بتسجيل الخطأ بهذه الطريقة:
log.error("Exception in fetching product information - {}", ex.getResponseBodyAsString())
سينتج عن هذا سجل بالتنسيق التالي:
[ 2020 -09 -27 T18: 54 : 41 , 500 + 0530 ]-[ERROR]-[InventoryValidator]-[ 13 ] Exception in fetching product information - Product Not Available
هل تلاحظ قلة المعلومات المتاحة في هذا السجل؟ سجل بهذا الشكل لا يخدم غرضًا كبيرًا لأنه يفتقر إلى أي معلومات سياقية حول الخطأ. هل يمكننا إضافة المزيد من المعلومات إلى هذا السجل لجعله أكثر فائدة لعملية التصحيح؟
ماذا عن إضافة معرف الطلب (Order Id) ومعرف المنتج (Product Id)؟
log.error( "Exception in processing Order #{} for Product #{} due to exception - {}" , orderId, productId, ex.getResponseBodyAsString())
سينتج عن هذا سجل بالتنسيق التالي:
[ 2020 -09 -27 T18: 54 : 41 , 500 + 0530 ]-[ERROR]-[InventoryValidator]-[ 13 ] Exception in processing Order # 182726 for Product # 21 due to exception - Product Not Available
الآن، أصبح هذا السجل أكثر منطقية ووضوحًا! بالنظر إلى السجلات، يمكننا أن نفهم أن خطأً حدث أثناء معالجة الطلب رقم 182726 لأن المنتج رقم 21 لم يكن متاحًا.
كيفية تسجيل السجلات بفعالية: التسجيل المنظم (Structured Logging)
بينما يبدو السجل أعلاه منطقيًا تمامًا لنا كبشر، فإنه قد لا يكون التنسيق الأمثل للآلات أو أدوات تحليل السجلات. دعنا نلقي نظرة على مثال لفهم السبب.
افترض وجود مشكلة في توفر منتج معين (لنقل المنتج رقم 21)؛ ونتيجة لذلك، تفشل جميع الطلبات التي تحتوي على هذا المنتج. لقد تم تكليفك بمهمة العثور على جميع الطلبات الفاشلة لهذا المنتج. ستقوم بسعادة باستخدام أمر grep للبحث عن Product #21 في سجلاتك وتنتظر النتائج بفارغ الصبر. عند اكتمال البحث، ستحصل على شيء مثل هذا:
[ 2020 -09 -27 T18: 54 : 41 , 500 + 0530 ]-[ERROR]-[InventoryValidator]-[ 13 ] Exception in processing Order # 182726 for Product # 21 due to exception - Product Not Available
[ 2020 -09 -27 T18: 53 : 29 , 500 + 0530 ]-[ERROR]-[InventoryValidator]-[ 13 ] Exception in processing Order # 972526 for Product # 217 due to exception - Product Not Available
[ 2020 -09 -27 T18: 52 : 34 , 500 + 0530 ]-[ERROR]-[InventoryValidator]-[ 13 ] Exception in processing Order # 46675754 for Product # 21 due to exception - Product Not Available
[ 2020 -09 -27 T18: 52 : 13 , 500 + 0530 ]-[ERROR]-[InventoryValidator]-[ 13 ] Exception in processing Order # 332254 for Product # 2109 due to exception - Product Not Available
هذه ليست بالضبط النتائج التي كنت تتوقعها، أليس كذلك؟ لقد عثر البحث على جميع السجلات التي تحتوي على السلسلة النصية Product #21، بما في ذلك Product #217 و Product #2109. فكيف يمكنك تحسين هذا الوضع؟ هنا يأتي دور التسجيل المنظم (Structured Logging).
ما هو التسجيل المنظم؟
يحل التسجيل المنظم هذه المشكلات الشائعة ويسمح لأدوات تحليل السجلات بتوفير قدرات إضافية. السجلات المكتوبة بتنسيق منظم تكون أكثر ملاءمة للآلة، مما يعني أنه يمكن تحليلها بسهولة بواسطة برامج مخصصة. يمكن أن يكون هذا مفيدًا في السيناريوهات التالية:
- البحث والربط الفعال: يمكن للمطورين البحث في السجلات وربط الأحداث ببعضها البعض، وهو أمر لا يقدر بثمن سواء أثناء التطوير أو لاستكشاف مشكلات الإنتاج وإصلاحها.
- تحليلات الأعمال: يمكن لفرق الأعمال تحليل هذه السجلات وإجراء تحليلات على حقول معينة (على سبيل المثال، عدد المنتجات الفريدة يوميًا) عن طريق استخراج وتلخيص هذه الحقول.
- لوحات المعلومات (Dashboards): يمكنك بناء لوحات معلومات (سواء للأعمال أو التقنية) عن طريق تحليل السجلات وإجراء تجميعات (Aggregates) على الحقول ذات الصلة.
دعنا نستخدم بيان السجل السابق الخاص بنا ونجري تغييرًا صغيرًا لجعله منظمًا:
log.error( "Exception in processing OrderId={} for ProductId={} due to Error={}" , orderId, productId, ex.getResponseBodyAsString())
سينتج عن هذا سجل بالتنسيق التالي:
[ 2020 -09 -27 T18: 54 : 41 , 500 + 0530 ]-[ERROR]-[InventoryValidator]-[ 13 ] Exception in processing OrderId= 182726 for ProductId= 21 due to Error =Product Not Available
الآن، يمكن تحليل رسالة السجل هذه بسهولة بواسطة الآلة باستخدام علامة المساواة (=) كفاصل لاستخراج حقول OrderId و ProductId و Error. يمكننا الآن إجراء بحث دقيق عن ProductId=21 لإنجاز مهمتنا. يسمح لنا هذا أيضًا بإجراء تحليلات أكثر تقدمًا على السجلات، مثل إعداد تقرير بجميع الطلبات التي فشلت بسبب أخطاء معينة.
إذا كنت تستخدم نظام إدارة سجلات مثل Splunk، فإن الاستعلام Error=”Product Not Available” | stats count by ProductId يمكن أن ينتج الآن النتيجة التالية:
| ProductId | count |
|---|---|
| 21 | 5 |
| 27 | 12 |
يمكننا أيضًا استخدام تنسيق JSON لطباعة سجلاتنا بهذا الشكل، مما يوفر بنية واضحة وموحدة:
{ "timestamp" : "2020-09-27T18:54:41,500+0530", "level" : "ERROR", "class" : "InventoryValidator", "line" : "13", "OrderId" : "182726", "ProductId" : "21", "Error" : "Product Not Available" }
من المهم فهم المنهجية الكامنة وراء التسجيل المنظم. لا يوجد معيار ثابت له، ويمكن تنفيذه بعدة طرق مختلفة، ولكن الهدف الأساسي هو جعل السجلات قابلة للتحليل آليًا.
الخلاصة التقنية
في هذا المقال، استعرضنا العيوب والمخاطر المرتبطة بالتسجيل غير المنظم (Unstructured Logging)، وكيف يمكن أن يعيق عملية استكشاف الأخطاء وإصلاحها وتحليل البيانات. في المقابل، سلطنا الضوء على الفوائد والمزايا العديدة التي يقدمها التسجيل المنظم (Structured Logging)، والذي يحول السجلات من مجرد نصوص عشوائية إلى مصادر بيانات قيمة يمكن البحث فيها وتحليلها بكفاءة عالية.
تستفيد أنظمة إدارة السجلات الحديثة مثل Splunk بشكل كبير من رسائل السجل المنظمة جيدًا، مما يتيح إمكانات بحث وتحليل سهلة وفعالة لأحداث السجل. ومع ذلك، يكمن التحدي الأكبر في التسجيل المنظم في وضع مجموعة قياسية من الحقول لنظامك البرمجي. يمكن تحقيق ذلك من خلال اتباع نموذج تسجيل مخصص أو اعتماد نظام تسجيل مركزي يضمن استخدام جميع المطورين لنفس الحقول في رسائل السجل الخاصة بهم، مما يضمن الاتساق والفعالية على مستوى المؤسسة.