"ओह, तुम वहाँ हो! क्या आपको याद है कि आज हमारे पास एक और सबक है?"

"नहीं, मैं बस तुम्हें ढूंढ रहा था। लगभग ..."

"बहुत बढ़िया, तो चलिए शुरू करते हैं। आज मैं आपको लॉगिंग के बारे में बताना चाहता हूँ।"

"लॉग उन घटनाओं की एक सूची है जो घटित हुई हैं। लगभग एक जहाज के लॉग या डायरी की तरह। या ट्विटर - शायद आप उससे बेहतर तरीके से संबंधित हो सकते हैं। अप्रत्याशित रूप से, एक लकड़हारा एक वस्तु है जिसे आप लॉगिंग के लिए उपयोग करते हैं।"

"प्रोग्रामिंग में, लगभग सब कुछ लॉग करने की प्रथा है। और जावा में, हम सब कुछ लॉग करते हैं और थोड़ा और भी।"

"तथ्य यह है कि जावा प्रोग्राम अक्सर यूआई, कंसोल इत्यादि के बिना बड़े सर्वर अनुप्रयोग होते हैं। वे एक ही समय में हजारों उपयोगकर्ता अनुरोधों को संसाधित करते हैं, और अक्सर विभिन्न त्रुटियां होती हैं। विशेष रूप से जब विभिन्न धागे एक-दूसरे के साथ हस्तक्षेप करना शुरू करते हैं।"

"वास्तव में, इन परिस्थितियों में शायद ही कभी पुनरुत्पादित बग और विफलताओं की खोज करने का एकमात्र तरीका प्रत्येक धागे पर होने वाली हर चीज को लॉग करना है।"

"अक्सर, लॉग में विधि तर्कों, किसी भी पकड़ी गई त्रुटियों और बहुत सारी मध्यवर्ती जानकारी के बारे में जानकारी होती है।"

"लॉग जितना अधिक पूर्ण होगा, घटनाओं के अनुक्रम को पुन: उत्पन्न करना और विफलताओं या बग के कारणों को ट्रैक करना उतना ही आसान होगा।"

"कभी-कभी लॉग प्रति दिन कई गीगाबाइट तक पहुँच जाते हैं। यह सामान्य है।"

"कुछ गीगाबाइट? O_o"

"हाँ। प्राय:, प्रासंगिक तिथि के संकेत के साथ, लॉग फ़ाइलें स्वचालित रूप से संग्रहीत की जाती हैं।"

"वाह।"

"उह-हुह। प्रारंभ में, जावा का अपना लकड़हारा नहीं था। परिणामस्वरूप, कई स्वतंत्र लकड़हारे लिखे गए थे। इनमें से सबसे आम था log4j।"

"कुछ साल बाद, जावा को अपना खुद का लकड़हारा मिला, लेकिन इसकी कार्यक्षमता बहुत कम थी और इसका व्यापक रूप से उपयोग नहीं किया गया था।"

"यह एक तथ्य है कि जावा का एक आधिकारिक लकड़हारा है, लेकिन जावा प्रोग्रामर का पूरा समुदाय अन्य लकड़हारे का उपयोग करना पसंद करता है। "

"बाद में, log4j के आधार पर कई और लकड़हारे लिखे गए।"

"तब विशेष सार्वभौमिक लकड़हारा slf4j, जो अब व्यापक रूप से उपयोग किया जाता है, उन सभी के लिए लिखा गया था। यह log4j के समान है, इसलिए मैं इसे एक उदाहरण के रूप में उपयोग करूँगा जब लॉगिंग की व्याख्या करेंगे।"

"संपूर्ण लॉगिंग प्रक्रिया में तीन भाग होते हैं।"

" पहले , जानकारी इकट्ठा करो।"

" दूसरा , एकत्रित जानकारी को फ़िल्टर करें।"

" तीसरा , चयनित जानकारी रिकॉर्ड करें।"

"चलिए संग्रह के साथ शुरू करते हैं। यहाँ एक वर्ग का एक विशिष्ट उदाहरण है जो लॉग करता है:"

लॉगिंग के साथ वर्ग
class Manager
{
 private static final Logger logger = LoggerFactory.getLogger(Manager.class);

 public boolean processTask(Task task)
 {
  logger.debug("processTask id = " + task.getId());
  try
  {
   task.start();
   task.progress();
   task.complete();
   return true;
  }
  catch(Exception e)
  {
   logger.error("Unknown error", e);
   return false;
  }
 }
}

"लाल रंग में हाइलाइट किए गए शब्दों पर ध्यान दें।"

" पंक्ति 3 - लकड़हारा ऑब्जेक्ट  बनाएं । ऐसी स्थिर वस्तु लगभग हर वर्ग में बनाई जाती है! ठीक है, उन वर्गों को छोड़कर जो स्टोर डेटा के अलावा कुछ नहीं करते हैं।"

