سجلات التطبيقات: استراتيجية متقدمة لجعلها حليفًا لا عبئًا في مشاريعك البرمجية

دقائق القراءة: 9

تُعد عملية التسجيل (Logging) جزءًا لا يتجزأ من عالم تطوير البرمجيات، وتتخذ أشكالًا ومتطلبات ونكهات متعددة. فمن الشركات الناشئة الصغيرة التي يديرها فرد واحد إلى المؤسسات الكبيرة، تنتشر السجلات في كل مكان. حتى أبسط الأسئلة البرمجية الخوارزمية تتضمن بعض عمليات التسجيل في مراحلها المختلفة. نعتمد بشكل كبير على السجلات لتطوير برامجنا وصيانتها وإبقائها قيد التشغيل بكفاءة.

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

صورة توضيحية لملح يمثل سجلات التطبيقات المتناثرة وغير المنظمة

التحدي الحالي: عندما تتحول السجلات إلى عبء تقني

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

قبل الغوص في الحل المقترح، دعنا نحدد مشكلة ملموسة بناءً على ملاحظاتي. فما هو التسجيل بالضبط؟ إليك تعريفًا موجزًا ومباشرًا وجدته في مقال لـ Colin Eberhardt:

التسجيل هو عملية تسجيل إجراءات التطبيق وحالته إلى واجهة ثانوية.

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

إجابة مقبولة على StackOverflow توضح تعريف التسجيل

قد يبدو مخطط بسيط يوضح كيفية دمج التسجيل في نظام مصمم ببنية نظيفة (clean architecture) على النحو التالي:

مخطط يوضح دمج التسجيل في بنية تطبيق نظيفة

يمكننا القول بأمان أن التسجيل بحد ذاته هو نظام فرعي (subsystem) ضمن تطبيقنا. ويمكننا القول بأمان أيضًا، أنه بدون دراسة متأنية، غالبًا ما يخرج عن السيطرة بشكل أسرع مما نتوقع. بينما تصميم التسجيل كنظام فرعي داخل تطبيقاتنا ليس خطأ، فإن التصور التقليدي للتسجيل (بمستوياته الأربعة إلى الستة مثل info و warn و error و debug وما إلى ذلك) غالبًا ما يجعل المطورين يركزون على الشيء الخطأ. إنه يجعلنا نركز على التنسيق بدلاً من الغرض الفعلي من كتابة السجلات. هذا أحد الأسباب التي تجعلنا نسجل الأخطاء دون التفكير مرتين في كيفية التعامل معها. إنه أيضًا سبب تسجيلنا في كل خطوة من شيفرتنا بينما نكون، على نحو ساخر، غير قادرين على تصحيح الأخطاء بفعالية إذا كانت هناك مشكلة في بيئة الإنتاج. لهذا السبب، أقترح إطار عمل بديل للتسجيل، وبالتالي، كيفية تصميم التسجيل في أنظمتنا بشكل موثوق.

إطار عمل “السيء، الجيد، والقبيح”: استراتيجية بديلة للتسجيل

هذا إطار عمل لكيفية اعتقادي بضرورة وضع استراتيجية للتسجيل. يتكون من ثلاث فئات أو اهتمامات لسجلاتنا، وثلاثة فقط.

القاعدة الذهبية الأولى: لا تسجل إلا للضرورة القصوى

التسجيل المفرط (Overlogging) يضر بإنتاجية فرق العمل وقدرتها على التعامل مع العمليات اليومية. هناك الكثير من الأسباب التي تجعلنا لا “نسجل كلما أمكن” كما ينصح به بعض المتحمسين للمراقبة (observability fanfare). فالتسجيل يعني المزيد من الشيفرة للصيانة، ويتكبد تكاليف من حيث أداء النظام، والمزيد من التسجيل يعرضنا لمزيد من تدقيقات الامتثال التنظيمي لخصوصية البيانات. إذا كنت بحاجة إلى المزيد من الأسباب للامتناع عن التسجيل، فراجع هذا المنشور لـ Nikita Sobolev أو هذا المنشور لـ Jeff Atwood.

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

مع ذلك، كيف يمكننا إدخال التسجيل بأمان عندما يكون ضروريًا للغاية؟ كيف يجب أن ننظم سجلاتنا وننسق محتواها؟ ما هي المعلومات الضرورية التي يجب تضمينها في السجلات؟

سجلات “القبيح”: للسيناريوهات الكارثية وغير المتوقعة

هذا هو النوع الأول من السجلات الذي أرغب في وصفه، وهو أيضًا النوع الذي أجده نادرًا ما يتكرر. (إذا وجدناه كثيرًا، فقد تكون لدينا مشكلات أكبر في أنظمتنا!).

