যে গোলিং প্রোগ্রামটি সবেমাত্র ত্রুটি হয়েছে তার লাইন নম্বরটি মুদ্রণের জন্য আপনি কীভাবে তা পান?


96

আমি আমার গোলং প্রোগ্রামে ত্রুটিগুলি ছুঁড়ে দেওয়ার চেষ্টা করছিলাম log.Fatalতবে, log.Fatalযেখানে লাইনটি log.Fatalচালানো হয়েছিল তাও মুদ্রণ করে না । লগ নামক নামক লাইন নম্বরটিতে অ্যাক্সেস পাওয়ার কোনও উপায় নেই? অর্থাত্ একটি ত্রুটি নিক্ষেপ করার সময় লাইন নম্বর পাওয়ার কোনও উপায় আছে?

আমি এটি গুগল করার চেষ্টা করছিলাম কিন্তু কিভাবে অনিশ্চিত ছিল। স্ট্যাকের ট্রেস ছাপানো আমার পক্ষে সবচেয়ে ভাল জিনিস ছিল যা আমি অনুমান করি যে ভাল তবে এটি খুব বেশি পরিমাণেও হতে পারে। আমি debug.PrintStack()প্রতিবার যখন লাইন নম্বর প্রয়োজন তখন লিখতে চাই না , আমি অবাক হয়েছি log.FatalStackTrace()যে এই জাতীয় বা পোশাকের জন্য কোনও কার্যকরী কোনও বিল্ট নেই isn't

এছাড়াও, আমি নিজের ডিবাগিং / ত্রুটি হ্যান্ডলিং স্টাফগুলি তৈরি করতে না চাইার কারণ হ'ল আমি চাই না যে লোকেরা কীভাবে আমার বিশেষ পোশাক হ্যান্ডলিং কোডটি ব্যবহার করতে হয় তা শিখতে হবে। আমি কেবল এমন কিছু স্ট্যান্ডার্ড চাই যেখানে লোকেরা আমার কোডটি পরে পড়তে এবং পছন্দ করতে পারে

"আহ ঠিক আছে, সুতরাং এটি একটি ত্রুটি ছুঁড়েছে এবং এক্স করছে ..."

কম লোকদের আমার কোড সম্পর্কে আরও ভাল জানতে হবে :)



আপনি যে মুহুর্তে লাইন নম্বর মুদ্রণ করছেন তার অর্থ হল আমাকে আপনার কোডে ডুব দিতে হবে, সুতরাং "কম লোকেরা আমার কোড সম্পর্কে ভালভাবে শিখতে হবে" তা এখানে রয়েছে। আপনার যা করা উচিত তা হল পরিষ্কার এবং সংক্ষিপ্ত ত্রুটি।
Wessie

উত্তর:


124

আপনি কোনও কাস্টম লগার, অথবা ডিফল্ট অন্তর্ভুক্ত করতে বা সেট করতে পারেনLlongfileLshortfile

// 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)
ওয়ানওফোন

আমি কি সত্যিই একটি পরিবর্তনশীল তৈরি করতে হবে? আমি আমার গো ফাইলের শীর্ষে লগইন.সেটফ্লাগগুলি (লগ.এলস্টডি ফ্ল্যাশস | লগ.সাল্টফিল) করতে পারি না? আমি একটি ত্রুটি expected declaration, found 'INDENT' logপাই : যখন আমি চেষ্টা করি log.SetFlags(log.LstdFlags | log.Lshortfile)। এটি কেবল আমাকে এর জন্য একটি ভেরিয়েবল তৈরি করতে বিরক্ত করে, কেন সেখানে একটি হতে পারে না log.Fatal("string", log.Flag)। তবে নতুন ভেরিয়েবল লগ তৈরির কাজ হয়েছে। লগ ভেরিয়েবল এবং স্টাফ তৈরি করা কি কোনও স্ট্যান্ডার্ড জিনিস?
পিনোচিও

4
@ পিনোকিও: ত্রুটিটি কারণ এটি বৈধ গো নয়, শীর্ষ স্তরে আপনার খালি ফাংশন কল থাকতে পারে না। এটি init () বা অন্য কোনও এন্ট্রি-পয়েন্টে রাখুন।
জিমবি

4
আপনাকে এটি লাগাতে হবেfunc init() {}
OneOfOne

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

4
অসাধারণ! ধন্যবাদ এটি runtimeপ্যাকেজ ব্যবহারের দুর্দান্ত উদাহরণ । লগগুলির মাধ্যমে ডিবাগ করার জন্য খুব সহায়ক।
18 ই

2

আপনার যদি হুবহু স্ট্যাক ট্রেস দরকার হয় তবে 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)
}

এবং এখানে আউটপুট: গোলং ত্রুটি স্ট্যাক ট্রেস

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.