" लॉगरफैक्टरी लॉगर बनाने के लिए एक विशेष वर्ग है, और गेटलॉगर इसकी स्थिर विधियों में से एक है। वर्तमान वस्तु आमतौर पर पारित हो जाती है, लेकिन विभिन्न विकल्प संभव हैं।"

" पंक्ति 7 - विधि कॉल के बारे में जानकारी लॉगर को लिखी जाती है। ध्यान दें कि यह विधि की पहली पंक्ति है। जैसे ही विधि को कॉल किया जाता है, हम तुरंत लॉग को जानकारी लिखते हैं।"

"हम डिबग विधि कहते हैं, जिसका अर्थ है कि सूचना का महत्व DEBUG स्तर है। इसका उपयोग फ़िल्टरिंग के लिए किया जाता है। मैं आपको इसके बारे में कुछ मिनटों में बताऊंगा।"

" पंक्ति 17 - हम एक अपवाद पकड़ते हैं और... इसे तुरंत लॉग में लिख देते हैं! ठीक यही करने की आवश्यकता है।"

"इस बार हम त्रुटि विधि कहते हैं, जो तुरंत इंगित करता है कि जानकारी त्रुटि स्तर है"

लकड़हारा - 1

"अभी के लिए सब कुछ स्पष्ट लग रहा है। खैर, जहाँ तक हमारी बातचीत के बीच में यह स्पष्ट हो सकता है।"

"बहुत बढ़िया, तो चलिए संदेश फ़िल्टरिंग पर चलते हैं।"

"आमतौर पर, प्रत्येक लॉग संदेश का अपना महत्व स्तर होता है, जिसका उपयोग आप कुछ संदेशों को छोड़ने के लिए कर सकते हैं। यहाँ महत्व के स्तर हैं जिनका मैंने उल्लेख किया है:"

महत्व स्तर विवरण
सभी सभी संदेश
पता लगाना सूक्ष्म डिबग संदेश
डीबग महत्वपूर्ण डिबग संदेश
जानकारी सूचनात्मक संदेश
चेतावनी देना चेतावनी
गलती त्रुटियाँ
घातक घातक त्रुटियाँ
बंद कोई संदेश नहीं

संदेशों को फ़िल्टर करते समय भी इन स्तरों का उपयोग किया जाता है।

मान लीजिए कि आपने लॉगिंग स्तर को WARN पर सेट किया है। फिर वे सभी संदेश जो WARN से कम महत्वपूर्ण हैं, हटा दिए जाएंगे: TRACE, DEBUG, INFO।

यदि आप फ़िल्टरिंग स्तर को FATAL पर सेट करते हैं, तो ERROR संदेशों को भी छोड़ दिया जाएगा।

"फ़िल्टरिंग करते समय दो और महत्वपूर्ण स्तरों का उपयोग किया जाता है: OFF, जो सभी संदेशों को छोड़ देता है; और ALL, जो सभी संदेशों को दिखाता है (कुछ भी नहीं छोड़ा जाता है)।"

"मैं फ़िल्टरिंग कैसे और कहाँ सेट करूँ?"

"मैं आपको आगे की हलचल के बिना बताता हूँ।"

"आमतौर पर, log4j लकड़हारा सेटिंग्स को log4j.properties फ़ाइल में निर्दिष्ट किया जाता है।"

आप इस फ़ाइल में एकाधिक एपेंडर ऑब्जेक्ट निर्दिष्ट कर सकते हैं। इन वस्तुओं को डेटा लिखा जाता है। डेटा स्रोत हैं, और परिशिष्ट हैं - ऐसी वस्तुएं जिनके विपरीत उद्देश्य हैं। ऐसी वस्तुएँ जिनमें डेटा पानी की तरह बहता है।

"यहां कुछ उदाहरण दिए गए हैं:"

कंसोल में लॉगिंग
# Root logger option
log4j.rootLogger = INFO, stdout

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

पंक्तियाँ 1 और 4 - ये टिप्पणियाँ हैं

पंक्ति 2 - हम वांछित लॉगिंग स्तर इंगित करते हैं। सभी कम महत्वपूर्ण स्तरों (DEBUG, TRACE) को छोड़ दिया जाएगा।

उसी स्थान पर, हम एक अल्पविराम जोड़ते हैं और फिर उस वस्तु का नाम इंगित करते हैं (जो हम स्वयं के साथ आते हैं) जिसके लिए लॉग लिखा जाएगा। लाइन्स 5-9 में इसकी सेटिंग्स हैं।

पंक्ति 5 - हम परिशिष्ट के प्रकार ( ConsoleAppender ) को निर्दिष्ट करते हैं।

पंक्ति 6 ​​- हम ठीक वही बताते हैं जहाँ हम लिख रहे हैं ( System.out. ) ।

पंक्ति 7 - हम उस वर्ग को सेट करते हैं जो प्रबंधक रूपांतरण पैटर्न (PatternLayout) होगा।

लाइन 8 - हम रूपांतरण पैटर्न सेट करते हैं जिसका उपयोग लेखन के लिए किया जाएगा। उपरोक्त उदाहरण में, यह दिनांक और समय है।

