Golang中如何仅对错误日志启用行号显示

Golang中如何仅对错误日志启用行号显示 我发现 log.SetFlags(log.LstdFlags | log.Lshortfile) 可以为所有 log 输出启用行号。但是有没有办法只为错误对象、FatalFatalf 启用行号呢?

log.SetFlags(log.LstdFlags | log.Lshortfile)
2 回复

无法仅为 FatalFatalf 函数启用行号。但是,你可以使用结构体嵌入来自定义它,如下所示:

package main

import (
	"io"
	"log"
	"os"
)

type MyLog struct {
	*log.Logger
	fatal *log.Logger
}

func New(out io.Writer, prefix string, flag int) *MyLog {
	l := &MyLog{
		Logger: log.New(out, prefix, flag),
		fatal:  log.New(out, prefix, flag|log.LstdFlags|log.Lshortfile),
	}
	return l
}

func (l *MyLog) Fatal(v ...interface{}) {
	l.fatal.Fatal(v...)
}

func main() {
	logger := New(os.Stderr, "logger: ", log.Lshortfile)

	logger.Print("Hello, log file!")
	logger.Fatal("Hello, log file!")
}

https://play.golang.org/p/9lr3FL5sYeN

更多关于Golang中如何仅对错误日志启用行号显示的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,标准库的log包不支持针对不同日志级别设置不同的输出格式。log.SetFlags()方法会全局影响所有通过该日志记录器输出的内容。

不过,你可以通过以下方式实现仅对错误日志启用行号显示:

方案1:创建自定义日志记录器

package main

import (
    "log"
    "os"
)

var (
    infoLog  *log.Logger
    errorLog *log.Logger
)

func init() {
    // 普通日志 - 不带行号
    infoLog = log.New(os.Stdout, "INFO: ", log.LstdFlags)
    
    // 错误日志 - 带行号
    errorLog = log.New(os.Stderr, "ERROR: ", log.LstdFlags|log.Lshortfile)
}

func main() {
    infoLog.Println("这是一条普通信息")
    errorLog.Println("这是一条错误信息,会显示文件名和行号")
    
    // 模拟Fatal错误
    errorLog.Fatal("致命错误,会显示行号")
}

方案2:包装标准日志函数

package main

import (
    "log"
    "os"
)

func Error(v ...interface{}) {
    log.SetFlags(log.LstdFlags | log.Lshortfile)
    log.SetPrefix("ERROR: ")
    log.Print(v...)
    log.SetFlags(log.LstdFlags)
    log.SetPrefix("")
}

func Info(v ...interface{}) {
    log.SetFlags(log.LstdFlags)
    log.SetPrefix("INFO: ")
    log.Print(v...)
}

func main() {
    Info("普通信息日志")
    Error("错误信息,带行号显示")
}

方案3:使用结构化的日志库

对于更复杂的日志需求,建议使用成熟的日志库如zaplogrus

package main

import (
    "go.uber.org/zap"
)

func main() {
    logger, _ := zap.NewProduction()
    defer logger.Sync()
    
    // 普通日志
    logger.Info("普通信息")
    
    // 错误日志 - 自动包含调用位置
    logger.Error("错误信息", 
        zap.String("key", "value"),
    )
}

第一种方案是最直接的方法,通过创建不同的日志记录器实例来分别控制输出格式,这样可以精确地为错误日志启用行号显示,而普通日志保持简洁格式。

回到顶部