إذا كنت ترغب في القيام بالأشياء بشكل جيد ، فيجب عليك أولاً شحذ أدواتك.
قد ينسى العديد من المبرمجين مدى أهمية تسجيل سلوك التطبيقات. عند مواجهة الأخطاء المتزامنة الناجمة عن الضغط العالي في بيئات متعددة الخيوط ، يمكنك فهم أهمية سجلات التسجيل.
كان بعض الناس سعداء جدًا بإضافة هذه الجملة إلى الكود:
log.info ("التسجيل السعيد والهم الهم") ؛
قد لا يدرك حتى أهمية سجلات التطبيق في الصيانة والضبط وتحديد الخطأ. أعتقد أن SLF4J هو أفضل واجهة برمجة تطبيقات تسجيل ، وذلك أساسًا لأنه يدعم طريقة رائعة لحقن المخطط:
log.debug ("Found {} سجلات مطابقة مرشح: '{}'" ، السجلات ، التصفية) ؛
بالنسبة إلى log4j ، يمكنك فقط القيام بذلك:
log.debug ("Found" + Records + "RecordsMatching Filter:" " + filter +" '") ؛
هذه الكتابة ليست مجرد قابلية للقراءة أكثر وضوحًا وسوءًا ، ولكن لديها أيضًا ربط سلسلة يؤثر على الكفاءة (عندما لا يتطلب هذا المستوى الإخراج).
يقدم SLF4J ميزة الحقن {} ، وبما أن الربط بين السلسلة يتم تجنبه في كل مرة ، فلن يتم استدعاء طريقة tostring ، وليس هناك حاجة لإضافة isdebugenabled. SLF4J هو تطبيق وضع المظهر ، إنه مجرد واجهة. للتنفيذ المحدد ، أوصي بإطار Logback. لقد أعلنت بالفعل مرة واحدة من قبل ، بدلاً من Log4J الكامل بالفعل. لديها العديد من الميزات المثيرة للاهتمام. على عكس log4j ، لا يزال تحت التطوير النشط والتحسين.
أداة أخرى للتوصية هي perf4j:
perf4j هو system.currentTimeMillis () كما log4j هو system.out.println ()
تمامًا مثل Log4J هو بديل أفضل لـ System.out.println ، يشبه Perf4J استبدال System.CurrentTimeMillis (). لقد قدمت Perf4J في مشروع ولاحظت كيف يعمل تحت الأحمال العالية. يذهل المسؤولون ومستخدمي الأعمال من قبل المخططات الجميلة التي توفرها هذه الأداة. يمكننا عرض مشكلات الأداء في أي وقت. يجب أن يكون Perf4J مقالًا خاصًا للحديث عنه. الآن ، يمكنك أولاً إلقاء نظرة على دليل المطور الخاص بها. يوجد أيضًا Ceki Gülcü (منشئ Log4J و SLF4J و Logback Project) يوفر وسيلة سهلة لنا لإزالة التبعيات على غطس العموم.
لا تنسى مستوى السجل
في كل مرة تريد إضافة سطر من السجلات ، ستفكر ، ما هو مستوى السجل الذي يجب استخدامه هنا؟ حوالي 90 ٪ من المبرمجين لا يهتمون بهذه القضية. يستخدمون مستوى واحد لتسجيل السجلات ، وعادة ما يكون معلومات أو تصحيح. لماذا؟
يحتوي إطار السجل على مزايزتان رئيسيتان مقارنة بالنظام. OUT: التصنيف والمستوى. يسمح لك كلاهما بتصفية السجلات بشكل انتقائي ، بشكل دائم أو فقط عند استكشاف الأخطاء وإصلاحها.
خطأ: حدث خطأ خطير ويجب التعامل معه على الفور. هذا المستوى من الخطأ لا يطاق لأي نظام. على سبيل المثال: استثناء مؤشر NULL ، لا تتوفر قاعدة البيانات ، ولا يمكن تنفيذ حالات استخدام المسارات الحرجة.
تحذير: ستستمر العملية اللاحقة ، ولكن يجب أن تؤخذ على محمل الجد. في الواقع ، آمل أن يكون هناك مستويان هنا: الأول هو المشكلة الواضحة في الحل (مثل "البيانات الحالية غير متوفرة ، باستخدام البيانات المخزنة مؤقتًا") ، والآخر هو المشكلة والاقتراحات المحتملة (مثل "تشغيل البرنامج في وضع التطوير" أو "كلمة مرور وحدة التحكم غير آمنة بما يكفي".
تصحيح: ما يهتم المطورين به. في وقت لاحق سأتحدث عن الأشياء التي يجب تسجيلها في هذا المستوى.
تتبع: معلومات أكثر تفصيلاً ، تستخدم فقط في مرحلة التطوير. قد لا تزال بحاجة إلى الانتباه إلى هذه المعلومات خلال فترة زمنية قصيرة بعد إطلاق المنتج ، لكن سجلات السجل هذه مؤقتة فقط ويجب إيقاف تشغيلها في النهاية. من الصعب التمييز بين الفرق بين التصحيح والتتبع ، ولكن إذا أضفت خطًا من السجلات وحذفه بعد التطوير والاختبار ، فيجب أن يكون السجل على مستوى التتبع.
القائمة أعلاه مجرد اقتراح ، يمكنك تسجيل الدخول وفقًا لقواعدك الخاصة ، ولكن من الأفضل أن يكون لديك قواعد معينة. تجربتي الشخصية هي: لا تصفية سجلات على مستوى الكود ، ولكن استخدم مستوى السجل الصحيح لتصفية المعلومات المطلوبة بسرعة ، والتي يمكن أن توفر لك الكثير من الوقت.
آخر شيء يقوله هو أن هذا سيئ السمعة هو*بيان مشروط. يحب بعض الناس إضافة هذا قبل كل سجل:
if (log.isdebugenabled ()) log.debug ("مكان لعلبك التجاري") ؛أنا شخصياً أعتقد أنه يجب عليك تجنب إضافة هذا الشيء الفوضوي إلى الكود. لا يبدو أن الأداء قد تم تحسينه كثيرًا (خاصة بعد استخدام SLF4J) ، وهو أشبه بالتحسين المبكرة. أيضًا ، ألا تجدها زائدة بعض الشيء؟ نادراً ما تكون هناك حاجة إلى بيان الحكم الصريح هذا بشكل صريح ما لم نثبت أن بناء رسائل السجل نفسها مكلفة للغاية. خلاف ذلك ، يمكنك أن تتذكر بقدر ما يجب عليك والسماح لإطار السجل بالقلق بشأن هذا.
هل تعرف ما الذي تسجله؟
في كل مرة تكتب فيها خطًا من السجلات ، خذ لحظة لمعرفة ما تقوم به في ملف السجل. اقرأ السجل الخاص بك واكتشف مكان الاستثناء. أولاً ، على الأقل تجنب استثناءات المؤشر الفارغ:
log.debug ("طلب المعالجة مع المعرف: {}" ، request.getID ()) ؛
هل أكدت أن الطلب ليس فارغًا؟
مجموعات التسجيل هي أيضا حفرة كبيرة. إذا كنت تستخدم Hibernate للحصول على مجموعة من كائنات المجال من قاعدة البيانات ، فإنك تكتبها بطريق الخطأ مثل هذا: log.debug ("إرجاع المستخدمين: {}" ، المستخدمين) ؛
لن يستدعي SLF4J سوى طريقة tostring عندما يتم طباعة هذا البيان بالفعل ، بالطبع هذا رائع. ومع ذلك ، إذا كان يفيض الذاكرة ، مشكلات اختيار N+1 ، يتضور مؤشر الترابط حتى الموت ، وتأخر استثناء التهيئة ، فإن مساحة تخزين السجل تنفد ... كل هذه قد تحدث. أفضل طريقة هي تسجيل معرف الكائن فقط (أو فقط حجم المجموعة). ومع ذلك ، يتطلب جمع المعرفات استدعاء طريقة getID لكل كائن ، وهي في الحقيقة ليست مهمة سهلة في Java. Groovy لديه مشغل توسيع رائع (المستخدمين*.ID). في Java يمكننا استخدام مكتبة BeanuTils المشاعات لمحاكاة:
log.debug ("إرجاع معرفات المستخدم: {}" ، جمع (المستخدمين ، "id")) ؛
ربما هذه هي الطريقة التي يتم بها تنفيذ طريقة التجميع:
مجموعة ثابتة عامة (مجموعة المجموعة ، string propertyName) {return CollectionUtils.Collect (Collection ، BeanTopropertyValuetRansformer (propertyName)) ؛}أخيرًا ، قد لا يتم تنفيذ طريقة tostring بشكل صحيح أو استخدامها.
أولاً ، من أجل تسجيل الدخول ، هناك العديد من الطرق لإنشاء tostring لكل فئة. من الأفضل استخدام ToStringBuilder لتوليد (ولكن ليس إصدار تنفيذ الانعكاس الخاص به).
ثانياً ، انتبه إلى المصفوفات والمجموعات غير التقليدية. قد لا تسمي تنفيذ TOSTRING للصفائف وبعض المجموعات البديلة طريقة TOSTRING لكل عنصر واحد تلو الآخر. يمكن استخدام المصفوفات#deeptostring التي توفرها JDK. تحقق من السجلات التي قمت طباعتها على نفسك لمعرفة ما إذا كان هناك أي معلومات حول استثناء التنسيق.
تجنب الآثار الجانبية
لا تؤثر طباعة السجل بشكل عام على أداء البرنامج. في الآونة الأخيرة ، ألقى صديق لي استثناءًا من سباتيسيتيليزيليزيكشن على نظام يعمل على بعض المنصات الخاصة. كما قد تكون قد خمنت من هذا ، فإن بعض مطبوعات السجل التي تؤدي إلى تأخر مجموعات التهيئة التي يتم تحميلها عند توصيل الجلسة. في هذه الحالة ، إذا تمت زيادة مستوى السجل ، فلن يتم تهيئة المجموعة. إذا كنت لا تعرف معلومات السياق هذه ، فكم من الوقت سيستغرقك لاكتشاف هذا الخطأ.
الآثار الجانبية الأخرى هي أنه يؤثر على سرعة تشغيل البرنامج. إجابة سريعة على هذا السؤال: إذا تم طباعة السجلات أكثر من اللازم أو لا يتم استخدام الربط بين ToString وسلسلة بشكل صحيح ، فستكون للطباعة السجل تأثير سلبي على الأداء. ما هو حجمه؟ حسنًا ، لقد رأيت برنامجًا يعيد تشغيله كل 15 دقيقة لأن الكثير من السجلات تتسبب في تجويع المواضيع حتى الموت. هذا هو التأثير الجانبي! من تجربتي ، فإن طباعة مائة ميغابايت في ساعة واحدة هي الحد الأعلى تقريبًا.
بالطبع ، إذا تم إحباط عملية الأعمال بسبب استثناءات طباعة السجل ، فسيكون هذا التأثير الجانبي رائعًا. كثيرا ما أرى الناس يكتبون هذا لتجنب هذا:
حاول {log.trace ("id =" + request.getuser (). getId () + "accesses" + manager.getpage (). geturl ().هذا جزء حقيقي من التعليمات البرمجية ، ولكن من أجل جعل العالم أكثر تنقية ، يرجى عدم كتابته مثل هذا.
وصف بوضوح
يحتوي كل سجل سجل على البيانات والوصف. ألق نظرة على هذا المثال:
log.debug ("Message Worded") ؛ log.debug (message.getJmsMessageId ()) ؛ log.debug ("Message with id '{}' Waged" ، message.getJmsMessageId ()) ؛ عند استكشاف الأخطاء وإصلاحها في نظام غير مألوف ، ما نوع السجل الذي تفضل رؤيته؟ ثق بي ، هذه الأمثلة شائعة. هناك أيضًا وضع سلبي:
if (message extryof textMessage)
// ...
آخر
log.Warn ("نوع رسالة غير معروفة") ؛
هل من الصعب إضافة أنواع الرسائل ومعرفات الرسائل وما إلى ذلك إلى سجل التحذير هذا؟ أعلم أن خطأ حدث ، لكن ما هذا؟ ما هي معلومات السياق؟
المثال السلبي الثالث هو "السجل السحري". مثال حقيقي: يعلم العديد من المبرمجين في الفريق أن 3 ≥ أرقام تتبع! الرقم الذي يتبعه رقم # ، يليه سجل رقم عشوائي زائف يعني "تم استلام الرسالة مع ID XYZ". لا أحد يريد تغيير هذا السجل. إذا قام شخص ما بكتابة لوحة المفاتيح واختر سلسلة فريدة من نوعها "&&&!#" ، فسيجد المعلومات التي يريدها بسرعة.
والنتيجة هي أن ملف السجل بأكمله يشبه سلسلة كبيرة من الأحرف العشوائية. لا يسع بعض الناس إلا أن يتساءلوا عما إذا كان هذا برنامج بيرل.
يجب أن تكون ملفات السجل قابلة للقراءة وواضحة وموصوفة ذاتيًا. لا تستخدم الأرقام السحرية وقيم التسجيل والأرقام والمعرفات وسياقها. سجل البيانات المصنعة ومعناها. سجل ما يفعله البرنامج. يجب أن يكون السجل الجيد مستندًا جيدًا لرمز البرنامج.
هل ذكرت عدم طباعة كلمة مرور ولدي معلومات شخصية؟ أعتقد أنه لا يوجد مثل هذا المبرمج الغبي.
اضبط التنسيق الخاص بك
تنسيق السجل هو أداة مفيدة للغاية ، والتي تضيف بشكل غير مرئي معلومات سياق قيمة إلى السجل. ولكن يجب أن تفكر بوضوح في نوع المعلومات المدرجة في تنسيلك. على سبيل المثال ، لا معنى لها تسجيل التواريخ في سجلات مكتوبة كل دورة بالساعة ، لأن اسم السجل الخاص بك يحتوي بالفعل على هذه المعلومات. على العكس من ذلك ، إذا لم تقم بتسجيل اسم مؤشر الترابط ، عندما يعمل خيطان بالتوازي ، فلن تتمكن من تتبع مؤشرات الترابط من خلال السجلات - تتداخل السجلات معًا. في تطبيق واحد متخلف ، لا بأس في القيام بذلك ، لكن هذا بالفعل شيء من الماضي.
من تجربتي ، يجب أن يتضمن تنسيق السجل المثالي (باستثناء معلومات السجل نفسها ، بالطبع): الوقت الحالي (لا يوجد تاريخ ، دقة مللي ثانية) ، مستوى السجل ، اسم مؤشر الترابط ، اسم السجل البسيط (ليس بالاسم الكامل) ، والرسائل. في المسواج ، سيبدو هكذا:
<appender name = "stdout"> <ChoDer> <datple> ٪ d {hh: mm: ss.sss} ٪ -5Level [thread] [٪ logger {0}] ٪ m ٪ n </pattern> </encoder> </espender>لا تحتاج إلى إدراج أسماء الملفات وأسماء الفصول وأرقام الأسطر ، على الرغم من أنها تبدو مفيدة. لقد رأيت أيضًا تسجيلًا فارغًا في الكود:
log.info ("") ؛ نظرًا لأن المبرمج يعتقد أن رقم السطر سيكون جزءًا من تنسيق السجل ، ويعرف أنه إذا ظهرت رسالة السجل الفارغة على السطر 67 من الملف ، فهذا يعني أنه تم مصادقة المستخدم. ليس ذلك فحسب ، فإن أسماء طريقة تسجيل اسم الفئة ، أو أرقام الأسطر لها تأثير كبير على الأداء.
ميزة أكثر تقدماً في إطار التسجيل هي السياق التشخيصي المعين. MDC هي مجرد خريطة محلية لخيط. يمكنك وضع أي أزواج ذات قيمة رئيسية في هذه الخريطة ، بحيث يمكن لجميع سجلات السجل لهذا الموضوع الحصول على معلومات مقابلة من هذه الخريطة كجزء من تنسيق الإخراج.
سجل المعلمات وقيم الإرجاع للطريقة
إذا وجدت خطأ في مرحلة التطوير ، فعادة ما تستخدم مصحح تصحيح لتتبع السبب المحدد. الآن دعنا نقول أنك لن تستخدم مصحح الأخطاء بعد الآن. على سبيل المثال ، نظرًا لأن هذا الخطأ ظهر في بيئة المستخدم قبل بضعة أيام ، كل ما يمكنك الحصول عليه هو بعض السجلات. ماذا يمكنك أن تعرف من هذا؟
إذا اتبعت المبدأ البسيط المتمثل في الطباعة داخل وخارج المعلمات لكل طريقة ، فلن تحتاج إلى مصحح تصحيح على الإطلاق. بالطبع ، يجوز لكل طريقة الوصول إلى أنظمة خارجية ، حظر ، انتظار ، وما إلى ذلك ، ويجب أخذها في الاعتبار. فقط الرجوع إلى التنسيق التالي:
السلسلة العامة printDocument (مستند المستند ، وضع الوضع) {log.debug ("إدخال printDocument (doc = {} ، mode = {})" ، doc ، mode) ؛ معرف السلسلة = ... ؛ // عملية طباعة طويلة log.debug ("ترك printDocument (): {}" ، id) ؛ معرف الإرجاع ؛}نظرًا لأنك تقوم بتسجيل السجلات في بداية ونهاية الطريقة ، يمكنك إيجاد رموز غير فعالة يدويًا ، وحتى اكتشاف الأسباب التي قد تسبب الجمود والجوع - تحتاج فقط إلى معرفة ما إذا لم يكن هناك "ترك" بعد "الدخول". إذا كان معنى اسم الطريقة واضحًا ، فسيكون ذلك أمرًا ممتعًا لمسح السجل. وبالمثل ، فإن تحليل الاستثناءات أسهل لأنك تعرف ما تفعله في كل خطوة. إذا كان هناك العديد من الطرق للتسجيل في الكود ، فيمكنك استخدام أقسام AOP لإكمالها. هذا يقلل من الكود المكررة ، ولكن يجب أن تكون حذراً للغاية عند استخدامه ، وإذا لم تكن حذراً ، فقد يؤدي ذلك إلى كمية كبيرة من إخراج السجل.
المستويات الأكثر ملاءمة لهذا النوع من السجل هي تصحيح الأخطاء والتتبع. إذا وجدت أن الطريقة تسمى بشكل متكرر للغاية وقد تؤثر تسجيل سجلها على الأداء ، فأنت بحاجة فقط إلى خفض مستوى السجل الخاص به ، أو حذف السجل مباشرة (أو واحد فقط من مكالمات الطريقة بأكملها؟) ومع ذلك ، فإن الكثير من السجلات أفضل من أقل من السجلات. فكر في التسجيل كاختبارات للوحدة ، يجب تغطية الكود الخاص بك بسجلات مثلما توجد اختبارات الوحدة في كل مكان. لا يوجد جزء من النظام لا يتطلب أي سجلات على الإطلاق. تذكر أنه في بعض الأحيان تحتاج إلى معرفة ما إذا كان نظامك يعمل بشكل صحيح ، ويمكنك فقط عرض السجلات التي تغمر الشاشة باستمرار.
مراقبة النظم الخارجية
يختلف هذا الاقتراح قليلاً عن الإطار السابق: إذا كنت تتواصل مع نظام خارجي ، تذكر أن تسجل البيانات الصادرة والقراءة الخاصة بنظامك. تكامل النظام هو عمل روتيني ، كما أن تشخيص المشكلات بين تطبيقين (تخيل شركات مختلفة ، بيئات ، فرق فنية) أمر صعب بشكل خاص. لقد وجدنا مؤخرًا أن تسجيل محتوى الرسائل الكامل ، بما في ذلك رؤوس SOAP و HTTP الخاصة بـ Apache CXF ، فعال للغاية أثناء مرحلة تكامل واختبار النظام.
هذا مكلف ، وإذا كان يؤثر على الأداء ، يمكنك فقط إيقاف تشغيل السجل. ولكن بهذه الطريقة ، قد يعمل نظامك بسرعة كبيرة ويتعلق بسرعة ، لذلك لا يمكنك فعل أي شيء حيال ذلك؟ عند الاندماج مع الأنظمة الخارجية ، يمكنك فقط أن تكون حذرًا أكثر من الحذر وأن تكون مستعدًا للتضحية ببعض النفقات العامة. إذا كنت محظوظًا بما فيه الكفاية وتم التعامل مع تكامل النظام من قبل ESB ، فمن الأفضل تسجيل الطلب والاستجابة على الحافلة. يمكنك الرجوع إلى مكون السجل من Mule.
في بعض الأحيان ، تحدد كمية البيانات المتبادلة بالأنظمة الخارجية أنه من المستحيل بالنسبة لك كتابة كل شيء. من ناحية أخرى ، من الأفضل الحفاظ على كل شيء في السجل خلال مرحلة الاختبار ومراحل الإصدار المبكرة وأن تكون مستعدًا للتضحية بالأداء. يمكن القيام بذلك عن طريق ضبط مستوى السجل. ألق نظرة على النصائح التالية:
مجموعة <integer> requestIds = // ... if (log.isdebugenabled ()) log.debug ("معرفات المعالجة: {}" ، requestIds) ؛ log.info ("المعالجة حجم معرفات: {}" ، requestids.size ()) ؛ إذا تم تكوين هذا المسجل إلى مستوى التصحيح ، فإنه يطبع المجموعة الكاملة لمعرفات الطلب. إذا تم تكوينه لطباعة المعلومات ، فسيقوم فقط بإخراج حجم المجموعة. قد تسألني إذا نسيت حالة Isinfoenabled ، يرجى الاطلاع على الاقتراح الثاني. شيء آخر يستحق الإشارة هنا هو أن مجموعة المعرفات لا يمكن أن تكون فارغة. على الرغم من أنه يمكن أن يطبع بشكل طبيعي تحت تصحيح التصحيح بأنه فارغ ، إلا أنه مؤشر فارغ كبير عند تكوينه كمعلومات. تذكر الآثار الجانبية المذكورة في الاقتراح الرابع؟
استثناءات التسجيل الصحيحة
أولاً ، لا تسجل الاستثناءات ، دع الإطار أو الحاوية يقوم بذلك. بالطبع هناك استثناء: إذا قمت بإلقاء استثناءات (RMI ، EJB ، إلخ) من خدمة عن بُعد ، يتم تسلسل الاستثناءات للتأكد من إمكانية إعادتها إلى العميل (جزء من API). خلاف ذلك ، سيتلقى العميل noclassDeffounderror أو استثناء غريب آخر بدلاً من رسالة خطأ حقيقية.
يعد تسجيل الاستثناءات أحد أهم مسؤوليات التسجيل ، لكن العديد من المبرمجين يميلون إلى استخدام التسجيل كوسيلة للتعامل مع الاستثناءات. عادة ما يعيدون القيمة الافتراضية (عادةً ما لاغية ، 0 أو سلسلة فارغة) ، ولا يتظاهرون بأي شيء لم يحدث. في بعض الأحيان ، سيقومون أولاً بتسجيل الاستثناء ، ثم يلفون الاستثناء ثم رميه:
log.error ("IO استثناء" ، ه) ؛ رمي Customexception (E) ؛وبهذه الطريقة ، سيتم عادةً طباعة معلومات المكدس مرتين ، لأن الأماكن التي يتم اكتشاف استثناء MyCustomexception مرة أخرى. سجلات السجل ، أو لفها ورميها ، لا تستخدمها في نفس الوقت ، وإلا فإن السجلات الخاصة بك ستبدو مربكة.
ماذا لو كنا نريد حقًا تسجيل الدخول؟ لسبب ما (من المفترض عدم قراءة واجهات برمجة التطبيقات والتوثيق؟) ، حوالي نصف قطع الأشجار أعتقد أنه خطأ. هل اختبار صغير ، أي من عبارات السجل التالية يمكنها طباعة استثناءات مؤشر فارغ بشكل صحيح؟
حاول {Integer x = null ؛ ++ x ؛} catch (استثناء e) {log.error (e) ؛ // log.error (e ، e) ؛ // B log.error ("" + e) ؛ // c log.error (e.ToString ()) ؛ // d log.error (e.getMessage ()) ؛ // e log.error (null ، e) ؛ // f log.error ("" ، e) ؛ // g log.error ("{}" ، e) ؛ // h log.error ("{}" ، e.getMessage ()) ؛ // i log.error ("خطأ قراءة القراءة:" + e) ؛ // j log.error ("خطأ في قراءة ملف التكوين:" + E.GetMessage ()) ؛ // k log.error ("خطأ في قراءة ملف تكوين" ، E) ؛ // l}من الغريب أن G و L (هذا أفضل) على حق! لا يتم تجميع A و B تحت SLF4J على الإطلاق. سيقوم الآخرون بإبعاد معلومات تتبع المكدس أو طباعة معلومات غير صحيحة. على سبيل المثال ، لا يطبع E أي شيء لأن استثناء مؤشر NULL نفسه لا يوفر أي معلومات استثناء ولا تتم طباعة معلومات المكدس. تذكر أن المعلمة الأولى هي عادة معلومات نصية ، حول الخطأ نفسه. لا تكتب معلومات استثناء فيه. سيخرج تلقائيًا بعد طباعة السجل ، أمام معلومات المكدس. ولكن إذا كنت ترغب في طباعة هذا ، بالطبع عليك نقل الاستثناء إلى المعلمة الثانية.
يجب أن تكون السجلات قابلة للقراءة وسهلة التحليل
الآن هناك مجموعتان من المستخدمين المهتمين بسجلاتك: نحن البشر (سواء كنت توافق أم لا ، المبرمجين موجودون هنا) ، وأجهزة الكمبيوتر (عادةً نصوص الصدفة التي كتبها مسؤولو النظام). يجب أن تكون السجلات مناسبة لكلا المستخدمين لفهمها. إذا نظر شخص ما إلى سجل البرنامج وراءك ورأى هذا:
ثم أنت بالتأكيد لم تتبع نصيحتي. يجب أن تكون السجلات سهلة القراءة وفهمها كرمز.
من ناحية أخرى ، إذا كان برنامجك ينشئ نصف GB من السجلات كل ساعة ، فلا يمكن لأحد أو أي محرر نصوص رسومية إنهاءها. في هذا الوقت ، جاء رجالنا المسنين ، Grep ، Sed و Owk ، عندما جاءوا إلى الميدان. إذا كان ذلك ممكنًا ، فمن الأفضل أن تسجل السجلات لتسجيلها لتسجيلها لكلا الكمبيوتر. لا تقم بتنسيق الأرقام ، استخدم بعض التنسيقات التي تجعلها مطابقة منتظمة ، وما إلى ذلك. إذا لم يكن ذلك ممكنًا ، فقم بطباعة البيانات بتنسيقين:
log.debug ("request ttl set to: {} ({{})" ، تاريخ جديد (ttl) ، ttl) ؛ {} ms ({}) "، mattermillis ، المدة) ؛ // استغرق الاستيراد: 123456789ms (1 يوم 10 ساعات 17 دقيقة 36 ثانية)ترى أجهزة الكمبيوتر "MS بعد عام 1970" أن هذا التنسيق الزمني سيشكرك ، بينما يسعد الناس برؤية شيء مثل "يوم واحد 10 ساعات 17 دقيقة 36 ثانية".
باختصار ، يمكن أيضًا كتابة المجلة بأناقة مثل قصيدة ، إذا كنت على استعداد للتفكير في الأمر.
ما ورد أعلاه عبارة عن مجموعة من المعلومات حول تنسيق إخراج تعديل سجل Java. يمكن للأصدقاء المهتمين الرجوع إليه.