JavaRush /مدونة جافا /Random-AR /تسجيل الدخول إلى جافا: ماذا وكيف وأين وبماذا؟
Roman Beekeeper
مستوى

تسجيل الدخول إلى جافا: ماذا وكيف وأين وبماذا؟

نشرت في المجموعة
مرحبًا بالجميع، مجتمع JavaRush! اليوم سنتحدث عن تسجيل جافا:
  1. ما هذا، لماذا هو. في أي الحالات يكون من الأفضل استخدامها وفي أي الحالات لا؟
  2. ما هي أنواع تطبيقات التسجيل الموجودة في Java وماذا يجب أن نفعل بهذا التنوع؟
  3. مستويات التسجيل. دعونا نناقش ما هو المُلحق وكيفية تكوينه بشكل صحيح.
  4. عقد التسجيل وكيفية تكوينها بشكل صحيح بحيث يعمل كل شيء بالطريقة التي نريدها.
هذه المادة مخصصة لجمهور واسع. سيكون الأمر واضحًا لأولئك الذين تعرفوا للتو على Java ولأولئك الذين يعملون بالفعل، لكنهم اكتشفوا ذلك فقط من خلال logger.info(“log something”); Let's Go!

لماذا هناك حاجة للتسجيل؟

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

أدوات تسجيل جافا

التسجيل: ماذا وكيف وأين وبماذا؟  - 2تتضمن الحلول المعروفة لتسجيل الدخول إلى Java ما يلي:
  • log4j
  • يوليو - java.util.logging
  • JCL - تسجيل جاكرتا كومونز
  • تسجيل الدخول مرة أخرى
  • SLF4J - واجهة تسجيل بسيطة لجافا
دعونا نلقي نظرة سريعة على كل واحد منهم، وفي الجزء العملي من المادة سنأخذ الاتصال Slf4j - log4j كأساس . قد يبدو هذا غريبًا الآن، لكن لا تقلق: بحلول نهاية المقال سيكون كل شيء واضحًا.

System.err.println

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

Log4j

لقد كان هذا بالفعل حلاً متكاملاً تم إنشاؤه بناءً على احتياجات المطورين. وتبين أنها أداة مثيرة للاهتمام حقًا للاستخدام. نظرًا لظروف مختلفة، لم يصل هذا الحل أبدًا إلى JDK، مما أزعج المجتمع بأكمله بشكل كبير. يحتوي log4j على خيارات تكوين بحيث يمكن تشغيل التسجيل في حزمة com.example.typeوإيقاف تشغيله في حزمة فرعية com.example.type.generic. هذا جعل من الممكن فصل ما يجب تسجيله بسرعة عما لم يكن مطلوبًا. من المهم أن نلاحظ هنا أن هناك إصدارين من log4j: 1.2.x و2.x.x، وهما غير متوافقين مع بعضهما البعض . أضاف log4j مفهومًا مثل المُلحق ، أي أداة يتم من خلالها تسجيل السجلات وتنسيق السجل. يتيح لك هذا تسجيل ما تحتاجه فقط وكيف تحتاجه. سنتحدث أكثر عن المُلحق بعد قليل.

يوليو - java.util.logging

أحد المزايا الرئيسية هو الحل - تم تضمين JUL في JDK (مجموعة تطوير Java). لسوء الحظ، أثناء تطويره، لم يتم أخذ log4j الشهير كأساس، ولكن الحل من IBM هو الذي أثر على تطويره. في الواقع، يوجد حاليًا JUL، لكن لا أحد يستخدمه. من "هكذا": في JUL تختلف مستويات التسجيل عما هو موجود في Logback وLog4j وSlf4j، وهذا يزيد من سوء التفاهم بينهما. إنشاء المسجل يشبه إلى حد ما. للقيام بذلك تحتاج إلى استيراد:
java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());
يتم تمرير اسم الفئة خصيصًا لمعرفة مصدر التسجيل. منذ Java 8، من الممكن تمرير Supplier<String>. يساعد هذا في حساب وإنشاء سلسلة فقط في اللحظة التي تكون هناك حاجة إليها حقًا، وليس في كل مرة، كما كان من قبل. فقط مع إصدار Java 8 تمكن المطورون من حل المشكلات المهمة، وبعد ذلك أصبح JUL قابلاً للاستخدام حقًا. وهي الأساليب ذات الوسيطة Supplier<String> msgSupplierكما هو موضح أدناه:
public void info(Supplier<String> msgSupplier) {
   log(Level.INFO, msgSupplier);
}

