سؤال

مثل سأل جيف أتوود:"ما هي فلسفتك في التسجيل؟يجب أن تكون جميع التعليمات البرمجية متناثرة .logthis() و .logthat() المكالمات؟أو هل تقوم بحقن التسجيل بعد الحقيقة بطريقة أو بأخرى؟"

هل كانت مفيدة؟

المحلول

يمكن تلخيص فلسفتي في التسجيل بسهولة في أربعة أجزاء:

التدقيق، أو تسجيل منطق الأعمال

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

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

تسجيل البرنامج

الرسائل التي ستساعد المطورين على اختبار التطبيق وتصحيح أخطائه، ومتابعة تدفق البيانات ومنطق البرنامج بسهولة أكبر لفهم مكان وجود أخطاء التنفيذ والتكامل والأخطاء الأخرى.

بشكل عام، يتم تشغيل وإيقاف هذا التسجيل حسب الحاجة لجلسات تصحيح الأخطاء.

تسجيل الأداء

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

تسجيل الأمن

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

نصائح أخرى

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

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

  • عن
  • الأخطاء فقط
  • أساسي
  • مفصلة
  • كل شئ

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

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

#define DEBUG_ERROR          1
#define DEBUG_BASIC          2
#define DEBUG_DETAIL         4
#define DEBUG_MSG_BASIC      8
#define DEBUG_MSG_POLL       16
#define DEBUG_MSG_STATUS     32
#define DEBUG_METRICS        64
#define DEBUG_EXCEPTION      128
#define DEBUG_STATE_CHANGE   256
#define DEBUG_DB_READ        512
#define DEBUG_DB_WRITE       1024
#define DEBUG_SQL_TEXT       2048
#define DEBUG_MSG_CONTENTS   4096

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

يأتي البرنامج عادةً مع تشغيل ERROR وBASIC وSTATE_CHANGE وEXCEPTION، ولكن يمكن تغيير ذلك في الحقل عبر مربع حوار التصحيح (أو إعداد التسجيل/ini/cfg، حيث يتم حفظ هذه الأشياء).

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

هذا هو دماغي الذي تم تفريغه ...

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

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

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

أنا أتبع ما أعتبره منهجًا تقليديًا؛بعض قطع الأشجار، محاطة بالتعريفات الشرطية.بالنسبة لبنيات الإنتاج، أقوم بإيقاف تشغيل التعريفات.

أختار تسجيل الدخول عمدًا أثناء المضي قدمًا، لأن هذا يعني أن بيانات السجل ذات معنى:

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

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