"और यहाँ एक फ़ाइल में लिखना कैसा दिखता है:"

फ़ाइल में लॉग इन करना
# Root logger option
log4j.rootLogger = INFO, file

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

"लाइन 2 संदेश फ़िल्टरिंग स्तर और एपेंडर ऑब्जेक्ट (सिंक) का नाम सेट करता है।"

"पंक्ति 5 - हम फ़ाइल एपेंडर प्रकार ( रोलिंगफाइलएपेंडर ) निर्दिष्ट करते हैं।"

"पंक्ति 6 ​​- हम उस फ़ाइल का नाम निर्दिष्ट करते हैं जिस पर लॉग लिखा जाएगा।"

"पंक्ति 7 - हम अधिकतम लॉग आकार निर्दिष्ट करते हैं। जब यह आकार सीमा पार हो जाती है, तो एक नई फ़ाइल बनाई जाती है।"

"पंक्ति 8 - हम संग्रहित की जाने वाली पुरानी लॉग फ़ाइलों की संख्या निर्दिष्ट करते हैं।"

"लाइन्स 9-10 - रूपांतरण पैटर्न सेट करें।"

"मुझे नहीं पता कि यहाँ क्या हो रहा है, लेकिन मैं अनुमान लगा सकता हूँ। यह उत्साहजनक है।"

"यह बहुत अच्छा है। फिर यहाँ एक फ़ाइल और कंसोल में लॉग लिखने का एक उदाहरण दिया गया है:"

कंसोल और एक फ़ाइल में लॉग इन करना
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

"आह, तो आप ऐसा कर सकते हैं? यह बहुत अच्छा है!"

"हां। आप जितने चाहें उतने परिशिष्ट घोषित कर सकते हैं और प्रत्येक को अनुकूलित कर सकते हैं।"

इसके अलावा, प्रत्येक एपेंडर में संदेश फ़िल्टरिंग के लिए बहुत ही लचीली सेटिंग्स हो सकती हैं। न केवल हम प्रत्येक परिशिष्ट के लिए एक व्यक्तिगत संदेश फ़िल्टरिंग स्तर निर्दिष्ट कर सकते हैं, बल्कि हम पैकेज द्वारा संदेशों को फ़िल्टर भी कर सकते हैं! इसलिए लकड़हारा बनाते समय आपको एक वर्ग निर्दिष्ट करने की आवश्यकता होती है (मैं LoggerFactory.getLogger के बारे में बात कर रहा हूं )।

"उदाहरण के लिए:"

कंसोल और एक फ़ाइल में लॉग इन करना
# Root logger option
log4j.rootLogger = INFO, file, stdout

# Direct log messages to a log file
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.threshold = DEBUG
log4j.appender.file.File = C:\\loging.log
log4j.appender.file.MaxFileSize = 1MB
log4j.appender.file.MaxBackupIndex = 1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-5p %c{1}:%L - %m%n

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.threshold = ERROR
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}

log4j.logger.org.springframework = ERROR
log4j.logger.org.hibernate = ERROR
log4j.logger.com.codegym = DEBUG
log4j.logger.org.apache.cxf = ERROR

"पंक्तियाँ 6 और 15 - हम प्रत्येक परिशिष्ट के लिए अपना स्वयं का फ़िल्टरिंग स्तर निर्धारित करते हैं।"

"लाइन्स 20-23 - हम इसके संदेशों के लिए पैकेज का नाम और फ़िल्टरिंग स्तर निर्दिष्ट करते हैं। Log4j.logger एक उपसर्ग है: पैकेज का नाम नारंगी रंग में हाइलाइट किया गया है।"

"सचमुच? आप भी ऐसा कर सकते हैं। अच्छा, बढ़िया!"

"वैसे, JDK में न तो log4j और न ही slf4j शामिल हैं। आपको उन्हें अलग से डाउनलोड करने की आवश्यकता होगी। आप इसे यहां कर सकते हैं । लेकिन एक और तरीका है:"

" चरण 1। वर्ग में आयात जोड़ें:"

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

" चरण 2। कर्सर को इन पंक्तियों पर रखें और IntelliJ IDEA में Alt+Enter दबाएं"

" चरण 3। 'फ़ाइल जार ऑन वेब» मेनू आइटम चुनें।'

" चरण 4। 'slf4j-log4j13.jar' चुनें"

" चरण 5। निर्दिष्ट करें कि पुस्तकालय (जार) को कहाँ डाउनलोड करना है"

" चरण 6। अपनी जरूरत की कक्षाओं का उपयोग करें।"

"वाह! यह कितना अच्छा दिन रहा है। इतना कुछ नया है और बहुत कुछ अच्छा है!"

"यहां लॉगिंग पर एक और अच्छा लेख है: https://docs.oracle.com/javase/10/core/java-logging-overview.htm#JSOR-GUID-48004124-2C00-49F7-A640-0C0DDA271DBC "

"ठीक है, यह काफी है। जाओ आराम करो, प्रोग्रामर।"