Saat menggunakan flag log.Lshortfile, logger mengawali semua baris log dengan nama file dan nomor baris dari panggilan fungsi logger, misalnya:

myfile.go:14: Hello, world!

Jika saya membungkus fungsi log seperti ini, misalnya:

func info(pattern string, args ...interface{}) {
    myLogger.Printf(pattern + "\n", args...)
}

Setiap baris yang dipancarkan oleh fungsi ini akan diawali dengan nomor baris panggilan Printf. Itu seperti yang diharapkan, tetapi perilaku yang diinginkan adalah agar setiap baris diawali dengan nomor baris dari baris tempat info dipanggil.

Apakah ada cara untuk mengatasinya?

10
Hubro 13 Maret 2017, 14:21

2 jawaban

Jawaban Terbaik

Metode log.Logger memanggil Logger.Output() metode untuk mengirim pesan ke output yang sesuai. Logger.Output() memungkinkan Anda untuk melewati calldepth (jumlah frame yang akan dilewati).

Sayangnya metode log.Logger berisi calldepth "terkabel", jadi Anda tidak dapat memberikan offset untuk melewati bingkai fungsi pembungkus.

Tetapi alternatif yang jauh lebih baik adalah memanggil ini Logger.Output() dari pembungkus Anda, jadi Anda tidak perlu repot dengan bingkai dan garis sendiri. Perhatikan juga bahwa Anda tidak perlu menambahkan baris baru "\n", karena tipe log.Logger sudah melakukannya jika pesan yang akan dicatat tidak diakhiri dengan baris baru.

Jadi alternatif yang lebih baik dan lebih pendek:

var myLogger = log.New(os.Stdout, "[my]", log.Lshortfile)

func info(pattern string, args ...interface{}) {
    myLogger.Output(2, fmt.Sprintf(pattern, args...))
}

Mengujinya:

func main() {
    log.SetFlags(log.Lshortfile)
    log.Println("hello")
    info("world")
}

Output (coba di Go Playground):

main.go:11: hello
[my]main.go:12: world

Seperti yang Anda lihat, info() mencetak nomor baris yang benar (+1 dibandingkan dengan nomor baris yang dicetak oleh log.Println() di baris sebelumnya).

11
icza 13 Maret 2017, 11:57

Saya akan memasukkan ini dalam pertanyaan sebagai solusi saya saat ini, tetapi saya kira itu adalah jawaban yang valid. Saya berharap seseorang dapat memberi tahu saya tentang opsi konfigurasi logger yang saya lewatkan yang memungkinkan saya menyesuaikan kedalaman yang digunakan logger saat memanggil runtime.Caller.

Solusinya adalah dengan menghapus tanda log.Lshortfile dan menerapkan perilaku tersebut secara manual:

func info(format string, args ...interface{}) {
    _, file, line, _ := runtime.Caller(1)

    prefix := fmt.Sprintf("%v:%v: ", path.Base(file), line)

    if logger != nil {
        logger.Printf(prefix+format+"\n", args...)
    }
}
0
Hubro 13 Maret 2017, 11:24