أبدأ بتأكيد الكثير من الشروط في الكود الخاص بي (في C#، باستخدام System.Diagnostics.Assert)، لكنني أقوم بإضافة التسجيل فقط عندما أجد، أثناء تصحيح الأخطاء أو وضع النظام تحت الضغط، أنني بحاجة حقًا إلى طريقة لمتابعة ما يحدث داخل الكود الخاص بي دون الحاجة إلى إرفاق مصحح أخطاء بشكل دائم.

بخلاف ذلك، أفضل استخدام قدرة Visual Studio لوضع آثار في التعليمات البرمجية كنقاط توقف خاصة (أي.تقوم بإدراج نقطة توقف والنقر عليها بزر الماوس الأيمن، ثم تحديد "عند الضغط على..." وإخبارها بما سيتم عرضه في هذه الحالة).ليست هناك حاجة لإعادة الترجمة ومن السهل تمكين/تعطيل الآثار أثناء التنقل.

إذا كنت تكتب برنامجًا سيستخدمه العديد من الأشخاص، فمن الأفضل أن يكون لديك نوع من الآلية لاختيار ما سيتم تسجيله وما لن يتم تسجيله.إحدى الحجج لصالح دوال .logthis() هي أنها يمكن أن تكون بديلاً ممتازًا للتعليقات المضمنة في بعض الحالات (إذا تم تنفيذها بشكل صحيح).

بالإضافة إلى ذلك، فهو يساعدك على تضييق نطاق حدوث الخطأ بالضبط.

قم بتسجيل الدخول جميعًا ودع Grep يقوم بفرزها.

أنا أتفق مع آدم، ولكنني سأفكر أيضًا في تسجيل الأشياء محل الاهتمام أو الأشياء التي يمكنك إظهارها كإنجازات كنوع من الدليل على حدوثها.

أقوم بتحديد مجموعة متنوعة من المستويات وتمرير الإعداد باستخدام التكوين/الاستدعاء.

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

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

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

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

كمثال على الحالة التي أنقذ فيها التسجيل مؤخرتي، ذات مرة كان لدي مستخدم غريب لديه نموذج أولي لجهاز Intel كان يتعطل.لقد أدرجنا الحد الأدنى من المتطلبات للأجهزة التي يجب أن تدعم SSE 4، لكن هذا الجهاز بالذات استوفى الحد الأدنى من المتطلبات وما زال لا يدعم امتدادات Streaming SIMD بعد SSE 3 على الرغم من كونه جهازًا يحتوي على 16 نواة.أصبح اكتشاف ذلك ممكنًا بسرعة من خلال النظر في سجله الذي أظهر بدقة رقم السطر الذي تم استخدام تعليمات SSE 4 فيه.لم يتمكن أي منا في فريقنا من إعادة إنتاج المشكلة، ناهيك عن مستخدم واحد آخر شارك في التحقق من التقرير.من الناحية المثالية، كان ينبغي أن نكتب تعليمات برمجية لإصدارات SIMD الأقدم أو على الأقل نقوم ببعض التفرع والتحقق للتأكد من أن الأجهزة تدعم الحد الأدنى من المتطلبات، لكننا أردنا تقديم افتراض ثابت يتم توصيله من خلال الحد الأدنى من متطلبات الأجهزة من أجل البساطة والاقتصاد.ربما يمكن القول هنا أن الحد الأدنى من متطلبات النظام لدينا هو الذي حدث فيه "الخلل".

نظرًا للطريقة التي أستخدم بها التسجيل هنا، فإننا نميل إلى الحصول على سجلات كبيرة إلى حد ما.ومع ذلك، فإن الهدف ليس سهولة القراءة - ما يهم عادة هو السطر الأخير من السجل الذي يتم إرساله مع تقرير عندما يواجه المستخدم عطلًا من نوع ما لا أحد منا في الفريق (ناهيك عن عدد قليل من المستخدمين الآخرين في العالم) يمكن أن تتكاثر.

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

لا أقوم برش مخرجات السجل في كل مكان (ربما أفعل ذلك إذا كان لدي الوقت).عادةً ما أحجزها أكثر للمناطق التي تبدو الأكثر خطورة:رمز يستدعي تظليل GLSL، على سبيل المثال.(يختلف بائعو وحدات معالجة الرسومات هنا بشكل كبير من حيث القدرة وحتى كيفية تجميع التعليمات البرمجية)، والتعليمات البرمجية التي تستخدم جوهريات SIMD، والتعليمات البرمجية ذات المستوى المنخفض للغاية، والتعليمات البرمجية التي يجب حتمًا أن تعتمد على سلوك خاص بنظام التشغيل، والتعليمات البرمجية ذات المستوى المنخفض التي تضع افتراضات حول تمثيل PODs (على سبيل المثال:الكود الذي يفترض 8 بتات لكل بايت) - نوع الحالات التي نود فيها أيضًا رش الكثير من التأكيدات والفحوصات المنطقية بالإضافة إلى كتابة أكبر عدد من اختبارات الوحدات.عادةً ما يكون هذا كافيًا، وقد أنقذني التسجيل عدة مرات حيث كنت سأتعامل مع مشكلة غير قابلة للتكرار وكان سيتعين علي اتخاذ خطوات عمياء في المشكلة، مما يتطلب العديد من المحاولات المرتدة للتكرار لحل المستخدم الوحيد في العالم الذي يمكن إعادة إنتاج المشكلة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top