سجلات “القبيح” هي نوع السجلات التي تظهر في ظل سيناريوهات كارثية أو غير متوقعة تتطلب إجراءً فوريًا (مثل الأخطاء الكارثية التي تتطلب إعادة تشغيل التطبيق). يمكننا القول إنه في ظل هذه الظروف، يكون استخدام أدوات التنبيه مثل Sentry أكثر منطقية. ومع ذلك، قد يظل سجل الخطأ مفيدًا لتزويدنا بمزيد من السياق المحيط بهذه الأخطاء والذي قد لا يكون متاحًا في تتبع المكدس (stack trace) الخاص بها. لكنها يمكن أن تساعد في إعادة إنتاج هذه الأخطاء، مثل مدخلات المستخدم.

تمامًا مثل الأخطاء التي تصاحبها، يجب أن تُبقى هذه السجلات في حدها الأدنى في شيفرتنا وتوضع في مكان واحد. يجب أيضًا تصميمها/توثيقها في المواصفات كسلوك نظام مطلوب للتعامل مع الأخطاء. كما يجب دمجها في الشيفرة المصدرية حول المكان الذي يتم فيه التعامل مع الأخطاء. بينما يكون تنسيق ومستوى سجلات “القبيح” تفضيليًا تمامًا على أساس كل فريق، أوصي باستخدام log.error أو log.fatal قبل الإغلاق السليم وإعادة تشغيل التطبيق. يجب عليك أيضًا إرفاق تتبع المكدس الكامل للخطأ وبيانات إدخال الدالة أو الطلبات لإعادة الإنتاج إذا لزم الأمر.

سجلات “السيء”: للأخطاء المتوقعة والمعالجة

سجلات “السيء” هي نوع السجلات التي تعالج الأخطاء المتوقعة والمعالجة مثل مشكلات الشبكة والتحقق من صحة مدخلات المستخدم (user input validation). يتطلب هذا النوع من السجلات انتباه المطورين فقط إذا كان هناك شذوذ فيها. جنبًا إلى جنب مع إعداد مراقب لتنبيه المطورين عند حدوث خطأ، تكون هذه السجلات مفيدة للتخفيف من مشاكل البنية التحتية أو الأمنية الخطيرة المحتملة.

يجب تحديد هذا النوع من السجلات ضمن المتطلبات التقنية للتعامل مع الأخطاء أيضًا، ويمكن تجميعها فعليًا إذا كنا نتعامل مع الأخطاء المتوقعة وغير المتوقعة في نفس موقع الشيفرة. بناءً على طبيعة ما تجعله “مرئيًا” للمطورين، يمكن استخدام log.warn أو log.error لسجلات “السيء” وفقًا لاتفاقية الفريق.

سجلات “الجيد”: لمسار العمليات الناجحة

أخيرًا وليس آخرًا، سجلات “الجيد” هي نوع السجلات التي يجب أن تظهر غالبًا في شيفرتنا المصدرية – ولكن غالبًا ما يكون من الأصعب تحقيقها بشكل صحيح. سجلات “الجيد” هي تلك المرتبطة بالخطوات “السعيدة” لتطبيقاتنا، مما يشير إلى نجاح العمليات.

نظرًا لطبيعتها التي تشير إلى بدء/تنفيذ عمليات ناجحة في نظامنا، غالبًا ما يُساء استخدام سجلات “الجيد” من قبل المطورين الذين يغريهم شعار “مجرد جزء آخر من البيانات في السجل، قد نحتاجه”. مرة أخرى، سأعود إلى قاعدتنا الأولى في التسجيل: “لا تسجل إلا إذا كنت مضطرًا لذلك تمامًا”.

لمنع حدوث هذا النوع من التسجيل المفرط، يجب علينا توثيق سجلات “الجيد” كجزء من متطلباتنا التقنية التي تكمل منطق الأعمال الرئيسي. علاوة على ذلك، لكل سجل من سجلات “الجيد” الموجودة في مواصفاتنا التقنية، يجب أن يجتاز اختبار الحمض: هل هناك أي ظروف قد ننظر فيها إلى السجل (سواء كان طلب دعم عملاء، أو استفسار مدقق خارجي)؟ بهذه الطريقة فقط لن يكون log.info إرثًا مخيفًا يحجب رؤية المطورين لتطبيقاتنا.

ما يجب معرفته أيضاً: التسجيل كمتطلب أساسي