JCL - تسجيل جاكرتا كومونز

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

تسجيل الدخول مرة أخرى

كم هو شائك طريق المصادر المفتوحة... تمت كتابة Logback بواسطة نفس المطور مثل log4j لإنشاء خليفة له. كانت الفكرة هي نفس فكرة log4j. كانت الاختلافات في تسجيل الدخول:
  • تحسين الأداء؛
  • تمت إضافة دعم أصلي لـ slf4j؛
  • تم توسيع خيار التصفية.
افتراضيًا، لا يتطلب تسجيل الدخول أي إعدادات ويسجل جميع السجلات من مستوى DEBUG وما فوق. إذا كانت هناك حاجة إلى التكوين، فيمكن القيام بذلك عبر تكوين XML:
<configuration>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>app.log</file>
        <encoder>
            <pattern>%d{HH:mm:ss,SSS} %-5p [%c] - %m%n</pattern>
        </encoder>
    </appender>
    <logger name="org.hibernate.SQL" level="DEBUG" />
    <logger name="org.hibernate.type.descriptor.sql" level="TRACE" />
    <root level="info">
        <appender-ref ref="FILE" />
    </root>
</configuration>

SLF4J - واجهة تسجيل بسيطة لجافا

في عام 2006 تقريبًا، ترك أحد الآباء المؤسسين لـ log4j المشروع وأنشأ slf4j - واجهة تسجيل بسيطة لـ Java - عبارة عن غلاف حول log4j وJUL وتسجيلات الدخول المشتركة وتسجيل الدخول مرة أخرى. كما ترون، وصل التقدم إلى النقطة التي قاموا فيها بإنشاء غلاف فوق الغلاف... علاوة على ذلك، فهو مقسم إلى قسمين: واجهة برمجة التطبيقات (API) التي يتم استخدامها في التطبيق، والتنفيذ، والذي يتم إضافته كـ تبعيات منفصلة لكل نوع من التسجيل. على سبيل المثال، slf4j-log4j12.jar، slf4j-jdk14.jar. يكفي توصيل التنفيذ الصحيح وهذا كل شيء: سيعمل المشروع بأكمله معه. يدعم Slf4j جميع الميزات الجديدة مثل تنسيق السلسلة للتسجيل. كانت هناك مثل هذه المشكلة من قبل. لنفترض أن هناك إدخال سجل:
log.debug("User " + user + " connected from " + request.getRemoteAddr());
userيوجد تحويل ضمني في الكائن user.toString()بسبب تسلسل السلسلة، وهذا يستغرق وقتًا، مما يؤدي إلى إبطاء النظام. وكل شيء على ما يرام إذا قمنا بتصحيح التطبيق. تبدأ المشاكل إذا كان مستوى التسجيل لهذه الفئة هو INFO وأعلى. أي أنه لا ينبغي تدوين هذا السجل، كما لا ينبغي إجراء تسلسل السلسلة. من الناحية النظرية، كان ينبغي أن تقرر مكتبة التسجيل نفسها هذا الأمر. علاوة على ذلك، تبين أن هذه هي أكبر مشكلة في الإصدار الأول من log4j. لم يقدموا حلاً عاديًا، لكنهم اقترحوا القيام بذلك على النحو التالي:
if (log.isDebugEnabled()) {
    log.debug("User " + user + " connected from " + request.getRemoteAddr());
}
أي أنه بدلاً من سطر تسجيل واحد، اقترحوا كتابة 3(!). يجب أن يقلل التسجيل من التغييرات في الكود، ومن الواضح أن ثلاثة أسطر تتعارض مع النهج العام. لم يواجه slf4j أي مشاكل في التوافق مع JDK وAPI، لذا ظهر حل جميل على الفور:
log.debug("User {} connected from {}", user, request.getRemoteAddr());
حيث {}تشير إلى إدخالات الوسائط التي تم تمريرها في الطريقة. أي أن الأول {}يتوافق مع userالثاني {}- request.getRemoteAddr(). ونتيجة لذلك، فقط إذا كان مستوى التسجيل يسمح بالتسجيل في السجل، فيمكن دمج هذه الرسالة في رسالة واحدة. بعد ذلك، زادت شعبية SJF4J بسرعة وهو الحل الأفضل حاليًا. لذلك، سننظر في التسجيل باستخدام مثال الحزمة slf4j-log4j12.

