2.1 पहिला लॉगर - log4j

आपल्याला आधीच माहित आहे की, लॉगचा इतिहास System.err.println()कन्सोलवर रेकॉर्डच्या आउटपुटसह सुरू झाला. हे अद्याप डीबगिंगसाठी सक्रियपणे वापरले जाते, उदाहरणार्थ, Intellij IDEA कन्सोलवर त्रुटी संदेश प्रदर्शित करण्यासाठी वापरते. परंतु या पर्यायामध्ये कोणतीही सेटिंग्ज नाहीत, तर चला पुढे जाऊया.

पहिला आणि सर्वात लोकप्रिय लॉगर कॉल केला गेला Log4j. हा एक चांगला आणि अत्यंत सानुकूल करण्यायोग्य उपाय होता. विविध परिस्थितीमुळे, हा निर्णय कधीही JDK मध्ये आला नाही, ज्याने संपूर्ण समुदायाला खूप अस्वस्थ केले.

हा लॉगर फक्त लॉग करण्यास सक्षम नव्हता, तो प्रोग्रामरसाठी प्रोग्रामरद्वारे तयार केला गेला होता आणि त्यांना लॉगिंगच्या संबंधात सतत उद्भवणार्या समस्यांचे निराकरण करण्याची परवानगी दिली होती.

आपल्याला आधीच माहित आहे की, लॉग शेवटी लिहिलेले आहेत जेणेकरून काही व्यक्ती ते वाचतील आणि प्रोग्रामच्या ऑपरेशन दरम्यान काय घडले ते समजून घेण्याचा प्रयत्न करेल - अपेक्षेप्रमाणे काय आणि केव्हा चूक झाली.

log4jयासाठी तीन गोष्टी होत्या :

  • उपपॅकेज लॉगिंग;
  • परिशिष्टांचा संच (परिणाम);
  • हॉट रीलोड सेटिंग्ज.

प्रथम, सेटिंग्ज log4jएका पॅकेजमध्ये लॉगिंग सक्षम करण्यासाठी आणि दुसर्‍या पॅकेजमध्ये अक्षम करण्यासाठी अशा प्रकारे लिहिल्या जाऊ शकतात. उदाहरणार्थ, मध्ये लॉगिंग सक्षम करणे शक्य होते com.codegym.server, परंतु ते अक्षम करा com.codegym.server.payment. यामुळे लॉगमधून अनावश्यक माहिती द्रुतपणे काढणे शक्य झाले.

दुसरे म्हणजे, log4jयाने एकाच वेळी अनेक लॉग फाइल्सवर लॉगिंग परिणाम लिहिण्याची परवानगी दिली. आणि प्रत्येकाचे आउटपुट स्वतंत्रपणे कॉन्फिगर केले जाऊ शकते. उदाहरणार्थ, एका फाईलमध्ये केवळ गंभीर त्रुटींबद्दल माहिती लिहिणे शक्य होते, दुसर्‍यामध्ये - विशिष्ट मॉड्यूलमधील लॉग आणि तिसऱ्यामध्ये - विशिष्ट वेळेसाठी लॉग.

अशा प्रकारे प्रत्येक लॉग फाइल विशिष्ट प्रकारच्या अपेक्षित समस्येसाठी ट्यून केली गेली. हे प्रोग्रामरचे जीवन मोठ्या प्रमाणात सुलभ करते ज्यांना गीगाबाइट लॉग फाइल्स मॅन्युअली पाहण्यात आनंद वाटत नाही.

आणि शेवटी, तिसरे म्हणजे, log4jप्रोग्राम चालू असताना तो रीस्टार्ट न करता थेट लॉग सेटिंग्ज बदलण्याची परवानगी दिली. विशिष्ट त्रुटीवर अतिरिक्त माहिती शोधण्यासाठी लॉगचे कार्य दुरुस्त करणे आवश्यक असताना हे खूप सुलभ होते.

