आपको उस त्रुटि की लाइन संख्या को प्रिंट करने के लिए गोलंग कार्यक्रम कैसे मिलता है?


94

मैं अपने गोलंग कार्यक्रम में त्रुटियों को फेंकने की कोशिश कर रहा था log.Fatal, लेकिन, log.Fatalउस रेखा को भी नहीं छापता, जहां log.Fatalभाग गया था। क्या लॉग.फ़ॉल नामक लाइन नंबर तक पहुंचने का कोई तरीका नहीं है? यानी त्रुटि फेंकते समय लाइन नंबर प्राप्त करने का एक तरीका है?

मैं यह गूगल करने के लिए कोशिश कर रहा था, लेकिन अनिश्चित कैसे था। सबसे अच्छी चीज जो मुझे मिल सकती है वह स्टैक ट्रेस को प्रिंट करना था , जो मुझे लगता है कि अच्छा है लेकिन थोड़ा बहुत हो सकता है। मैं debug.PrintStack()हर बार यह भी लिखना नहीं चाहता कि मुझे लाइन नंबर की आवश्यकता है, मुझे आश्चर्य log.FatalStackTrace()है कि इस तरह या इस तरह की पोशाक के लिए कोई फ़ंक्शन नहीं बनाया गया है।

इसके अलावा, कारण यह है कि मैं अपना डिबगिंग / एरर हैंडलिंग सामान नहीं बनाना चाहता, क्योंकि मैं नहीं चाहता कि लोगों को यह सीखना पड़े कि मुझे अपने विशेष कॉस्ट्यूम हैंडलिंग कोड का उपयोग कैसे करना है। मैं बस कुछ मानक चाहता हूं जहां लोग बाद में मेरे कोड को पढ़ सकें और पसंद कर सकें

"आह ठीक है, तो इसकी एक त्रुटि और एक्स कर रहा है ..."

कम लोगों को मेरे कोड के बारे में बेहतर सीखना होगा :)



जिस क्षण आप लाइन नंबर प्रिंट कर रहे हैं, इसका मतलब है कि मुझे आपके कोड में गोता लगाना होगा, इसलिए "कम लोगों को मेरे कोड के बारे में बेहतर सीखना होगा" यहाँ पर मूट है। आपको जो करना चाहिए वह स्पष्ट और संक्षिप्त त्रुटियां हैं।
वेसी जूल

जवाबों:


122

आप या तो एक कस्टम लॉगर, या डिफ़ॉल्ट शामिल करने के लिए पर झंडे सेट कर सकते हैं LlongfileयाLshortfile

// to change the flags on the default logger
log.SetFlags(log.LstdFlags | log.Lshortfile)

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

4
हां, यदि आप एक कस्टम लॉग का उपयोग कर रहे हैं तो आप इसका उपयोग कर सकते हैं var mylog = log.New(os.Stderr, "app: ", log.LstdFlags | log.Lshortfile)
OneOfOne

क्या मुझे वास्तव में एक वैरिएबल बनाना है? मैं अपनी लॉग फ़ाइल के शीर्ष पर log.SetFlags (log.LstdFlags | log.Lshortfile) बस नहीं कर सकता? मुझे एक त्रुटि मिलती है: expected declaration, found 'INDENT' logजब मैं करने की कोशिश करता हूं log.SetFlags(log.LstdFlags | log.Lshortfile)। यह सिर्फ मुझे इसके लिए एक चर बनाने के लिए परेशान करता है, क्यों नहीं हो सकता है ए log.Fatal("string", log.Flag)। लेकिन एक नया वैरिएबल लॉग बनाने से काम चल गया। क्या लॉग चर और सामान बनाना एक मानक बात है?
पिनोचियो

3
@Pinocchio: यह त्रुटि है क्योंकि यह मान्य नहीं है, आप शीर्ष स्तर पर एक नंगे फ़ंक्शन कॉल नहीं कर सकते। इसे init () या किसी अन्य प्रविष्टि-बिंदु पर रखें।
जिमब

5
आपको इसे func init() {}
लगाना होगा

94

लघु संस्करण, इसमें सीधे कुछ भी नहीं बनाया गया है, हालांकि आप इसे कम से कम सीखने की अवस्था के साथ लागू कर सकते हैं runtime.Caller

func HandleError(err error) (b bool) {
    if err != nil {
        // notice that we're using 1, so it will actually log where
        // the error happened, 0 = this function, we don't want that.
        _, fn, line, _ := runtime.Caller(1)
        log.Printf("[error] %s:%d %v", fn, line, err)
        b = true
    }
    return
}

//this logs the function name as well.
func FancyHandleError(err error) (b bool) {
    if err != nil {
        // notice that we're using 1, so it will actually log the where
        // the error happened, 0 = this function, we don't want that.
        pc, fn, line, _ := runtime.Caller(1)

        log.Printf("[error] in %s[%s:%d] %v", runtime.FuncForPC(pc).Name(), fn, line, err)
        b = true
    }
    return
}

func main() {
    if FancyHandleError(fmt.Errorf("it's the end of the world")) {
        log.Print("stuff")
    }
}

playground


11
जबकि पहले से दिए गए उत्तर ने समस्या को बड़े करीने से ठीक कर दिया है, आपके समाधान ने मुझे कुछ भयानक - रनटाइम पैकेज के अस्तित्व के लिए सतर्क कर दिया है! लवली सामान :) golang.org/pkg/runtime
Gwyneth Llewelyn

fnचर से सौंपा runtime.Caller()वास्तव में फ़ाइल, नहीं एक समारोह संदर्भ का नाम है। मैं fn को फ़ंक्शन के रूप में समझता हूं , फ़ाइल नाम के बारे में नहीं ।
sshow

1
बहुत बढ़िया! धन्यवाद। यह runtimeपैकेज उपयोग का महान उदाहरण है । लॉग के माध्यम से डिबगिंग के लिए बहुत उपयोगी है।
18 उद्घाटन

1

यदि आपको वास्तव में स्टैक ट्रेस की आवश्यकता है, तो https://github.com/ztrue/tracerr पर एक नज़र डालें

स्टैक ट्रेस और स्रोत टुकड़े दोनों को अधिक डीबग करने और अधिक विवरण के साथ त्रुटियों को लॉग करने में सक्षम होने के लिए मैंने यह पैकेज बनाया।

यहाँ एक कोड उदाहरण है:

package main

import (
    "io/ioutil"
    "github.com/ztrue/tracerr"
)

func main() {
    if err := read(); err != nil {
        tracerr.PrintSourceColor(err)
    }
}

func read() error {
    return readNonExistent()
}

func readNonExistent() error {
    _, err := ioutil.ReadFile("/tmp/non_existent_file")
    // Add stack trace to existing error, no matter if it's nil.
    return tracerr.Wrap(err)
}

और यहाँ उत्पादन है: गोलंग त्रुटि स्टैक ट्रेस

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.