ما يجب تسجيله

وبطبيعة الحال، لا ينبغي عليك تسجيل كل شيء. في بعض الأحيان يكون هذا غير ضروري بل وخطير. على سبيل المثال، إذا تعهدت ببيانات شخصية لشخص ما وتم الكشف عنها بطريقة أو بأخرى، فستكون هناك مشاكل حقيقية، خاصة في المشاريع الموجهة نحو الغرب. ولكن هناك أيضًا شيء إلزامي لتسجيل الدخول :
  1. بداية/نهاية التطبيق. علينا أن نعرف أن التطبيق بدأ بالفعل كما توقعنا وانتهى كما توقعنا.
  2. اسئلةالأمان. سيكون من الجيد هنا تسجيل محاولات تخمين كلمة المرور، وتسجيل تسجيلات دخول المستخدمين المهمين، وما إلى ذلك.
  3. بعض حالات التطبيق . على سبيل المثال، الانتقال من حالة إلى أخرى في عملية تجارية.
  4. بعض المعلومات لتصحيح الأخطاء بمستوى مناسب من التسجيل.
  5. بعض البرامج النصية SQL. هناك حالات حقيقية عندما تكون هناك حاجة لذلك. مرة أخرى، من خلال ضبط المستويات بمهارة، يمكن تحقيق نتائج ممتازة.
  6. يمكن تسجيل الخيوط المنفذة (Thread) في الحالات التي يتم فيها التحقق من العملية الصحيحة.

أخطاء التسجيل الشائعة

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

مستويات التسجيل

س: مرئية
مميت خطأ تحذير معلومات تصحيح يتعقب الجميع
عن
مميت س
خطأ س س
تحذير س س س
معلومات س س س س
تصحيح س س س س س
يتعقب س س س س س س
الجميع س س س س س س س
ما هي مستويات التسجيل؟ من أجل ترتيب السجلات بطريقة أو بأخرى، كان من الضروري إعطاء بعض التسميات والتمييزات. ولهذا الغرض، تم تقديم مستويات التسجيل. يتم تحديد المستوى في التطبيق. إذا كان الإدخال ينتمي إلى مستوى أقل من المستوى المحدد، فلن يتم إدخاله في السجل. على سبيل المثال، لدينا سجلات تُستخدم لتصحيح أخطاء التطبيق. في أعمال الإنتاج العادية (عند استخدام التطبيق للغرض المقصود منه)، لا تكون هناك حاجة لمثل هذه السجلات. لذلك، سيكون مستوى التسجيل أعلى من مستوى التصحيح. دعونا نلقي نظرة على المستويات باستخدام log4j كمثال. تستخدم الحلول الأخرى، باستثناء JUL، نفس المستويات. وهنا هم في ترتيب تنازلي:
  • OFF: لا تتم كتابة أي سجلات، وسيتم تجاهل كل شيء؛
  • فادح: خطأ لن يتمكن التطبيق بعده من العمل وسيتم إيقافه، على سبيل المثال، خطأ نفاد الذاكرة في JVM؛
  • خطأ: معدل الخطأ عندما تكون هناك مشاكل تحتاج إلى حل. الخطأ لا يوقف التطبيق ككل. قد تعمل الاستعلامات الأخرى بشكل صحيح؛
  • تحذير: يشير إلى السجلات التي تحتوي على تحذير. حدث إجراء غير متوقع، ورغم ذلك قاوم النظام وأكمل الطلب؛
  • INFO: سجل يسجل الإجراءات المهمة في التطبيق. هذه ليست أخطاء، هذه ليست تحذيرات، هذه هي الإجراءات المتوقعة من النظام؛
  • DEBUG: السجلات اللازمة لتصحيح التطبيق. للتأكد من أن النظام يفعل بالضبط ما هو متوقع منه، أو لوصف إجراء النظام: "بدأت الطريقة 1 في العمل"؛
  • TRACE: سجلات ذات أولوية أقل لتصحيح الأخطاء، مع أدنى مستوى للتسجيل؛
  • الكل: المستوى الذي سيتم فيه تسجيل كافة السجلات من النظام.