महत्वाचे! लॉगच्या दोन आवृत्त्या आहेत log4j: 1.2.x आणि 2.xx , ज्या एकमेकांशी विसंगत आहेत .

तुम्ही कोड वापरून लॉगरला प्रोजेक्टशी कनेक्ट करू शकता:

<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.2</version>
  </dependency>

  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
  </dependency>
</dependencies>

२.२ पहिला अधिकृत लॉगर - JUL: java.util.logging

जावा समुदायामध्ये लॉगर्सचे प्राणीसंग्रहालय दिसू लागल्यानंतर, विकसकांनी JDKएक मानक लॉगर बनवण्याचा निर्णय घेतला जो प्रत्येकजण वापरेल. अशा प्रकारे लॉगर दिसला JUL: पॅकेज java.util.logging.

तथापि, त्याच्या विकासादरम्यान, लॉगरच्या निर्मात्यांनी आधार म्हणून नव्हे log4jतर IBM कडील लॉगरचा एक प्रकार घेतला, ज्याने त्याच्या विकासावर परिणाम केला. चांगली बातमी अशी आहे की लॉगर JULसमाविष्ट आहे JDK, वाईट बातमी ही आहे की काही लोक ते वापरतात.

जुल

विकासकांनी केवळ “दुसरे सार्वत्रिक मानक”JUL बनवले नाही , तर त्यांनी त्यासाठी त्यांचे स्वतःचे लॉगिंग स्तर देखील बनवले, जे त्या वेळी लोकप्रिय लॉगर्सने स्वीकारलेल्या लोकांपेक्षा वेगळे होते.

आणि ही एक मोठी समस्या होती. तथापि, उत्पादने Javaबर्‍याचदा मोठ्या संख्येने लायब्ररीमधून गोळा केली जातात आणि अशा प्रत्येक लायब्ररीचे स्वतःचे लॉगर होते. त्यामुळे ऍप्लिकेशनमध्ये असलेले सर्व लॉगर कॉन्फिगर करणे आवश्यक होते.

जरी लॉगर स्वतः खूपच चांगला आहे. लॉगर तयार करणे कमी-अधिक प्रमाणात समान आहे. हे करण्यासाठी, आपण आयात करणे आवश्यक आहे:


java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());

लॉगिंग कोठून होत आहे हे जाणून घेण्यासाठी वर्गाचे नाव विशेषतः पास केले जाते.

केवळ रिलीझसह, विकसकांनी महत्त्वपूर्ण समस्या सोडवल्या, ज्यानंतर ते JULवापरणे खरोखर सोयीचे आहे. त्याआधी, हे काही प्रकारचे द्वितीय-दर लॉगर होते.

हा लॉगर लॅम्बडा अभिव्यक्ती आणि आळशी मूल्यांकनास देखील समर्थन देतो. सह प्रारंभ करून Java 8, आपण उत्तीर्ण होऊ शकता Supplier<String>. हे वाचण्यास आणि स्ट्रिंग तयार करण्यास मदत करते जेव्हा त्याची खरोखर गरज असते, आणि प्रत्येक वेळी नाही, जसे पूर्वी होते.

युक्तिवाद असलेल्या पद्धती Supplier<String> msgSupplierयासारख्या दिसतात:

public void info(Supplier msgSupplier) {
   log(Level.INFO, msgSupplier);
}

2.3 प्रथम लॉगर रॅपर - JCL: जकार्ता कॉमन्स लॉगिंग

बर्याच काळापासून लॉगर्समध्ये एकच मानक नव्हते, ते JULएक व्हायला हवे होते, परंतु ते वाईट होते log4j, म्हणून एकच मानक कधीही दिसला नाही. परंतु लॉगर्सचे संपूर्ण प्राणीसंग्रहालय दिसू लागले, ज्यापैकी प्रत्येकाला समान व्हायचे होते.

जेसीएल

तथापि, सामान्य जावा विकसकांना हे आवडले नाही की जवळजवळ प्रत्येक लायब्ररीचे स्वतःचे लॉगर आहे आणि ते कसे तरी विशिष्ट प्रकारे कॉन्फिगर केले जाणे आवश्यक आहे. म्हणून, समुदायाने इतर लॉगर्सवर एक विशेष आवरण तयार करण्याचा निर्णय घेतला - हे असे आहेJCL: jakarta commons logging

आणि पुन्हा, एक नेता होण्यासाठी तयार केलेला प्रकल्प, एक झाला नाही. तुम्ही विजेता तयार करू शकत नाही, तुम्ही फक्त विजेता बनू शकता. कार्यक्षमता JCLखूपच खराब होती आणि कोणीही ते वापरू इच्छित नव्हते. लॉगर, सर्व लॉगर पुनर्स्थित करण्यासाठी डिझाइन केलेले, समान नशीब भेटले कारण ते JULवापरले गेले नाही.

अपाचे समुदायाने प्रसिद्ध केलेल्या अनेक लायब्ररींमध्ये ते जोडले गेले असले तरी, लॉगर्सचे प्राणीसंग्रहालय केवळ वाढले आहे.

2.4 पहिला शेवटचा लॉगर - लॉगबॅक

पण एवढेच नाही. विकसकाने log4jठरवले की तो सर्वात हुशार आहे (तरीही, बहुतेक लोकांनी त्याचा लॉगर वापरला) आणि एक नवीन सुधारित लॉगर लिहिण्याचे ठरवले जे log4jइतर लॉगरचे फायदे एकत्र करेल.

नवीन लॉगरला बोलावले होते Logback. हा लॉगर होता जो भविष्यातील सिंगल लॉगर बनणार होता जो प्रत्येकजण वापरेल. मधील सारख्याच कल्पनेवर ते आधारित होते log4j.

तुम्ही कोड वापरून हा लॉगर प्रोजेक्टशी कनेक्ट करू शकता:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
</dependency>

फरक यात होते Logback:

  • सुधारित कामगिरी;
  • मूळ समर्थन जोडले slf4j;
  • विस्तारित फिल्टरिंग पर्याय.

या लॉगरचा आणखी एक फायदा असा होता की त्यात खूप चांगली डीफॉल्ट सेटिंग्ज होती. आणि जर तुम्हाला त्यात काहीतरी बदलायचे असेल तरच तुम्हाला लॉगर कॉन्फिगर करावे लागेल. तसेच, सेटिंग्ज फाइल कॉर्पोरेट सॉफ्टवेअरमध्ये अधिक चांगल्या प्रकारे रुपांतरित करण्यात आली होती - तिचे सर्व कॉन्फिगरेशन म्हणून सेट केले होते xml/.

डीफॉल्टनुसार, Logbackयास कोणत्याही सेटिंग्जची आवश्यकता नसते आणि पातळी 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>

2.5 नवीनतम युनिव्हर्सल लॉगर - SLF4J: Java साठी साधे लॉगिंग दर्शनी भाग

सोनेरी अर्थ शोधण्यासाठी किती वेळ लागू शकतो...

2006 मध्ये, निर्मात्यांपैकी एकाने log4jप्रकल्प सोडला आणि सार्वत्रिक लॉगर तयार करण्यासाठी पुन्हा प्रयत्न करण्याचा निर्णय घेतला. पण यावेळी हा नवीन लॉगर नव्हता, तर एक नवीन सार्वत्रिक मानक (रॅपर) होता ज्यामुळे वेगवेगळ्या लॉगर्सना एकत्र संवाद साधता आला.

या लॉगरला म्हणतात slf4j — Simple Logging Facade for Java, तो सुमारे एक आवरण होता log4j, JUL, common-loggins and logback. या लॉगरने एक वास्तविक समस्या सोडवली - लॉगर्सचे प्राणीसंग्रहालय व्यवस्थापित करणे, म्हणून प्रत्येकाने त्वरित त्याचा वापर करण्यास सुरवात केली.

आम्ही स्वतःसाठी निर्माण केलेल्या समस्या वीरपणे सोडवतो. जसे आपण पाहू शकता, प्रगती या टप्प्यावर पोहोचली आहे की आम्ही रॅपरवर एक आवरण तयार केले आहे ...

रॅपमध्ये दोन भाग असतात:

  • API, जे अनुप्रयोगांमध्ये वापरले जाते;
  • प्रत्येक लॉगरसाठी स्वतंत्र अवलंबन म्हणून जोडलेली अंमलबजावणी.

तुम्ही कोड वापरून लॉगरला प्रोजेक्टशी कनेक्ट करू शकता:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.17.2</version>
</dependency>

योग्य अंमलबजावणी कनेक्ट करणे पुरेसे आहे आणि तेच आहे: संपूर्ण प्रकल्प त्याच्यासह कार्य करेल.

2.6 slf4j मध्ये ऑप्टिमायझेशन

Slf4jलॉगिंगसाठी स्ट्रिंग फॉरमॅटिंगसारख्या सर्व नवीन वैशिष्ट्यांना समर्थन देते . याआधीही अशी समस्या होती. समजा तुम्हाला लॉगवर संदेश मुद्रित करायचा आहे:

log.debug("User " + user + " connected from " + request.getRemoteAddr());

या कोडमध्ये समस्या आहे. समजा तुमचा ऍप्लिकेशन चालू आहे productionआणि लॉगवर काहीही लिहित नाही DEBUG-messages, तथापि, पद्धत log.debug()अद्याप कॉल केली जाईल, आणि जेव्हा ती कॉल केली जाईल, तेव्हा खालील पद्धती देखील कॉल केल्या जातील:

  • user.toString();
  • request.getRemoteAddr();

या पद्धतींना कॉल केल्याने अनुप्रयोगाची गती कमी होते. त्यांचा कॉल फक्त डीबगिंग दरम्यान आवश्यक आहे, परंतु तरीही त्यांना कॉल केला जातो.

तर्कशास्त्राच्या दृष्टिकोनातून, ही समस्या लॉगिंग लायब्ररीमध्येच सोडवायची होती. आणि log4j च्या पहिल्या आवृत्तीमध्ये समाधान आले:

if (log.isDebugEnabled()) {
    log.debug("User " + user + " connected from " + request.getRemoteAddr());
}

लॉगसाठी एका ओळीऐवजी आता तीन लिहिणे आवश्यक होते. ज्याने कोडची वाचनीयता नाटकीयरित्या खराब केली आणि ची लोकप्रियता कमी केली log4j.

लॉगर slf4jस्मार्ट लॉगिंग ऑफर करून परिस्थिती किंचित सुधारण्यात सक्षम होता. हे असे दिसले:

log.debug("User {} connected from {}", user, request.getRemoteAddr());

जेथे {}पद्धतीमध्ये पास केलेल्या वितर्कांचा अंतर्भाव दर्शवितात. म्हणजेच, पहिला {}वापरकर्त्याशी संबंधित आहे, {}दुसरा request.getRemoteAddr().

हे पॅरामीटर्स एका संदेशात एकत्रित केले जातील जर लॉगिंग पातळी लॉगिंगला परवानगी देत ​​असेल. परिपूर्ण नाही, परंतु इतर सर्व पर्यायांपेक्षा चांगले.

त्यानंतर, SLF4Jते लोकप्रियतेमध्ये वेगाने वाढू लागले, याक्षणी हा सर्वोत्तम उपाय आहे.

म्हणून, आम्ही बंडलचे उदाहरण वापरून लॉगिंग करण्याचा विचार करू slf4j-log4j12.