सामान्य तौर पर, लॉगिंग किसी कंप्यूटर प्रोग्राम से जनरेट हुए लॉग को रखने का एक तरीका है। एक लॉग फ़ाइल में आमतौर पर आपके कोड (जैसे, एक Python कोड) या ऑपरेटिंग सिस्टम में होने वाली घटनाओं के रिकॉर्ड का सेट होता है। ये घटनाएँ या संदेश एक लॉग फ़ाइल में लिखे जाते हैं; कोई संदेश या घटना अलग-अलग उपयोगकर्ताओं के बीच संचार भी हो सकती है।
आमतौर पर यह इस पर निर्भर करता है कि डेवलपर लॉग कैसे जनरेट करना चाहते हैं। हो सकता है वे अपने बनाए गए एप्लिकेशन के हर ऑपरेशन को लॉग करना चाहें, केवल तब लॉग करें जब कोई त्रुटि हो, या किसी उपयोगकर्ता द्वारा की गई आवश्यक कार्रवाइयों की निगरानी कर उन्हें लॉग करें। एक आवश्यक कार्रवाई, उदाहरण के लिए, यह जाँचना हो सकती है कि एप्लिकेशन या सर्वर तक किस एंड-यूज़र या IP एड्रेस से पहुँचा गया, और यदि वह प्रयास असफल रहा हो, तो डेवलपर लॉग की मदद से मात्र एक स्टैक ट्रेस की तुलना में बेहतर समझ प्रदान कर सकते हैं।
एक अच्छा उदाहरण तब है जब आप Linux पर sudo उपयोगकर्ता न होते हुए भी sudo के रूप में इंस्टॉलेशन करने की कोशिश करते हैं। आपको संदेश दिखाई देता है "Xyz is not in the sudoers file. This incident will be reported", जो कि एक लॉग फ़ाइल में लिखा जाता है।
अच्छी खबर यह है कि Python में बिल्ट-इन लॉगिंग मॉड्यूल आता है, और आप इसे बिना किसी इंस्टॉलेशन के तुरंत उपयोग कर सकते हैं।
लॉगिंग Print फ़ंक्शन से कैसे अलग है?
आत्मा में, लॉगिंग Print Function के समान है। हालाँकि, Print फ़ंक्शन में वह बहुत-सी जानकारी नहीं होती जो डेवलपर के लिए उपयोगी हो सकती है। दूसरी ओर, लॉगिंग टाइमस्टैम्प और वह पंक्ति संख्या लॉग कर सकती है जिस पर त्रुटि हुई। यह त्रुटियाँ या कोई भी सूचना फ़ाइलों, सॉकेट्स आदि में लॉग कर सकती है, और यह आपको पाँच प्रकार की गंभीरता प्रदान करती है जिनके आधार पर आप अपनी लॉगिंग को अलग कर सकते हैं।
Debug (10): कोड में समस्याओं के निदान के लिए उपयोगी।
Info (20): यह इस बात की पुष्टि के रूप में काम कर सकता है कि कोड में बग नहीं हैं। Info स्तर की लॉगिंग का एक अच्छा उपयोग-केस किसी मशीन लर्निंग मॉडल के प्रशिक्षण की प्रगति है।
Warning (30): भविष्य में हो सकने वाली किसी समस्या का संकेत। उदाहरण के लिए, किसी मॉड्यूल के भविष्य में बंद होने की चेतावनी या लो-रैम चेतावनी।
Error (40): कोड में एक गंभीर बग; यह सिंटैक्स एरर, आउट-ऑफ-मेमोरी एरर, अपवाद इत्यादि हो सकते हैं।
Critical (50): ऐसी त्रुटि जिसके कारण प्रोग्राम काम करना बंद कर सकता है या अचानक बंद हो सकता है।
काफी सिद्धांत हो गया, है ना?
अब समझते हैं कि आप Python कोड में लॉगिंग कैसे लागू कर सकते हैं।
लेकिन उससे पहले, लॉगिंग एट्रिब्यूट तालिका देखते हैं; आप आज के ट्यूटोरियल में नीचे दिए गए कुछ लॉगिंग एट्रिब्यूट्स का उपयोग करेंगे।
जैसा कि आप ऊपर के आउटपुट से देख सकते हैं, केवल वे ही सफलतापूर्वक लॉग हुए जिनकी गंभीरता का स्तर 20 से अधिक था, क्योंकि Python में लॉगिंग की यही डिफ़ॉल्ट कॉन्फ़िगरेशन है।
हालाँकि, जैसा कि ऊपर चर्चा की गई, आप basicConfig() मेथड का उपयोग कर गंभीरता के स्तर बदल सकते हैं। यहाँ आप गंभीरता स्तर को 20 पर बदलेंगे, जिसका अर्थ है कि 10 से अधिक गंभीरता वाले लॉगिंग स्तर लॉग होंगे।
नोट: सही आउटपुट देखने के लिए कृपया नीचे की कोशिकाएँ चलाने से पहले कर्नेल को पुनः आरंभ करें।
logging.critical("A Critical Logging Message")संचालित द्वारा
जैसा कि आप देख सकते हैं, अब लॉग्स एक लॉग फ़ाइल datacamp.log में जनरेट हो रहे हैं। ऊपर की कोशिकाएँ कई बार चलाने पर आप देखेंगे कि उतनी ही बार लॉग्स लॉग फ़ाइल में जुड़ते जाएँगे। डिफ़ॉल्ट रूप से फ़ाइल append मोड में होती है।
आप filemode कीवर्ड का उपयोग कर लॉग फ़ाइल में कई प्रतियों में लॉग्स लिखे जाने यानी append मोड को रोक सकते हैं। filemode को write मोड में बदला जा सकता है, जो पिछले लॉग्स को ओवरराइट करेगा और केवल वर्तमान लॉग्स सहेजेगा। चूँकि filemode w पर सेट है, इसका अर्थ है कि हर बार basicConfig() चलने पर लॉग फ़ाइल write mode में खुलेगी, जो अंततः फ़ाइल को ओवरराइट कर देगी।
लॉगिंग में फ़ाइल मोड की कार्यक्षमता Python द्वारा उपलब्ध कराए गए मानक फ़ाइल हैंडलिंग के समान है।
आइए ऊपर की कोड पंक्तियाँ कई बार चलाते हैं। आप देखेंगे कि इस बार केवल वर्तमान लॉग प्रविष्टियाँ सहेजी जाएँगी और पिछली ओवरराइट हो जाएँगी, जैसा कि नीचे दिखाया गया है।
आइए कुछ और लॉगिंग एट्रिब्यूट्स देखते हैं जैसे तिथि, समय, वह पंक्ति संख्या जिस पर चेतावनी या त्रुटि जनरेट हुई। अब तक आप सहमत होंगे कि ये सभी एक साधारण Print फ़ंक्शन पर फायदे हैं और यह मात्र Print फ़ंक्शन की तुलना में कहीं अधिक सक्षम है।
इसे पूरा करने के लिए, आप asctime और lineno लॉगिंग एट्रिब्यूट्स पास करेंगे। साथ ही आप message एट्रिब्यूट भी पास करेंगे, जो उन संदेशों के लिए प्लेसहोल्डर होगा जिन्हें आप लॉग में दिखाना चाहते हैं। ये सभी एट्रिब्यूट्स format मेथड को पास किए जाएँगे।
Date-Time :2020-03-1823:58:12,429: Line No.:1-A Debug Logging Message
Date-Time :2020-03-1823:58:12,436: Line No.:2-A Info Logging Message
Date-Time :2020-03-1823:58:12,437: Line No.:3-A Warning Logging Message
Date-Time :2020-03-1823:58:12,440: Line No.:4- An Error Logging Message
Date-Time :2020-03-1823:58:12,441: Line No.:5-A Critical Logging Message
संचालित द्वारा
आइए प्रत्येक एट्रिब्यूट की परिभाषाएँ सीधे इस तालिका से देखते हैं।
asctime: वह मानव-पठनीय समय जब LogRecord जनरेट हुआ। डिफ़ॉल्ट रूप से, यह 2020-03-18 22:24:42,670 के रूप में होता है (अल्पविराम के बाद की संख्याएँ समय का मिलीसेकंड भाग हैं)। चूँकि यह एट्रिब्यूट एक स्ट्रिंग है, इसलिए आप इसके बाद s कीवर्ड का उपयोग करते हैं।
lineno: स्रोत पंक्ति संख्या जहाँ से लॉगिंग कॉल की गई। चूँकि यह एट्रिब्यूट एक पूर्णांक है, इसलिए आप इसके बाद d कीवर्ड का उपयोग करते हैं।
message: लॉग किया गया संदेश, जिसे msg % args के रूप में गणना किया जाता है। यह तब सेट होता है जब Formatter.format() इनवोक होता है। यदि आप format() पैरामीटर का उपयोग करते समय इस एट्रिब्यूट को निर्दिष्ट नहीं करते, तो वे संदेश जिन्हें आप लॉग करना चाहते हैं, जनरेट नहीं होंगे। इसी तरह, message एट्रिब्यूट के लिए आप s का उपयोग करते हैं क्योंकि यह एक स्ट्रिंग है।
funcName: यह उस मॉड्यूल या फ़ंक्शन का नाम आउटपुट करेगा जिसमें लॉग जनरेट हुआ। यह तब उपयोगी है जब आपके कोड में बहुत-से फ़ंक्शंस हों और आप लॉग्स को उस फ़ंक्शन या मेथड के आधार पर अलग करना चाहें जिससे वे संबंधित हैं।
आइए एक सरल उदाहरण लेते हैं और देखते हैं कि आप प्रिंट फ़ंक्शन की जगह लॉगिंग डिबग फ़ंक्शन कैसे प्लग-इन कर सकते हैं।
import logging
logging.basicConfig(format='%(asctime)s ::%(levelname)s ::%(funcName)s ::%(lineno)d \
::%(message)s', level = logging.INFO)defaddition(x, y):
add = x + y
return add
defsubtract(x, y):
sub = x - y
return sub
defmultiply(x, y):
mul = x * y
return mul
defdivide(x, y):
div = x / y
return div
defexponent(x, y):
exp = x ** y
return exp
num1 =20
num2 =2defmain():
add_result = addition(num1, num2)
logging.info('Add: {} + {} = {}'.format(num1, num2, add_result))
sub_result = subtract(num1, num2)
logging.info('Sub: {} - {} = {}'.format(num1, num2, sub_result))
mul_result = multiply(num1, num2)
logging.info('Mul: {} * {} = {}'.format(num1, num2, mul_result))
div_result = divide(num1, num2)
logging.info('Div: {} / {} = {}'.format(num1, num2, div_result))
exp_result = exponent(num1, num2)
logging.info('Exp: {} ** {} = {}'.format(num1, num2, exp_result))
main()संचालित द्वारा
2020-03-1900:01:27,372::INFO:: main ::35:: Add:20+2=222020-03-1900:01:27,376::INFO:: main ::38:: Sub:20-2=182020-03-1900:01:27,377::INFO:: main ::41:: Mul:20*2=402020-03-1900:01:27,378::INFO:: main ::44:: Div:20/2=10.02020-03-1900:01:27,379::INFO:: main ::47:: Exp:20**2=400संचालित द्वारा
निष्कर्ष
ट्यूटोरियल पूरा करने पर बधाई।
आप दूसरे लॉगिंग एट्रिब्यूट्स भी आज़मा सकते हैं और समझ सकते हैं कि उन्हें अपने कोड में कैसे उपयोग में लाया जा सकता है।
कृपया इस ट्यूटोरियल से संबंधित कोई भी प्रश्न नीचे कमेंट सेक्शन में बेझिझक पूछें।
Python के साथ डेटा विश्लेषण की बुनियादी बातें सिर्फ चार घंटे में सीखें। यह ऑनलाइन पाठ्यक्रम Python इंटरफ़ेस का परिचय देगा और लोकप्रिय पैकेजों का अन्वेषण करेगा।
यदि आप Python में अभी-अभी शुरुआत कर रहे हैं और अधिक सीखना चाहते हैं, तो DataCamp का Introduction to Data Science in Python कोर्स करें।
सामान्य तौर पर, लॉगिंग किसी कंप्यूटर प्रोग्राम से जनरेट हुए लॉग को रखने का एक तरीका है। एक लॉग फ़ाइल में आमतौर पर आपके कोड (जैसे, एक Python कोड) या ऑपरेटिंग सिस्टम में होने वाली घटनाओं के रिकॉर्ड का सेट होता है। ये घटनाएँ या संदेश एक लॉग फ़ाइल में लिखे जाते हैं; कोई संदेश या घटना अलग-अलग उपयोगकर्ताओं के बीच संचार भी हो सकती है।
आमतौर पर यह इस पर निर्भर करता है कि डेवलपर लॉग कैसे जनरेट करना चाहते हैं। हो सकता है वे अपने बनाए गए एप्लिकेशन के हर ऑपरेशन को लॉग करना चाहें, केवल तब लॉग करें जब कोई त्रुटि हो, या किसी उपयोगकर्ता द्वारा की गई आवश्यक कार्रवाइयों की निगरानी कर उन्हें लॉग करें। एक आवश्यक कार्रवाई, उदाहरण के लिए, यह जाँचना हो सकती है कि एप्लिकेशन या सर्वर तक किस एंड-यूज़र या IP एड्रेस से पहुँचा गया, और यदि वह प्रयास असफल रहा हो, तो डेवलपर लॉग की मदद से मात्र एक स्टैक ट्रेस की तुलना में बेहतर समझ प्रदान कर सकते हैं।
एक अच्छा उदाहरण तब है जब आप Linux पर sudo उपयोगकर्ता न होते हुए भी sudo के रूप में इंस्टॉलेशन करने की कोशिश करते हैं। आपको संदेश दिखाई देता है "Xyz is not in the sudoers file. This incident will be reported", जो कि एक लॉग फ़ाइल में लिखा जाता है।
अच्छी खबर यह है कि Python में बिल्ट-इन लॉगिंग मॉड्यूल आता है, और आप इसे बिना किसी इंस्टॉलेशन के तुरंत उपयोग कर सकते हैं।
लॉगिंग Print फ़ंक्शन से कैसे अलग है?
आत्मा में, लॉगिंग
Print Functionके समान है। हालाँकि, Print फ़ंक्शन में वह बहुत-सी जानकारी नहीं होती जो डेवलपर के लिए उपयोगी हो सकती है। दूसरी ओर, लॉगिंग टाइमस्टैम्प और वह पंक्ति संख्या लॉग कर सकती है जिस पर त्रुटि हुई। यह त्रुटियाँ या कोई भी सूचना फ़ाइलों, सॉकेट्स आदि में लॉग कर सकती है, और यह आपको पाँच प्रकार की गंभीरता प्रदान करती है जिनके आधार पर आप अपनी लॉगिंग को अलग कर सकते हैं।यहाँ दिखाए गए लॉगिंग के पाँच स्तर हैं:
Debug (10): कोड में समस्याओं के निदान के लिए उपयोगी।
Info (20): यह इस बात की पुष्टि के रूप में काम कर सकता है कि कोड में बग नहीं हैं। Info स्तर की लॉगिंग का एक अच्छा उपयोग-केस किसी मशीन लर्निंग मॉडल के प्रशिक्षण की प्रगति है।
Warning (30): भविष्य में हो सकने वाली किसी समस्या का संकेत। उदाहरण के लिए, किसी मॉड्यूल के भविष्य में बंद होने की चेतावनी या लो-रैम चेतावनी।
Error (40): कोड में एक गंभीर बग; यह सिंटैक्स एरर, आउट-ऑफ-मेमोरी एरर, अपवाद इत्यादि हो सकते हैं।
Critical (50): ऐसी त्रुटि जिसके कारण प्रोग्राम काम करना बंद कर सकता है या अचानक बंद हो सकता है।
काफी सिद्धांत हो गया, है ना?
अब समझते हैं कि आप Python कोड में लॉगिंग कैसे लागू कर सकते हैं।
लेकिन उससे पहले, लॉगिंग एट्रिब्यूट तालिका देखते हैं; आप आज के ट्यूटोरियल में नीचे दिए गए कुछ लॉगिंग एट्रिब्यूट्स का उपयोग करेंगे।
अब आप
basicConfig()मेथड को कॉल करेंगे, जो लॉगिंग सिस्टम के सुचारू रूप से काम करने के लिए एक बुनियादी कॉन्फ़िगरेशन बनाने में मदद करता है।यह आपको निम्न पैरामीटर्स सेट करने की अनुमति देता है:
ध्यान रखें कि
basicConfig()मेथड वैकल्पिक है, और आप इसे छोड़ना भी चाहें तो छोड़ सकते हैं।अब हम पाँच स्तरों की गंभीरता बनाएँगे।
जैसा कि आप ऊपर के आउटपुट से देख सकते हैं, केवल वे ही सफलतापूर्वक लॉग हुए जिनकी गंभीरता का स्तर 20 से अधिक था, क्योंकि Python में लॉगिंग की यही डिफ़ॉल्ट कॉन्फ़िगरेशन है।
हालाँकि, जैसा कि ऊपर चर्चा की गई, आप
basicConfig()मेथड का उपयोग कर गंभीरता के स्तर बदल सकते हैं। यहाँ आप गंभीरता स्तर को 20 पर बदलेंगे, जिसका अर्थ है कि 10 से अधिक गंभीरता वाले लॉगिंग स्तर लॉग होंगे।नोट: सही आउटपुट देखने के लिए कृपया नीचे की कोशिकाएँ चलाने से पहले कर्नेल को पुनः आरंभ करें।
अब हम ऊपर के आउटपुट्स को एक लॉग फ़ाइल में लॉग करेंगे। इसे करने के लिए आप
basicConfig()मेथड का उपयोग करेंगे।जैसा कि आप देख सकते हैं, अब लॉग्स एक लॉग फ़ाइल
datacamp.logमें जनरेट हो रहे हैं। ऊपर की कोशिकाएँ कई बार चलाने पर आप देखेंगे कि उतनी ही बार लॉग्स लॉग फ़ाइल में जुड़ते जाएँगे। डिफ़ॉल्ट रूप से फ़ाइलappendमोड में होती है।आप
filemodeकीवर्ड का उपयोग कर लॉग फ़ाइल में कई प्रतियों में लॉग्स लिखे जाने यानी append मोड को रोक सकते हैं। filemode कोwriteमोड में बदला जा सकता है, जो पिछले लॉग्स को ओवरराइट करेगा और केवल वर्तमान लॉग्स सहेजेगा। चूँकि filemodewपर सेट है, इसका अर्थ है कि हर बारbasicConfig()चलने पर लॉग फ़ाइलwrite modeमें खुलेगी, जो अंततः फ़ाइल को ओवरराइट कर देगी।लॉगिंग में फ़ाइल मोड की कार्यक्षमता Python द्वारा उपलब्ध कराए गए मानक फ़ाइल हैंडलिंग के समान है।
आइए ऊपर की कोड पंक्तियाँ कई बार चलाते हैं। आप देखेंगे कि इस बार केवल वर्तमान लॉग प्रविष्टियाँ सहेजी जाएँगी और पिछली ओवरराइट हो जाएँगी, जैसा कि नीचे दिखाया गया है।
आइए कुछ और लॉगिंग एट्रिब्यूट्स देखते हैं जैसे तिथि, समय, वह पंक्ति संख्या जिस पर चेतावनी या त्रुटि जनरेट हुई। अब तक आप सहमत होंगे कि ये सभी एक साधारण Print फ़ंक्शन पर फायदे हैं और यह मात्र Print फ़ंक्शन की तुलना में कहीं अधिक सक्षम है।
इसे पूरा करने के लिए, आप
asctimeऔरlinenoलॉगिंग एट्रिब्यूट्स पास करेंगे। साथ ही आपmessageएट्रिब्यूट भी पास करेंगे, जो उन संदेशों के लिए प्लेसहोल्डर होगा जिन्हें आप लॉग में दिखाना चाहते हैं। ये सभी एट्रिब्यूट्सformatमेथड को पास किए जाएँगे।आइए प्रत्येक एट्रिब्यूट की परिभाषाएँ सीधे इस तालिका से देखते हैं।
asctime: वह मानव-पठनीय समय जब LogRecord जनरेट हुआ। डिफ़ॉल्ट रूप से, यह2020-03-18 22:24:42,670के रूप में होता है (अल्पविराम के बाद की संख्याएँ समय का मिलीसेकंड भाग हैं)। चूँकि यह एट्रिब्यूट एक स्ट्रिंग है, इसलिए आप इसके बादsकीवर्ड का उपयोग करते हैं।lineno: स्रोत पंक्ति संख्या जहाँ से लॉगिंग कॉल की गई। चूँकि यह एट्रिब्यूट एक पूर्णांक है, इसलिए आप इसके बादdकीवर्ड का उपयोग करते हैं।message: लॉग किया गया संदेश, जिसे msg % args के रूप में गणना किया जाता है। यह तब सेट होता है जब Formatter.format() इनवोक होता है। यदि आप format() पैरामीटर का उपयोग करते समय इस एट्रिब्यूट को निर्दिष्ट नहीं करते, तो वे संदेश जिन्हें आप लॉग करना चाहते हैं, जनरेट नहीं होंगे। इसी तरह, message एट्रिब्यूट के लिए आपsका उपयोग करते हैं क्योंकि यह एक स्ट्रिंग है।funcName: यह उस मॉड्यूल या फ़ंक्शन का नाम आउटपुट करेगा जिसमें लॉग जनरेट हुआ। यह तब उपयोगी है जब आपके कोड में बहुत-से फ़ंक्शंस हों और आप लॉग्स को उस फ़ंक्शन या मेथड के आधार पर अलग करना चाहें जिससे वे संबंधित हैं।आइए एक सरल उदाहरण लेते हैं और देखते हैं कि आप प्रिंट फ़ंक्शन की जगह लॉगिंग डिबग फ़ंक्शन कैसे प्लग-इन कर सकते हैं।
निष्कर्ष
ट्यूटोरियल पूरा करने पर बधाई।
आप दूसरे लॉगिंग एट्रिब्यूट्स भी आज़मा सकते हैं और समझ सकते हैं कि उन्हें अपने कोड में कैसे उपयोग में लाया जा सकता है।
कृपया इस ट्यूटोरियल से संबंधित कोई भी प्रश्न नीचे कमेंट सेक्शन में बेझिझक पूछें।
यदि आप Python में अभी-अभी शुरुआत कर रहे हैं और अधिक सीखना चाहते हैं, तो DataCamp का Introduction to Data Science in Python कोर्स करें।