اتضح أنه إذا تم تمكين مستوى تسجيل المعلومات في مكان ما في التطبيق، فسيتم تسجيل جميع المستويات، بدءًا من المعلومات وحتى فادحًا. إذا كان مستوى التسجيل فادحًا، فسيتم تسجيل السجلات بهذا المستوى فقط.

تسجيل وإرسال السجلات: Appender

سننظر في هذه العملية باستخدام log4j كمثال: فهو يوفر فرصًا كبيرة لتسجيل/إرسال السجلات:
  • للكتابة إلى ملف - الحل DailyRollingFileAppender ؛
  • لتلقي البيانات في وحدة تحكم التطبيق - ConsoleAppender ؛
  • لكتابة السجلات إلى قاعدة البيانات - JDBCAppender ؛
  • للتحكم في الإرسال عبر TCP/IP - TelnetAppender ؛
  • للتأكد من أن التسجيل لا يؤثر على الأداء - AsyncAppender .
هناك العديد من التطبيقات الأخرى: يمكن العثور على القائمة الكاملة هنا . بالمناسبة، إذا لم يكن المُلحق المطلوب متاحًا، فهذه ليست مشكلة. يمكنك كتابة المُلحق الخاص بك عن طريق تنفيذ واجهة المُلحق ، التي تقبل log4j فقط.

عقد التسجيل

سنستخدم في العرض التوضيحي واجهة slf4j والتنفيذ من log4j. يعد إنشاء المسجل أمرًا بسيطًا للغاية: تحتاج إلى كتابة ما يلي في فئة تسمى MainDemo، حيث سيتم إجراء التسجيل:
org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(MainDemo.class);
سيؤدي هذا إلى إنشاء مسجل لنا. لإجراء إدخال سجل، يمكنك استخدام العديد من الطرق التي تشير إلى المستوى الذي سيتم إدخال الإدخالات فيه. على سبيل المثال:
logger.trace("Method 1 started with argument={}", argument);
logger.debug("Database updated with script = {}", script);
logger.info("Application has started on port = {}", port);
logger.warn("Log4j didn't find log4j.properties. Please, provide them");
logger.error("Connection refused to host = {}", host);
على الرغم من أننا تجاوزنا الفصل، إلا أنه في النهاية يتم كتابة الاسم الكامل للفصل مع الحزم. يتم ذلك بحيث يمكنك بعد ذلك تقسيم التسجيل إلى عقد، وتكوين مستوى التسجيل والمُلحق لكل عقدة. على سبيل المثال اسم الفئة: com.github.romankh3.logginglecture.MainDemo- تم إنشاء مسجل فيها. وهذه هي الطريقة التي يمكن تقسيمها إلى عقد تسجيل. العقدة الرئيسية هي RootLogger الفارغة . هذه هي العقدة التي تستقبل كافة سجلات التطبيق بأكمله. يمكن تصوير الباقي كما هو موضح أدناه: التسجيل: ماذا وكيف وأين وبماذا؟  - 4يقوم المُلحقون بتكوين عملهم خصيصًا على عقد التسجيل. الآن، باستخدام log4j.properties كمثال ، سننظر في كيفية تكوينها.

تكوين Log4j.properties خطوة بخطوة

سنقوم الآن بإعداد كل شيء خطوة بخطوة ونرى ما يمكن فعله:
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
يشير هذا السطر إلى أننا نقوم بتسجيل مُلحق CONSOLE الذي يستخدم تطبيق org.apache.log4j.ConsoleAppender. يقوم هذا المُلحق بكتابة البيانات إلى وحدة التحكم. بعد ذلك، لنسجل مُلحقًا آخر سيكتب في ملف:
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
من المهم ملاحظة أن المُلحقات ستظل بحاجة إلى التهيئة. بمجرد أن يكون لدينا مُلحقون مسجلون بالفعل، يمكننا تحديد مستوى التسجيل في العقد وأي المُلحقين سيتم استخدامه.

