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

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

* लेख आलसी लकड़हारा स्तरों से लिया गया चित्र
ट्रेसिंग का कार्य प्रोग्राम के प्रत्येक चरण के संचालन का विश्लेषण करके किसी भी वातावरण (डेवलपर पर्यावरण, परीक्षण पर्यावरण, काम के वातावरण) में आवेदन में एक दोष खोजने के लिए है। इसलिए, ट्रेसिंग लॉग में जानकारी जोड़ना तर्कसंगत है:
- सभी त्रुटियों के बारे में - संसाधित और संसाधित नहीं
- स्टार्टअप पैरामीटर और लोडेड कॉन्फ़िगरेशन
- साथ ही नीचे वर्णित घटनाएं।
ट्रेसिंग जानकारी मुख्य रूप से डेवलपर और परीक्षण इंजीनियर (या बहुत उच्च स्तर के सहायक कर्मचारियों के लिए काम के माहौल में) के लिए अभिप्रेत है।
ट्रेसिंग की एक विशेषता यह है कि आमतौर पर इस कार्यक्षमता को आवश्यकताओं में वर्णित नहीं किया जाता है, और इसलिए आमतौर पर डेवलपर्स के लिए एक परियोजना की शुरुआत में यह कल्पना करना मुश्किल है कि ट्रेसर की जानकारी की क्या आवश्यकता हो सकती है, और इसलिए, यह समझना मुश्किल है कि क्या और कब रिकॉर्ड करना है।
सबसे महत्वपूर्ण बात यह समझना है कि काम के माहौल में अनुरेखण केवल आवश्यक होने पर सक्षम है, अर्थात। ईवेंट लॉग को रोकना नहीं है। विकास के माहौल और परीक्षण के माहौल के लिए, अनुरेखण को सबसे अधिक बार सक्षम किया जाता है ताकि वह एप्लिकेशन के सही संचालन और डिबगिंग की निगरानी कर सके।
लॉगिंग टूल आमतौर पर लॉग में रिकॉर्ड करने का अवसर प्रदान करते हैं, यह इंगित करते हैं कि वास्तव में यह जानकारी कहाँ दर्ज की जाएगी। एक महत्वपूर्ण तत्व कॉन्फ़िगरेशन में निर्दिष्ट करने की क्षमता है कि कौन सी प्रविष्टियां लॉग में जाएंगी और कौन सी नहीं होगी (आमतौर पर यह घटना श्रेणियों और घटना के स्तर के आधार पर किया जाता है)।
हालांकि, बड़ी समस्या यह है कि, उपकरणों की उपलब्धता के बावजूद, आप शायद ही कभी उन्हें सही तरीके से उपयोग करने के बारे में सिफारिशें पा सकते हैं, अर्थात्:
- ट्रेस लॉग में किन घटनाओं को लिखा जाना चाहिए
- घटना के लिए स्तर कैसे चुनें
- ईवेंट श्रेणियां कैसे चुनें
- जब कोई घटना घटित होती है तो क्या जानकारी दर्ज की जानी चाहिए
इसे लेख में बाद में माना जाएगा।
ट्रेस लॉग में किन घटनाओं को दर्ज किया जाना चाहिए
ट्रेस लॉग में लिखी जाने वाली घटनाओं का चयन करते समय एक महत्वपूर्ण कारक, दो कारकों पर, मेरी राय में निर्भर करता है:
- क्या इकाई परीक्षण का उपयोग विकास में किया जाता है?
इकाई परीक्षणों का उपयोग करने से उन तरीकों के व्यापार तर्क में त्रुटियों की संख्या को काफी कम किया जा सकता है जो बाहरी प्रणालियों (इस एप्लिकेशन परत के लिए बाहरी) के साथ बातचीत नहीं करते हैं। हालाँकि, जब कोड एक बाहरी सिस्टम (डेटाबेस के साथ व्यापार परत कोड की बातचीत, विभिन्न कंप्यूटरों पर स्थित व्यावसायिक तर्क परतों की बातचीत), के साथ बातचीत करता है, तो यूनिट परीक्षण प्रभावी नहीं होते हैं क्योंकि अलग-अलग वातावरण में अलग-अलग परतों के कॉन्फ़िगरेशन भिन्न हो सकते हैं। इसके आधार पर, हम यह निष्कर्ष निकाल सकते हैं कि इकाई परीक्षणों का उपयोग करते समय केवल परतों और त्रुटि अनुरेखण के बीच बातचीत का पता लगाना तर्कसंगत है (क्योंकि हम मानते हैं कि व्यक्तिगत रूप से प्रत्येक परत का तर्क बहुत अच्छी तरह से परीक्षण किया गया है)। यदि कोई इकाई परीक्षण नहीं हैं, तो आपको प्रोग्राम लॉजिक की प्रत्येक शाखा (विधि में प्रवेश, निकास, विधि में त्रुटि की घटना, सशर्त विवरण की प्रत्येक शाखा) का पता लगाने की आवश्यकता है - आवेदन का प्रकार।
तालिका ट्रेस लॉग में लॉग करने के लिए कुछ प्रकार के अनुप्रयोगों और घटनाओं को दिखाती है (यह स्पष्ट है कि अन्य प्रकार के अनुप्रयोग हैं)।
आवेदन का प्रकार | लॉगिंग सुविधाएँ |
पृथक डेस्कटॉप अनुप्रयोग (डिस्क में कुछ भी सेव नहीं करता है) | यदि इस तरह के अनुप्रयोग को यूनिट परीक्षणों द्वारा अच्छी तरह से जांचा जाता है, तो इसका कोई मतलब नहीं है |
डेटा दर्ज करने और रिपोर्ट प्राप्त करने के लिए आवेदन | आवेदन और भंडार के बीच पहले से ही बातचीत है, और इसलिए इस बातचीत के बारे में जानकारी लॉग करना तर्कसंगत है: अनुरोध, प्रविष्टियों की संख्या और प्राप्त, प्रसंस्करण अनुरोधों की गति, रिपोर्ट बनाने के लिए प्रमुख पैरामीटर |
एप्लिकेशन इंस्टॉलर (पैच, अपडेट) | इस मामले में, कार्यक्रम बाहरी प्रणाली के साथ निकटता से बातचीत करता है और इसलिए, प्रत्येक चरण (निष्पादित करने का प्रयास और निष्पादन का परिणाम) ट्रेस लॉग में दर्ज किया जाना चाहिए |
एकीकरण बस | इनकमिंग या आउटगोइंग डेटा के बारे में संक्षिप्त या पूर्ण (पूरी तरह से डेटा) जानकारी |
एक एप्लिकेशन जिसे उपयोगकर्ता द्वारा बहुत संशोधित किया जा सकता है (या अतिरिक्त मॉड्यूल और प्लगइन्स के साथ विस्तारित किया गया है) | इस तरह के बाहरी मॉड्यूल (इनपुट / आउटपुट मापदंडों) और कार्यक्रम पर सेट कॉन्फ़िगरेशन मापदंडों के प्रभाव के साथ सभी इंटरैक्शन |
ट्रेस लॉग में क्या डेटा दर्ज किया जाना चाहिए
घटना के सरल नाम (विवरण) के अलावा, काम का विश्लेषण करने के लिए अक्सर अतिरिक्त जानकारी की आवश्यकता होती है। निम्न तालिका उस डेटा को दिखाती है जो रिकॉर्ड करने के लिए उपयोगी होगा। यह स्पष्ट है कि इस तरह के विस्तार से घटनाओं को लिखना हमेशा आवश्यक होता है। इसके अलावा, आमतौर पर ट्रेसिंग टूल निम्न में से कुछ जानकारी को स्वचालित रूप से रिकॉर्ड करने की अनुमति देते हैं।
डेटा | विवरण |
तारीख और समय | दिनांक और समय घटना हुई |
सर्वर | सर्वर जिस पर घटना हुई (विभिन्न सर्वरों से एकत्रित लॉग का विश्लेषण करते समय उपयोगी) |
प्रक्रिया है | प्रक्रिया का नाम जहां घटना हुई। यह आवश्यक है, उदाहरण के लिए, यदि विभिन्न प्रक्रियाएं साझा पुस्तकालयों का उपयोग करती हैं। |
विधि | विधि का नाम, संभवतः कक्षा और पुस्तकालय के नाम सहित |
घटना श्रेणी | परत या तार्किक इकाई का नाम |
स्तर | घटना विस्तार स्तर |
नाम | घटना का नाम (विधि की शुरुआत या अंत, त्रुटि, वस्तु की स्थिति में परिवर्तन, आदि) |
विस्तृत जानकारी | उदाहरण के लिए, त्रुटि के बारे में विस्तृत जानकारी (और एक महत्वपूर्ण त्रुटि के मामले में, सिस्टम के बारे में विस्तृत जानकारी हो सकती है), पैरामीटर का मान (वस्तु), वस्तु का नाम, या वस्तु पर कार्रवाई का विवरण। |
वह खाता जिसके तहत प्रक्रिया चलती है | |
उपयोगकर्ता का खाता जिसने कार्रवाई को ट्रिगर किया | प्रारंभिक कॉल करने वाले उपयोगकर्ता का खाता, जिसके कारण यह ईवेंट हुआ |
अनेकता | विधि कॉल का एक ढेर जिसके कारण यह घटना हुई। यह घटना के विस्तृत विश्लेषण में उपयोगी हो सकता है। |
प्रक्रिया सहसंबंध संख्या | यदि एप्लिकेशन बहु-उपयोगकर्ता है, तो यह समझना महत्वपूर्ण है कि यह (या) इवेंट रिकॉर्ड किस अनुरोध (उपयोगकर्ता) का है। |
प्रारंभिक प्रक्रिया सहसंबंध संख्या | यदि एप्लिकेशन वितरित किया जाता है, तो यह संख्या विभिन्न सर्वरों (या प्रक्रियाओं) पर घटनाओं से मेल खाने के लिए उपयोग की जाती है। उदाहरण के लिए, आप क्लाइंट से सर्वर से सहसंबंध संख्या को स्थानांतरित कर सकते हैं और ट्रेसिंग करते समय इसे सहेज सकते हैं। भविष्य में, आप सर्वर पर घटना के लिए क्लाइंट एप्लिकेशन कॉल को मैप कर सकते हैं |
ट्रेस स्तर
स्तर मुख्य रूप से लॉग को लिखते समय घटनाओं को फ़िल्टर करने के लिए उपयोग किया जाता है। यह उस डेटा के लॉग को लिखने से रोकना है जिसकी किसी निश्चित समय पर जरूरत नहीं है।
उदाहरण के लिए, NLog जैसे उपकरण डिफ़ॉल्ट 6 ईवेंट स्तर (अधिक विस्तृत से कम विस्तृत में) प्रदान करता है: ट्रेस, डीबग, जानकारी, चेतावनी, त्रुटि, अधिक जानकारी के लिए ( एनएलओजी के लिए प्रलेखन देखें)
इसके अलावा, कॉन्फ़िगरेशन में, आप यह निर्दिष्ट कर सकते हैं, उदाहरण के लिए, काम के माहौल में, ट्रेस लॉग में त्रुटि और घातक स्तर की घटनाओं को लिखें (अन्य सभी को अनदेखा करें), और यदि कोई समस्या होती है, तो सभी घटनाओं को रिकॉर्ड करने के लिए कॉन्फ़िगरेशन को बदलें।
निम्न तालिका ट्रेसिंग के समय इवेंट स्तर चुनने के लिए मेरी सिफारिशों को दिखाती है
घटना | स्तर |
लोडेड कॉन्फ़िगरेशन / कॉन्फ़िगरेशन परिवर्तन | जानकारी |
उपयोगकर्ता क्रियाएँ | जानकारी |
प्रत्येक "सार्वजनिक" विधि की शुरुआत और अंत (या एक तरीका जो विनिर्देश के अनुसार तर्क को लागू करता है), इनपुट / आउटपुट पैरामीटर, ऐसी विधि के संचालन का परिणाम है | जानकारी |
सार्वजनिक तरीकों में, इनपुट / आउटपुट पैरामीटर जो डेटा सेट हैं | डिबग |
विनिर्देश द्वारा वर्णित तर्क (कार्यक्रम शाखाएं) | जानकारी |
शेष विधियों की शुरुआत और अंत, इनपुट / आउटपुट पैरामीटर, काम का परिणाम | निशान |
अन्य विधियों के चरण | निशान |
बाहरी संसाधनों तक पहुँच (उदाहरण के लिए: डेटाबेस, वेब सेवाएँ) | जानकारी |
बाहरी संसाधनों और परिणाम तक पहुंच के लिए अनुरोधों (आदेशों) के बारे में विस्तृत जानकारी | डिबग |
अप्रत्याशित अपवाद (महत्वपूर्ण नहीं) | त्रुटि |
विशिष्टता अपवाद | चेतावनी / त्रुटि |
अपवादों को संभाला | चेतावनी / जानकारी / डिबग |
महत्वपूर्ण अपवाद (संसाधित या संसाधित नहीं) | घातक |
ईवेंट श्रेणियों का चयन करें
दूसरा महत्वपूर्ण पैरामीटर जिसके द्वारा आप लॉग में घटनाओं के फ़िल्टरिंग को कॉन्फ़िगर कर सकते हैं, इवेंट श्रेणियां हैं। डेवलपर को इन श्रेणियों को स्वयं चुनना चाहिए (यानी उपकरण डिफ़ॉल्ट रूप से श्रेणियां प्रदान नहीं करते हैं)
मेरा सुझाव है कि आप इन सिफारिशों का पालन करें - प्रत्येक व्यक्तिगत तार्किक स्तर के लिए, एक अलग श्रेणी बनाएं। उदाहरण के लिए: इंटरफ़ेस स्तर (UIControls), व्यावसायिक तर्क स्तर (BusinessLogic), डेटा एक्सेस स्तर (DAL), खोज मॉड्यूल (खोज), कॉन्फ़िगरेशन प्रोग्राम (ConfigManager) और इसी तरह।
इसके अलावा, यदि आपके पास परत के अंदर अलग-अलग घटक हैं, तो आप उनके अनुरेखण के लिए अलग उपश्रेणियों का चयन कर सकते हैं, उन्हें मुख्य श्रेणी से डॉट के साथ अलग कर सकते हैं।
उदाहरण के लिए, एक टैग क्लाउड (जो इंटरफ़ेस स्तर पर स्थित है) को प्रदर्शित करने के लिए दृश्य घटक UIControls.TagsControl है।
इस प्रकार, यदि घटक के साथ कोई समस्या है, तो एक तरफ, आप हमेशा लॉग से यह निर्धारित कर सकते हैं कि किस घटक ने यह या उस घटना को बनाया है, और दूसरे पर, केवल चयनित घटक के लिए इवेंट लॉग में इवेंट्स को फ़िल्टर करने के लिए अधिक लचीला है।
निष्कर्ष
लॉगिंग किसी भी एप्लिकेशन में एक महत्वपूर्ण विशेषता है और इसके लिए सावधानीपूर्वक विश्लेषण और डिजाइन की आवश्यकता होती है। इस तथ्य के बावजूद कि अनुरेखण आमतौर पर आवश्यकताओं में वर्णित नहीं है, इसका सही उपयोग परीक्षण और उत्पादन वातावरण पर दोषों का पता लगाने और ठीक करने की प्रक्रिया को काफी तेज कर सकता है।
ये गणना मेरे अभ्यास और अवलोकन हैं, और, तदनुसार, लॉगिंग (और विशेष रूप से ट्रेसिंग) का उपयोग करने के लिए आपके पास अपना अनुभव और अपनी खुद की कार्यप्रणाली हो सकती है। सिफारिशों को सुधारने के लिए महत्वपूर्ण प्रतिक्रिया और टिप्पणियां सुनकर मुझे खुशी हुई।
ट्रेस पर क्या पढ़ना है