أفترض الآن أنك لاحظت أن الموضوع العام لاستراتيجية التسجيل المقترحة يدور حول التوثيق الواضح والمحدد لغرض السجل. من المهم أن نتعامل مع التسجيل كجزء من متطلباتنا، وأن نكون محددين بشأن الكلمات المفتاحية والرسائل التي نريد وضع علامة عليها في سياق كل سجل لكي تتم فهرستها بفعالية. بهذه الطريقة فقط يمكننا أن نكون على دراية بكل سجل ننتجه، وبالتالي، أن يكون لدينا رؤية واضحة لأنظمتنا.

مع ترقية السجلات إلى “مواطنين من الدرجة الأولى” بمتطلبات تقنية ملموسة في مواصفاتنا، فإن الآثار المترتبة على ذلك هي أنها ستحتاج إلى:

  • الصيانة والتحديث مع تطور متطلبات الأعمال والتقنية.
  • تغطيتها باختبارات الوحدة (unit tests) واختبارات التكامل (integration tests).

قد يبدو هذا وكأنه الكثير من العمل الإضافي لإنجاز سجلاتنا بشكل صحيح. ومع ذلك، أرى أن هذا هو نوع الاهتمام والجهد الذي يستحقه التسجيل لكي يكون مفيدًا. اخدم سجلاتنا، وسنُكافأ بسخاء!

دليل عملي للهجرة: تحويل سجلاتك الفوضوية إلى نظام فعال

أعتقد أنه لا فائدة من استراتيجية تسجيل جديدة (أو أي استراتيجيات/أطر عمل جديدة لهذه المسألة) للمشاريع القديمة (legacy projects) إذا لم تكن هناك طريقة لنقلها من حالتها الفوضوية إلى الحالة المثالية المقترحة. لذلك، لدي خطة عامة من ثلاث خطوات لأي شخص يشعر بالإحباط من سجلات نظامه ويرغب في استثمار الوقت لتسجيل أكثر فعالية.

الخطوة الأولى: تحديد “المشتبه بهم المعتادين”

بما أن الفكرة هي تقليل سجلات “القمامة”، فإن خطوتنا الأولى هي تحديد مكان اختباء المجرمين. باستخدام محررات النصوص القوية وبيئات التطوير المتكاملة (IDEs) التي لدينا في الوقت الحاضر (أو grep إذا كنت تقرأ هذا في الماضي عبر نافذة إلى المستقبل)، يمكن تحديد جميع occurrences of logging بسهولة. قد تكون وثيقة (أو جدول بيانات إذا كنت ترغب في أن تكون منظمًا) توثق جميع occurrences of logging ضرورية إذا كان هناك الكثير منها.

الخطوة الثانية: تصفية السجلات غير الضرورية

بعد تحديد جميع المشتبه بهم، حان الوقت لإزالة “التفاح الفاسد”. السجلات المكررة أو التي لا يمكن الوصول إليها هي ثمار سهلة يمكننا إزالتها فورًا من شيفرتنا المصدرية. أما بالنسبة لبقية occurrences of logging، فقد حان الوقت لإشراك أصحاب المصلحة الآخرين مثل مهندس “التأسيس” الذي بدأ المشروع (إذا كان ذلك ممكنًا)، ومديري المنتجات، ودعم العملاء، أو فريق الامتثال للإجابة على السؤال: هل نحتاج إلى كل سجل من هذه السجلات، وإذا كان الأمر كذلك، فما الغرض منها؟

الخطوة الثالثة: صياغة متطلبات واضحة للسجلات

الآن بعد أن أصبح لدينا قائمة مختصرة بالسجلات الضرورية للغاية، فإن تحويلها إلى متطلبات تقنية مع توثيق الغرض لكل منها أمر ضروري لتحديد عقد (أو يمكننا تسميته مواصفات) لنظام التسجيل الفرعي الخاص بنا. اسأل نفسك ماذا تفعل عندما يحدث log.error، ولمن نقوم بعمل log.info؟ بعد ذلك، الأمر مجرد مسألة انضباط بنفس الطريقة التي نكتب بها البرامج ونحافظ عليها بشكل عام. دعونا نعمل جميعًا معًا ونجعل التسجيل رائعًا!

يمكنك التواصل معي على تويتر لأي أسئلة أو تعليقات. إذا قرأت هذا الحد، اشكر المؤلف لإظهار اهتمامك. قل شكرًا. تعلم البرمجة مجانًا. لقد ساعد منهج freeCodeCamp مفتوح المصدر أكثر من 40,000 شخص في الحصول على وظائف كمطورين. ابدأ.

الخلاصة التقنية

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

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *