2015-11-24 13 views
8

मैंने अब तक log.Fatal का उपयोग टाला है, लेकिन मैंने हाल ही में इन प्रश्नों को सह-खोजा है; code-coverage और tests-using-log-fatalक्या एक गो पैकेज कभी लॉग का उपयोग करना चाहिए। घातक और कब?

100 कोड कवरेज सवालों से टिप्पणी में से एक का कहना है: ...

मामलों log.Fatal के विशाल बहुमत में केवल मुख्य, या init कार्यों में इस्तेमाल किया जा किया जाना चाहिए (या शायद कुछ बातें करने के लिए होती उन लोगों से केवल सीधे बुलाया जाना) "

यह मुझे सोच जाना है, इसलिए मैं जाओ के साथ प्रदान की मानक पुस्तकालय कोड को देखने के लिए शुरू कर दिया। वहाँ उदाहरण के बहुत सारे जहां पुस्तकालय में परीक्षण कोड का उपयोग करता है कर रहे हैं log.Fatal जो ठीक लगता है। वहाँ हैं ,

// net/http/transport.go 
func (t *Transport) putIdleConn(pconn *persistConn) bool { 
    ... 
    for _, exist := range t.idleConn[key] { 
     if exist == pconn { 
      log.Fatalf("dup idle pconn %p in freelist", pconn) 
     } 
    } 
    ... 
} 

अपने सबसे अच्छा अभ्यास log.Fatal के उपयोग से बचने के लिए है, तो क्यों है यह मानक पुस्तकालयों में बिल्कुल भी इस्तेमाल किया, मैं अपेक्षा की होगी: इस तरह के net/http में के रूप में परीक्षण कोड, के बाहर कुछ उदाहरण हैं, नीचे दिखाया गया है बस एक त्रुटि वापस करें। यह लाइब्रेरी के उपयोगकर्ता को os.Exit कहने के लिए अनुचित लगता है और एप्लिकेशन को साफ-सफाई के लिए कोई मौका नहीं प्रदान करता है।

मैं निष्पक्ष हो सकता हूं, इसलिए मेरा प्रश्न बेहतर अभ्यास के रूप में log.Panic पर कॉल करना प्रतीत होता है जिसे पुनर्प्राप्त किया जा सकता है और मेरे सैद्धांतिक लंबे चलने वाले स्थिर अनुप्रयोग को राख से बढ़ने का मौका मिल सकता है।

तो लॉग के समय के बारे में गो के लिए सबसे अच्छा अभ्यास क्या होगा। घातक का उपयोग किया जाना चाहिए?

+3

मेरी आशा यह होगी कि यह कोड बिल्कुल पहुंच योग्य नहीं है। यह एक त्रुटि है जो एक निष्क्रिय कनेक्शन को निष्क्रिय सूची में अभी भी होने का कारण बनती है जबकि एक सक्रिय कनेक्शन के रूप में भी प्रयोग किया जा रहा है, ऐसा कुछ नहीं होना चाहिए जो कभी भी होना चाहिए, और इसके लिए होने वाला कुछ विनाशकारी होना चाहिए। लेकिन चूंकि वे निष्क्रिय सूची के आस-पास ठीक से म्यूटेक्स का उपयोग कर रहे हैं और मुझे पता नहीं है कि यह लूप और कोड भी आवश्यक क्यों होगा। क्यों वे पैनसिंग के बजाए तुरंत आपके कार्यक्रम से बाहर निकलेंगे एक और रहस्य है। महान सवाल – captncraig

+0

क्या उस पैकेज में कोई भी परीक्षण उस लाइन तक पहुंचने में सक्षम है? – captncraig

+0

अच्छा सवाल, थोड़ा सा देखो और कुछ भी नहीं देख सकता जो कि विशेष रूप से उस रेखा तक पहुंचने के लिए डिज़ाइन किया गया है। अभी तक निर्णायक नहीं है ... – miltonb

उत्तर

8

यह सिर्फ मुझे हो सकता है, लेकिन यहां मैं log.Fatal का उपयोग कैसे करता हूं। यूनिक्स सम्मेलनों के अनुसार, एक प्रक्रिया जो त्रुटि का सामना करती है, एक गैर-शून्य निकास कोड के साथ जितनी जल्दी हो सके विफल होनी चाहिए। यह मैं निम्नलिखित दिशा-निर्देशों के लिए नेतृत्व जब log.Fatal उपयोग करने के लिए ...

  1. ... मेरी func init() में से किसी में एक त्रुटि होता है, के रूप में इन हो सकता है जब आयात कार्रवाई की जाती है या मुख्य समारोह कहा जाता है से पहले, क्रमशः। इसके विपरीत, मैं केवल उन चीजों को करता हूं जो पुस्तकालय या cmd को काम करने की इकाई की इकाई को सीधे प्रभावित नहीं करते हैं। उदाहरण के लिए, मैंने लॉगिंग सेट अप की है और गीलेर की जांच की है, हमारे पास एक सभ्य वातावरण और पैरामीटर हैं। यदि हमारे पास अवैध झंडे हैं, तो मुख्य रूप से चलाने की आवश्यकता नहीं है, है ना? और अगर हम उचित प्रतिक्रिया नहीं दे सकते हैं, तो हमें इसे जल्दी ही बताना चाहिए।
  2. ... एक त्रुटि होती है जिसके बारे में मुझे पता है कि यह अपरिवर्तनीय है। आइए मान लें कि हमारे पास एक प्रोग्राम है जो कमांड लाइन पर दी गई छवि फ़ाइल का थंबनेल बनाता है। यदि यह फ़ाइल मौजूद नहीं है या अपर्याप्त अनुमतियों के कारण अपठनीय है, तो जारी रखने का कोई कारण नहीं है और यह त्रुटि पुनर्प्राप्त नहीं की जा सकती है। तो हम सम्मेलनों का पालन करते हैं और असफल होते हैं।
  3. ... एक प्रक्रिया के दौरान एक त्रुटि होती है जो कि उलट नहीं हो सकती है। यह एक मुलायम परिभाषा है, मुझे पता है। मुझे इसे स्पष्ट करने दें। आइए मान लें कि हमारे पास cp का कार्यान्वयन है, और यह गैर-इंटरैक्टिव होने और एक निर्देशिका को दोबारा कॉपी करने के लिए शुरू किया गया था। अब, मान लीजिए कि हम लक्ष्य निर्देशिका में एक फ़ाइल का सामना करते हैं जिसमें एक ही नाम (लेकिन अलग-अलग सामग्री) है, जिसकी प्रतिलिपि बनाने के लिए फ़ाइल है। चूंकि हम उपयोगकर्ता से यह तय करने के लिए नहीं कह सकते कि क्या करना है और हम इस फ़ाइल की प्रतिलिपि नहीं बना सकते हैं, हमें एक समस्या है। चूंकि उपयोगकर्ता यह मान लेगा कि जब हम निकास कोड शून्य के साथ समाप्त करते हैं तो स्रोत और लक्ष्य निर्देशिका सटीक प्रतियां होती हैं, इसलिए हम फ़ाइल को प्रश्न में छोड़ नहीं सकते हैं। हालांकि, हम इसे आसानी से ओवरराइट नहीं कर सकते हैं, क्योंकि इससे संभावित रूप से जानकारी नष्ट हो सकती है।यह एक ऐसी स्थिति है जिसे हम उपयोगकर्ता द्वारा प्रति स्पष्ट अनुरोध से पुनर्प्राप्त नहीं कर सकते हैं, और इसलिए मैं स्थिति को समझाने के लिए log.Fatal का उपयोग करूंगा, इस प्रकार सिद्धांत को जल्द से जल्द विफल करने का पालन करता हूं।
+1

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

+1

यह थोड़ा सा अंतर्निहित है, हालांकि, मैं गीलेर के बावजूद उन नियमों को लागू करता हूं, मैं एक पैकेज या एक cmd लिखता हूं: एक अपरिवर्तनीय त्रुटि एक अपरिवर्तनीय त्रुटि है। यह एक पैकेज स्वीकृत इनपुट देने के लिए एक कार्यक्रम जिम्मेदारी है। यदि यह संभव नहीं है, तो एक त्रुटि लौटा दी जानी चाहिए, लेकिन केवल तभी इनपुट को पहले से संचरित नहीं किया जा सकता है। तो जहां उचित है वास्तव में एक पैकेज के उपयोगकर्ता को बेहतर कोड लिखने में मदद करता है। –

+1

बात यह है कि यह पैकेज रखरखाव की कॉल नहीं है अगर कुछ अपरिवर्तनीय है या नहीं। निश्चित रूप से, आप थंबनेल उत्पन्न करने में विफल रहे, लेकिन मैं इसे अपने वेब सर्वर के एक छोटे से हिस्से के रूप में उपयोग कर रहा था। यदि कोई थंबनेल पैकेज ओ.एक्सिट कहता है क्योंकि यह फ़ाइल लोड नहीं कर सकता है, तो मैं परेशान होगा। – captncraig

संबंधित मुद्दे