log4j.rootLogger=تصحيح الأخطاء، وحدة التحكم، ملف

  • يعني log4j.rootLogger أننا سنقوم بتكوين العقدة الرئيسية التي تحتوي على كافة السجلات؛
  • بعد علامة المساواة، تشير الكلمة الأولى إلى أي مستوى سيتم تسجيل السجلات وأعلى (في حالتنا، هذا هو التصحيح)؛
  • ثم بعد الفاصلة تتم الإشارة إلى جميع المُلحقات التي سيتم استخدامها.
لتكوين عقدة تسجيل معينة، تحتاج إلى استخدام الإدخال التالي:
log4j.logger.com.github.romankh3.logginglecture=TRACE, OWN, CONSOLE
حيث log4j.logger.يتم استخدامه لتكوين عقدة معينة، وهو في حالتنا. com.github.romankh3.logginglecture. والآن دعونا نتحدث عن إعداد مُلحق CONSOLE:
# CONSOLE appender customisation
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.threshold=DEBUG
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] : %c:%L : %m%n
نرى هنا أنه يمكننا تحديد المستوى الذي سيعالج المُلحق منه. الوضع الحقيقي: استقبلت عقدة التسجيل رسالة بمستوى المعلومات وتم تمريرها إلى المُلحق المخصص لها، لكن المُلحق، بمستوى التحذير والأعلى، قبل هذا السجل، لكنه لم يفعل شيئًا به. بعد ذلك، عليك أن تقرر القالب الذي سيكون في الرسالة. أنا أستخدم PatternLayout في المثال، ولكن هناك العديد من الحلول المتاحة. لن يتم الكشف عنها في هذه المقالة. مثال على إعداد مُلحق الملف:
# File appender customisation
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=./target/logging/logging.log
log4j.appender.FILE.MaxFileSize=1MB
log4j.appender.FILE.threshold=DEBUG
log4j.appender.FILE.MaxBackupIndex=2
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[ %-5p] - %c:%L - %m%n
هنا يمكنك تكوين الملف الذي سيتم كتابة السجلات إليه، كما يتبين من ذلك
log4j.appender.FILE.File=./target/logging/logging.log
التسجيل يذهب إلى الملف logging.log. لتجنب مشاكل حجم الملف، يمكنك تعيين الحد الأقصى: في هذه الحالة، 1 ميغابايت. MaxBackupIndex - يخبرنا بعدد هذه الملفات التي ستكون موجودة. إذا تم إنشاء أكثر من هذا الرقم، فسيتم حذف الملف الأول. لإلقاء نظرة على مثال حقيقي حيث تم تكوين التسجيل، يمكنك الانتقال إلى المستودع المفتوح على GitHub.

دعونا ندمج النتيجة

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

دعونا نلخص ذلك

  1. تحدثنا عن الحلول الموجودة في Java.
  2. تمت كتابة جميع مكتبات التسجيل المعروفة تقريبًا تحت سيطرة شخص واحد:D
  3. لقد تعلمنا ما يجب تسجيله وما لا يجب تسجيله.
  4. لقد اكتشفنا مستويات التسجيل.
  5. تعرفنا على عقد التسجيل.
  6. لقد نظرنا إلى ما هو الملحق وما هو الغرض منه.
  7. قمنا بتكوين ملف log4j.proterties خطوة بخطوة.

مواد إضافية

  1. جافا راش: التسجيل. قم بفك كرة من السكتريس
  2. JavaRush: محاضرة المسجل
  3. حبر: تسجيل جافا. مرحبا بالعالم
  4. حبر: تسجيل جافا: قصة كابوس
  5. يوتيوب: دورات Golovach. تسجيل. الجزء 1 ، الجزء 2 ، الجزء 3 ، الجزء 4
  6. Log4j: المُلحق
  7. Log4j: التخطيط
أنظر أيضا مقالاتي الأخرى:
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION