जावा लॉगिंग: एक बुरा सपना कहानी

प्रविष्टि



फ़ाइलों को लॉग करने के लिए लाइनों को लिखने के सही तरीके के लिए जावा प्लेटफॉर्म का कांटेदार और यातनापूर्ण रास्ता। जावा में लॉगिंग का इतिहास ओपन सोर्स की सुविधाओं का अध्ययन करने के मामले में काफी जानकारीपूर्ण है, जिसमें निगमों और व्यक्तिगत प्रोग्रामर के साथ बातचीत शामिल है। मैं जावा लॉगिंग के इतिहास के बारे में जितना संभव हो उतना बताने जा रहा हूं, साथ ही यह सब कहां आया और कैसे रहना है। स्थिति का मेरा विश्लेषण इस कारण के बारे में काफी व्यक्तिपरक होगा कि लॉगिंग हमेशा स्वाद का मामला है, और मेरे स्वाद ने मेरे अपने, वयस्कों का गठन किया है। मुझे लगता है कि यह पूरे चिड़ियाघर लॉगिंग फ्रेमवर्क की कुछ तकनीकी विशेषताओं के संदर्भ में जानकारीपूर्ण नहीं होगा, लेकिन ओपन सोर्स मॉडल में डेवलपर्स की नीतियों और मनोविज्ञान के संदर्भ में।



शुरुआत



यह स्पष्ट है कि किसी भी लॉगिंग लाइब्रेरी को कम से कम कंसोल / लॉग फाइल के लिए एक लाइन प्रिंट करने की अनुमति देनी चाहिए।



शुरुआत में, निश्चित रूप से, System.err.println



। इसके अलावा, सर्वलेट एपीआई के पहले संस्करण में एक log



फ़ंक्शन (हालांकि, काफी आदिम) शामिल था।



1999 में अधिक उन्नत समाधानों के विकल्पों में से एक एवलॉन प्रोजेक्ट (और एक्सकैलिबुर एंड फोर्ट्रेस नामक सबप्रोजेक्ट्स) था, जिसमें डीआई सेवाओं के अलावा लॉगइनेबल्ड इंटरफ़ेस की पेशकश की गई थी। एक ऑब्जेक्ट जिसने खुद को लॉगइनेक्स्ट घोषित किया था उसे इंजेक्ट किया गया था (मैं डीआई के साथ अपने संबंध पर जोर देने के लिए "इंजेक्शन" के बजाय इस शब्द का उपयोग करता हूं), एक प्रकार का लॉगर, जहां आप लिख सकते हैं: ए) लाइनें बी) अपवाद। उस समय यह दृष्टिकोण ताजा और अभिनव लग रहा था, लेकिन आधुनिक दृष्टिकोण से यह शुद्ध मूढ़ता और अति-इंजीनियरिंग है। लॉगिंग के लिए DI का उपयोग करने का कोई मतलब नहीं है, और इस लकड़हारे का एक स्थिर उदाहरण खुद सभी के लिए उपयुक्त होगा। एवलॉन में, मुझे यह सोचना था कि इस शापित लॉगर को कहाँ बचाया जाए और यदि डीआई (कंटेनर द्वारा नियंत्रित नहीं किया गया है) का उपयोग नहीं करता है तो क्या करना है, और मैं वास्तव में इसमें लॉग इन करना चाहता हूं।



1999 के आसपास, एक नई पीढ़ी का पुस्तकालय दिखाई देता है - log4j। पुस्तकालय का प्रोटोटाइप आईबीएम द्वारा विकसित किया गया था (उस युग में जब ब्लू विशाल जावा को OS / 2 में निचोड़ने की कोशिश कर रहा था), तब ASF ने बैटन को उठाया। उत्पाद पहले से ही बहुत अधिक सोचा गया था और वास्तविक जरूरतों पर परीक्षण किया गया था। सामान्य तौर पर, मुझे यह कहना चाहिए कि उस समय तक जावा में सर्वर एप्लिकेशन केवल एक वर्ष के थे, और लॉगिंग हमेशा सर्वर पर मांग में थी। इस समय के दौरान, जावा समुदाय धीरे-धीरे समझने लगा कि उन्हें क्या और कैसे चाहिए।



log4j ने एक लकड़हारा या श्रेणी (यानी उस एप्लिकेशन का क्षेत्र जो लॉग में लिखना चाहता है) की अवधारणा को विभाजित किया है, वास्तविक लॉग प्रविष्टियाँ जो तथाकथित ऐपेंडर्स को लागू करती हैं , और रिकॉर्ड्स ( लेआउट ) को प्रारूपित करती हैं। लॉग 4 जे कॉन्फ़िगरेशन यह निर्धारित करता है कि कौन से ऐप्पेंडर्स किन श्रेणियों से जुड़े हैं और लॉग स्तर के संदेश प्रत्येक ऐपेंडर में आते हैं।



Log4j की आधारशिला श्रेणियों की श्रेणी है। उदाहरण के लिए, आप org.hibernate



से सभी संदेश लॉग कर सकते हैं और org.hibernate.type



से सब कुछ म्यूट कर सकते हैं। कुछ समय बाद, वास्तव में, श्रेणियों के पदानुक्रम और आवेदन में पैकेज पदानुक्रम के मिलान की प्रथा स्थापित की गई।



श्रेणियों का पदानुक्रम आपको अनावश्यक संदेशों को कुशलता से काटने की अनुमति देता है, इसलिए log4j ने बहुत चालाकी से काम किया। वैसे, लॉगर के लिए सिद्धांत बात इतनी रिकॉर्डिंग गति नहीं है जितना कि अनावश्यक की फ़िल्टरिंग गति (और आमतौर पर 90% से अधिक अनावश्यक) और स्वरूपण।



Log4j में निर्धारित सिद्धांत अन्य भाषाओं में काफी सफलतापूर्वक पोर्ट किए गए हैं: log4cxx, log4net (और ताजा शावक - log4php)। पायथन 2.x में मानक लॉगिंग पैकेज एक पुन: डिज़ाइन किया गया लॉग 4j (अन्य पुस्तकालयों के एक छोटे से जोड़ के साथ) है।



इसलिए, हम संक्षेप में बताते हैं। सफल वास्तुकला, स्पष्ट विन्यास योजना, असफल-सुरक्षित सिद्धांत - क्यों इस तरह के एक अद्भुत पुस्तकालय को मंच में शामिल नहीं किया गया है?



जावा लॉगिंग एपीआई



वास्तव में, सब कुछ अजीब निकला। IBM, जिसकी गहराई में log4j उत्पन्न हुआ, नए JSR47 (जावा लॉगिंग एपीआई) के गठन के प्रश्नों में बहुत तेज निकला। विशेष रूप से, कॉमरेड ग्राहम हैमिल्टन, जो JSR47 के लिए जिम्मेदार हैं, ने आधार के रूप में log4j नहीं लेने का फैसला किया, लेकिन मूल आईबीएम लॉगिंग टूलकिट । इसके अलावा, लॉगिंग टूलकिट को इसके पूर्ण उपयोग के लिए उपयोग किया गया था: न केवल सभी मुख्य वर्गों के नाम, बल्कि उनके कार्यान्वयन भी; उन्होंने कोड को यथासंभव कम से कम खत्म करने की कोशिश की, जाहिरा तौर पर मंच की अगली रिलीज को पकड़ने के लिए। हालाँकि, वैचारिक रूप से यह log4j से काफी मिलता-जुलता था, केवल ऐपेंडर्स के बजाय इसे हैंडलर कहा जाता था, और लेआउट के बजाय फॉर्मैटर था।



चूंकि JSR47 का मुख्य उद्देश्य एपीआई को परिभाषित करना था , और कार्यान्वयन नहीं , केवल 4 उपलब्ध थे (प्लेटफॉर्म में डिफ़ॉल्ट रूप से) आउटपुट टूल (log4j में 10 से अधिक), और फॉर्मेटर्स इतने खराब थे कि उन्हें लगभग तुरंत तैयार करना पड़ा, क्योंकि वे तैयार थे पर्याप्त नहीं है। JSR47 ने .properties के रूप में कॉन्फ़िगरेशन का उपयोग करने का सुझाव दिया, और यह कोष्ठक में नोट किया गया था कि फ़ाइल में सब कुछ वर्णित नहीं किया जा सकता है। इस प्रकार, जब कॉन्फ़िगरेशन जटिल था, प्रोग्रामर को अप्रत्याशित रूप से पता चला कि कोड लिखना फिर से आवश्यक था, क्योंकि .properties



के रूप में .properties



इसका विन्यास .properties



नहीं है।



यह कहना नहीं है कि JSR47 प्रदर्शन में हार जाता है। कुछ स्थानों पर, उन्होंने स्मृति को अपने विन्यास के एक विशेष प्रतिनिधित्व को बनाए रखते हुए log4j को पछाड़ दिया (जो संयोगवश, उसी समय इस बहुत विन्यास को जटिल करता है)। हालांकि, जैसा कि यह निकला, JSR47 ने अनिवार्य रूप से तथाकथित कॉलर सूचना एकत्र की, अर्थात "यह संदेश कहां से आता है।" कॉलर जानकारी प्राप्त करना एक महंगा ऑपरेशन है, यह मूल कोड का उपयोग करके आगे बढ़ता है। Log4j के अनुभवी चाचाओं को यह पता था, इसलिए उन्होंने इस अवसर को "बेहतर इसे चालू नहीं" के साथ प्रदान किया।



Log4j के डेवलपर्स ने एक खुली याचिका दायर की , जहां उन्होंने "असेंबली लाइन से JSR47 को हटाने" की मांग की, जबकि यह अभी तक मंच का हिस्सा नहीं था। याचिका पर 100 से अधिक लोगों ने हस्ताक्षर किए ... हालांकि, बहुत देर हो चुकी थी। जेडीके की अगली रिलीज को मंजूरी दे दी गई और मंच भविष्य में अल्पविकसित java.util.logging



या संक्षेप में JUL के साथ बह गया। नया लॉगिंग इतना अविकसित और असुविधाजनक था कि उन्होंने इसे केवल कुछ एप्लिकेशन सर्वरों में उपयोग करने का निर्णय लिया (उनमें से राल और जेट्टी)। हालांकि, सन ने याचिका का जवाब दिया और मूल JSR47 की अधिकांश प्रमुख समस्याओं को धीरे-धीरे समाप्त कर दिया गया। फिर भी, ये हेरफेर लकड़ी के पुल के लिए समर्थन स्थापित करने की तरह अधिक थे, जो किसी भी तरह से इस पुल को प्रबलित कंक्रीट नहीं बनाएंगे। Log4j डेवलपर्स ने सूर्य की ओर झुकाव किया, ध्यान दिया, हालांकि, JUL की वक्रता की डिग्री अभी भी काफी अधिक है। अन्य बातों के अलावा, JDK 1.4 लाइसेंस ने लॉग 4j को JUL कार्यान्वयन के रूप में उपयोग करने की अनुमति नहीं दी । Log4j के लिए अंतिम ट्रेन चली गई है।



बड़ी संख्या में लॉग लेखकों (यानी हैंडलर) का समर्थन करने में असमर्थ, JUL ने लॉग स्तर के एक अविश्वसनीय संख्या को परिभाषित करके दिखाया। उदाहरण के लिए, संदेशों को डीबग करने के लिए पहले से ही 3 स्तर थे - FINE, FINER और FINEST। यह सब देखकर, डेवलपर्स को अक्सर समझ में नहीं आया कि तीन स्तरों में से कौन सा, इसे लानत है, इसका उपयोग किया जाना चाहिए।



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



बेशक, समुदाय ने इस समस्या को ठीक करने का प्रयास किया। रैपिड महामारी शुरू हो गई है। या, मैं एक महामारी भी कहूंगा।



आवरण नरक



जब आप कई पुस्तकालयों को जोड़ते हैं और उनके लॉग को एक पूरे में संयोजित करने का प्रयास करते हैं (और कोड को संशोधित नहीं किया जा सकता है), तो इसे एडॉप्टर कहा जाएगा। JUL एडेप्टर log4j में लिखे गए थे और इसके विपरीत। दुर्भाग्य से, कार्यात्मक एडेप्टर "कम से कम सामान्य एकाधिक" हैं। यहां तक ​​कि जब संदर्भ समर्थन (NDC और MDC) log4j में दिखाई दिया, तो यह JUL में आधान के दौरान खो गया था। इससे भी बदतर, JUL ने केवल JDK 1.4 के बाद से काम किया, जबकि एक अविश्वसनीय संख्या में एंटरप्राइज़ एप्लिकेशन अभी भी 1.3 पर बैठे। परिणामस्वरूप, समुदाय एक "वास्तविक मानक" बनाने के विचार से ग्रस्त हो गया जिसका उपयोग हर कोई एक साथ करता था और वह कभी भी, कहीं भी काम करेगा।



2002 के आसपास, जकार्ता समूह से कॉमन्स-लॉगिंग (JCL = जकार्ता कॉमन्स लॉगिंग) नामक एक परियोजना निकली। वास्तव में, यह उस समय मौजूद सभी लॉगिंग टूल के लिए एक आवरण था। यह अनुप्रयोगों को लिखने के लिए प्रस्तावित किया गया था ताकि वे एक आवरण ( Log



नामक एक इंटरफ़ेस) में बदल जाएं, जो एक "उपयुक्त" लॉगिंग सिस्टम का चयन करता है और खुद से जुड़ा होता है। रैपर कार्यात्मक रूप से खराब था और मौजूदा लॉगिंग टूल में कोई जोड़ नहीं था।



स्वचालित रूप से उपयुक्त लॉगिंग सिस्टम को कैसे चुना गया? लेकिन यह सबसे दिलचस्प है। सबसे पहले, आप इसे स्पष्ट रूप से एक विशेष commons-logging.properties



फ़ाइल को CLASSPATH में रखकर निर्धारित कर सकते हैं। दूसरे, एक प्रणाली संपत्ति के माध्यम से (जो, जाहिर है, कोई भी नहीं करेगा)। तीसरी बात, अगर CLASSPATH में लॉग 4j का कहीं पता लगाया गया था, तो यह स्वचालित रूप से सक्रिय हो गया था। अन्य सभी पुस्तकालयों के कार्यान्वयन को उसी तरह से खोजा गया था, पहले वाला हमेशा जुड़ा हुआ था।



सुंदर! ठीक है, यही है, यह अच्छा होगा यदि दुनिया के सभी सॉफ़्टवेयर कॉमन्स-लॉगिंग का उपयोग करते हैं। तब आप JAR को सुरक्षित रूप से एकत्र कर सकते हैं, उन्हें एप्लिकेशन सर्वर में डाल सकते हैं, और वहां JCL इस एप्लिकेशन सर्वर और वॉइला के लॉगिंग को चुन लेगा!



वास्तव में, जैसा कि यह निकला, सॉफ्टवेयर का एक गुच्छा आमतौर पर "उनके डेवलपर की पसंदीदा लॉगिंग" का उपयोग करता है। इसका मतलब है कि एक पूरी तरह से मनमाना पुस्तकालय, एक निर्भरता के रूप में, उदाहरण के लिए, log4j को खींच सकता है, जो इस प्रकार CLASSPATH में आता है और log4j का उपयोग करने के लिए अप्रत्याशित रूप से JCL को स्विच करता है। यहां तक ​​कि commons-logging.properties



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



लॉगिंग की पसंद की पूरी अप्रत्याशितता जेसीएल की मुख्य और बहुत ही मजेदार विशेषता है। Log4j समूह ने कॉमन्स-लॉगिंग एपीआई को अपनाने से पहले एक बार फिर से गुस्से में सोचो लेख में विस्फोट किया, जिसने महामारी को रोकने और मौजूदा समाधान को परिष्कृत करने पर ध्यान केंद्रित करने का सुझाव दिया, log4j।



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



वास्तव में, ओपन सोर्स ने इस विकृति को जन्म देते हुए इतने अजीब तरीके से काम क्यों किया? डेवलपर्स ने सिर्फ एक और परिपक्व और लोकप्रिय ओपन सोर्स उत्पाद - log4j का उपयोग करने की हिम्मत क्यों नहीं की? यहाँ बिंदु, शायद, समुदाय की एक निश्चित जड़ता है, जिसका उपयोग या तो एएसएफ (और इस बुरे सपने को उत्पन्न करने वाले जकार्ता समूह एएसएफ का हिस्सा है) या सूर्य का अनुसरण करने के लिए किया जाता है। जैसे ही जेसीएल का उपयोग करने वाली परियोजनाओं का एक महत्वपूर्ण द्रव्यमान बनता है, बाकी सभी (और सबसे विनम्र लोग नहीं, ठीक है, गैविन किंग?) जेसीएल का उपयोग करना शुरू करता है (क्योंकि अपाचे भयानक है!)। यह आमतौर पर ब्राउनियन आंदोलन की याद दिलाता है, जहां अपाचे या सन जैसे ब्रांड कम दबाव वाले क्षेत्र बनाने में सक्षम हैं जहां लाखों डेवलपर्स भाग रहे हैं। JCL मामले में, "सफलता की कहानी" का वर्णन रॉड वाल्डहॉफ (तथाकथित जकार्ता कॉमन्स के डेवलपर्स में से एक) के ब्लॉग पर किया गया था।



प्रगति का एक नया दौर



इसलिए, कहीं न कहीं 2004 में हम किट में हैं:

  1. स्थिर और कार्यात्मक रूप से विकसित log4j
  2. सुस्त java.util.log
  3. समस्या कॉमन्स-लॉगिंग
  4. कुछ छोटे लकड़हारे ध्यान देने योग्य नहीं हैं


ध्यान दें कि इस समय log4j परियोजना में रूढ़िवादी मूड प्रबल था। विशेष रूप से पुराने JDKs के साथ संगतता पर ध्यान दिया गया था। ऐसा लगता है कि एक नई शाखा log4j का विकास - 1.3.x। यह संस्करण एक प्रकार का समझौता समाधान है: हां, मैं नई कार्यक्षमता चाहता हूं, हां, मैं पिछड़ी संगतता बनाए रखना चाहता हूं, हां, हम हमारे और आपके दोनों को खुश करने की कोशिश करेंगे। इस बीच, रास्ते में JDK 1.5 के साथ varargs, JMX एक्सटेंशन और अन्य उपहारों का एक गुच्छा। Log4j टीम ने एक दिमागी शुरुआत की। 2.x शाखा अलग है - मुख्य 1.2.x शाखा के साथ असंगत है और विशेष रूप से JDK 1.5 के लिए बनाई गई है। जावा समुदाय अधीर दिख रहा है। ऐसा लगता है जैसे कुछ हो रहा है । लेकिन क्या वास्तव में समझने के लिए नहीं है - log4j 2.0 अभी भी एक अप्राप्य अल्फा है, log4j 1.3 बेतहाशा छोटी गाड़ी है और वादा किए गए ड्रॉप-इन संगतता प्रदान नहीं करता है। और केवल शाखा 1.2 अभी भी स्थिर और जीवित है और अच्छी तरह से, कुछ वर्षों में कूद रहा है - ध्यान! - संस्करण 1.2.6 से 1.2.12 तक।



2006 में कहीं, log4j के संस्थापक पिता में से एक - Ceki Gülcü - तेजी से क्षय करने वाली टीम को छोड़ने का फैसला करता है। तो SLF4J (जावा के लिए सरल लॉगिंग मुखौटा) नामक अगले "सब कुछ का आवरण" का जन्म हुआ है। अब यह चारों ओर एक आवरण है: log4j, JUL, कॉमन्स-लॉगिंग, और एक नया लकड़हारा जिसे लॉगबैक कहा जाता है। जैसा कि आप देख सकते हैं, प्रगति तेजी से "रैपर के चारों ओर आवरण" के चरण तक पहुंच गई। यह अनुमान लगाना आसान है कि, एक ही योजना के अनुसार, लिपटे पुस्तकालयों की संख्या एक तथ्यात्मक के रूप में बढ़ेगी। हालाँकि, SLF4J अन्य अन्य ट्विस्ट भी प्रदान करता है। ये विशेष बाइनरी एडेप्टर हैं: log4j से SLF4J तक, कॉमन्स-लॉगिंग से SLF4J और इसी तरह। ऐसे एडेप्टर कोड के लिए बनाए जाते हैं जिनके स्रोत उपलब्ध नहीं हैं; हालाँकि, उन्हें लॉग लाइब्रेरीज़ के मूल JAR को बदलना होगा। मैं कल्पना नहीं कर सकता कि यह किस प्रकार का दलिया होगा, लेकिन यदि आप वास्तव में चाहते हैं, तो आप कर सकते हैं।



मेरे सभी रैपरों के लिए, ईमानदारी से, SLF4J एक अच्छी तरह से बनाया गया उत्पाद है। पूर्ववर्तियों की सभी कमियों को ध्यान में रखा गया था। उदाहरण के लिए, CLASSPATH में वर्ग खोजों के साथ shamanistic नृत्यों के बजाय, एक अधिक विश्वसनीय योजना का आविष्कार किया गया था। अब पूरे आवरण को दो भागों में विभाजित किया गया है - एपीआई (जो अनुप्रयोगों द्वारा उपयोग किया जाता है) और कार्यान्वयन, जो प्रत्येक प्रकार के लॉगिंग के लिए अलग-अलग JAR फ़ाइलों द्वारा दर्शाया जाता है (उदाहरण के लिए, slf4j-log4j12.jar



, slf4j-jdk14.jar



, आदि)। अब यह परियोजना के लिए आवश्यक कार्यान्वयन फ़ाइल को कनेक्ट करने के लिए पर्याप्त है, जिसके बाद - उफ़! सभी परियोजना कोड और उपयोग किए गए सभी पुस्तकालय (बशर्ते कि वे SLF4J एपीआई का उपयोग करते हैं) सही दिशा में प्रवेश करेंगे।



कार्यात्मक रूप से, SLF4J ने सभी आधुनिक घंटियाँ और सीटी जैसे NDC और MDC का समर्थन किया। वास्तव में रैपिंग कॉल के अलावा, SLF4J ने स्ट्रिंग्स को फॉर्मेट करते समय एक छोटा लेकिन उपयोगी बोनस की पेशकश की। यहाँ बोनस इस प्रकार है। कोड में, आपको अक्सर फॉर्म के निर्माण को प्रिंट करना होता है:



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





वास्तव में स्ट्रिंग को प्रिंट करने के अलावा, यहां user.toString()



रूपांतरण का user.toString()



से पालन किया जाएगा। सब कुछ नहीं होगा। डिबग मोड में, निष्पादन की गति वास्तव में हमें परेशान नहीं करती है। हालांकि, भले ही हम स्तर निर्धारित करते हैं, कहते हैं, INFO में, यह पता चला है कि स्ट्रिंग का निर्माण अभी भी होगा! कोई चमत्कार नहीं: log.debug



कॉल करने से पहले लाइन का निर्माण किया जाता है, इसलिए log.debug



पास किसी भी तरह इसे नियंत्रित करने का कोई तरीका नहीं है। यदि आप कल्पना करते हैं कि यह log.debug



कुछ महत्वपूर्ण आंतरिक लूप में रखा गया है ... सामान्य रूप से, आप उस तरह नहीं रह सकते। Log4j के डेवलपर्स ने डिबगिंग कोड को इस तरह तैयार करने का सुझाव दिया:



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





यह अच्छा नहीं है। सिद्धांत रूप में, लॉगिंग लाइब्रेरी द्वारा इन सभी समस्याओं का ध्यान रखा जाना चाहिए। यह समस्या केवल log4j की एच्लीस हील की थी। डेवलपर्स ने सुस्त रूप से किक करने के लिए प्रतिक्रिया व्यक्त करते हुए कहा कि अब आप लॉगिंग कॉल (बिलकुल सही!) में एक ऑब्जेक्ट जोड़ सकते हैं, और यहां तक ​​कि यह भी बता सकते हैं कि ऑब्जेक्टरेंडर इंटरफ़ेस का उपयोग करके लॉग को यह ऑब्जेक्ट कैसे लिखा जाएगा। द्वारा और बड़े, ये सभी बहाने और आधे उपाय थे।



SLF4J को JDK और API के पुराने संस्करणों के साथ संगतता के ढांचे द्वारा निचोड़ा नहीं गया था, इसलिए मैंने तुरंत एक और सुंदर समाधान प्रस्तावित किया:

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





सामान्य तौर पर, सब कुछ सरल है। इस पंक्ति में, {}



अलग से पारित किए गए मापदंडों के लिंक हैं। पैरामीटर को लॉग रिकॉर्ड के स्ट्रिंग और अंतिम स्वरूपण में परिवर्तित करना तब होता है जब DEBUG स्तर सेट किया जाता है। आप बहुत सारे मापदंडों को पारित कर सकते हैं। यह काम करता है! if



और अन्य गूंगा है if



फ्रेमिंग लिखने की जरूरत नहीं है!



कोष्ठक में, यह ध्यान दिया जाना चाहिए कि यह विशेषता भी ग्रूवी भाषा द्वारा पूरी तरह से अप्रत्याशित रूप से लागू की गई थी, जहां GString की अवधारणा है, अर्थात। स्ट्रिंग देखें
 "User ${user} connected from ${request.getRemoteAddr()}"
      
      



, जो स्पष्ट रूप से कई संदर्भ चर (यहां यह user



, request



) के साथ जुड़ा हुआ है, और स्ट्रिंग की गणना एक आस्थगित तरीके से होती है । यह log4j के रूप में इस तरह के लॉग पुस्तकालयों के लिए बहुत सुविधाजनक है - आप इसे GString इनपुट में प्राप्त कर सकते हैं, और फिर या तो इसे गणना के बिना फेंक सकते हैं, या फिर भी इसे सामान्य (स्थिर) स्ट्रिंग - स्ट्रिंग में परिवर्तित कर सकते हैं।



संक्षेप में, SLF4J को भविष्य के लिए आरक्षित करने के साथ, सक्षम बनाया गया था। इससे समुदाय के बीच इसकी लोकप्रियता में गंभीर वृद्धि हुई: अब SLF4J का उपयोग जेटी, हाइबरनेट, मीना, जेरोनिमो, मुले, विकेट, नेक्सस ... जैसी महत्वपूर्ण परियोजनाओं द्वारा किया जाता है, सामान्य तौर पर, लगभग सभी हारे हुए लोग एक बार कॉमन्स-लॉगिंग पर एसएलएफ 4 जे पर स्विच कर जाते हैं। । मुझे आश्चर्य है कि कई साल पहले वांछित राज्य में कॉमन्स-लॉगिंग के सुधार को क्या रोका गया था? लेकिन ये ओपन सोर्स की वास्तविकताएं हैं - इसमें सॉफ्टवेयर का विकास विकासवादी की तुलना में अधिक क्रांतिकारी है।



इसके साथ ही SLF4J के साथ, एक पूरी तरह से नया लकड़हारा टेबल पर लाया गया - लॉगबैक। यह एक आदमी द्वारा बनाया गया था जो लॉगिंग पर एक कुत्ते को खा गया था, और वास्तव में वास्तव में एक अच्छा उत्पाद निकला। Logback को मूल रूप से JDK 1.5+ के तहत तेज किया गया था, एक में लॉग 4j प्रोजेक्ट में निहित सभी सीनेट पिछड़े संगतता रोगों से छुटकारा पाया। और इसका मतलब है कि varargs, java.util.concurrent



और अन्य प्रसन्न । उदाहरण के लिए, अंतर्निहित रनटाइम-फ़िल्टरिंग सिस्टम के कारण, आप उपयोगकर्ता सत्र के आधार पर लॉगिंग स्तर को बदल सकते हैं, उपयोगकर्ताओं को विभिन्न लॉग फ़ाइलों में और इसी तरह आगे और पीछे बिखेर सकते हैं।



मैं लेखक द्वारा चित्रित मूर्ति में सरसों फेंक दूंगा। इन विशेषताओं में से अधिकांश को log4j के लिए अतिरिक्त परिशिष्ट के रूप में लागू किया जा सकता है। कॉन्फ़िगरेशन को झुकना और दर्ज करना अधिक कठिन है, लेकिन यह एक तथ्य है कि इसके लिए नए लकड़हारे के लिए स्विच करना आवश्यक नहीं है। इस प्रकार, सभी लॉगबैक विज्ञापित चिप्स सुविधाजनक हैं, लेकिन अद्वितीय नहीं हैं।



समुदाय के लिए, यह सावधानी के साथ लॉगबैक का इलाज करता है। सबसे पहले, कुछ वर्षों में उन्हें 0.9.x संस्करण मिला, और यह कुछ प्रोग्रामर को डराता है। दूसरे, लॉगबैक न तो अपाचे छाता के नीचे है और न ही सूर्य के दायरे में है। यह लोगों को परेशान करता है। तीसरा, लेखक को खाने की जरूरत है, इसलिए लॉगबैक और समर्थन के लिए कुछ ऐड-ऑन के लिए, इसे पैसे की आवश्यकता है। यह कभी-कभी छात्रों को डराता है। अन्य चीजों में, लॉगबैक के पास एक जटिल दोहरी लाइसेंस (एलजीपीएल / ईपीएल) है, जबकि लॉग 4 जे में एक सार्वभौमिक अपाचे लाइसेंस है। पुस्तकालयों और आम तौर पर पुनर्वितरण सॉफ्टवेयर के लिए, लाइसेंसिंग एक बहुत ही सूक्ष्म बिंदु है।



द्वारा और बड़े, Logback आज विकास का शिखर है। लॉगबैक के अलावा, एक दर्जन नए लॉगिंग लाइब्रेरी दिखाई दिए हैं, लेकिन उच्च संभावना के साथ उनमें से कोई भी जीवित नहीं रहेगा। संक्षेप में, फिलहाल की स्थिति इस प्रकार है:



मैंने पहले ही कहा है कि ओपन सोर्स समुदाय झुंड के लिए "गुरुत्वाकर्षण के केंद्रों" में जाता है। अब गुरुत्वाकर्षण का ऐसा केंद्र इसकी "सार्वभौमिकता" के कारण SLF4J है। एसएलएफ 4 जे की सापेक्ष लोकप्रियता कुछ हद तक नए रैपरों के उद्भव की गारंटी देती है। SLF4J का उपयोग करने वाली परियोजनाओं की संख्या "महत्वपूर्ण द्रव्यमान" को जमा करने के लिए पहले से ही पर्याप्त है। Logback (एक ही लेखक, आप के दिमाग) में ऐसा कोई महत्वपूर्ण द्रव्यमान नहीं है। (वैसे, log4j अभी भी हमें सुनहरे पहाड़ों और संस्करण 2.0 का वादा करता है, लेकिन चीजें अभी भी हैं।) मुझे लगता है कि अगर लॉगबैक अपने गर्व को शांत करता है और अपाचे को स्थानांतरित करता है, तो उसकी स्थिति में बहुत सुधार होगा।



निष्कर्ष



कार्यक्रम के मनोविज्ञान के कोण से इस मुद्दे के इतिहास को देखना दिलचस्प है। दरअसल, सिद्धांत रूप में, यह सब सर्पिल है (और यह प्रगतिशील प्रतीत होता है!) आंदोलन - अंतहीन "पहिया को मजबूत करें"। यही है, दो विकल्पों में "मौजूदा को संशोधित करें" और "अपना खुद का करें", दूसरा हमेशा चुना गया था। इसलिए, उल्लिखित परियोजनाओं में से एक बिना शर्त नेताओं (बहुत वास्तविक मानकों में) में टूट गया है। इसके बजाय, डेवलपर्स को अलग-अलग परियोजनाओं में अलग-अलग समय पर "कटा हुआ" किया गया और एक साथ अभिनय करने के बजाय अलग-अलग काम किया गया। हालांकि यह एक तथ्य नहीं है कि सभी लेखक एक टीम में काम कर सकते हैं। राजनीतिक क्षण थे (याद रखें कि ग्राहम हैमिल्टन आईबीएम को कैसे पसंद करते थे), और टीम में सिर्फ तुच्छ झगड़े थे। जकार्ता कॉमन्स के प्रतिभागियों को "पसंद की स्वतंत्रता" के साथ समुदाय प्रदान करने की इच्छा आम तौर पर समुदाय के लिए "रैपरों की महामारी" में बदल गई।



सामान्य तौर पर, ये सभी विसेस एक खुले समुदाय के विशिष्ट हैं। यह 10-वर्ष के इतिहास से भी पता चलता है कि यह धारणा कितनी गलत है कि सूर्य अब जावा समुदाय में कुछ तय कर रहा है। हम देखते हैं कि सूर्य के विपरीत और स्वतंत्र रूप से कई चीजें हुईं। एक शब्द में, मुझे आश्चर्य है कि यह आगे कैसे बढ़ेगा। मुझे एक बात का यकीन है - परियोजनाएँ आती हैं और जाती हैं, लोग बदलते नहीं हैं :)



All Articles