如何使用Golang log包记录日志_Golang log日志输出示例

11次阅读

log.println自动加空格和换行,适合快速调试;log.printf支持格式化输出、需手动换行,适合结构化日志;二者均写入os.Stderr。

如何使用Golang log包记录日志_Golang log日志输出示例

log.Println 和 log.Printf 的区别在哪

两者都写入 os.Stderr,但语义和格式控制不同:log.Println 自动加空格、换行,适合快速调试;log.Printf 支持格式化字符串,类似 fmt.Printf,适合结构化输出。

常见错误是混用:比如用 log.Println("user_id:", id, "Error:", err) 看似方便,但一旦 errnil,输出会变成 user_id: 123 error: ,可读性差;而 log.Printf("user_id: %d, error: %v", id, err) 能明确控制 nil 的显示方式(默认为 ,也可提前判空)。

  • 如果日志只是临时排查,log.Println 足够轻量
  • 如果需统一字段顺序、避免空格歧义、或拼接 jsON 片段,必须用 log.Printf
  • 注意 log.Printf 不自动换行,漏写 n 会导致多条日志挤在同一行

如何让 log 输出带时间戳和文件位置

默认的 log 包不带这些信息,需通过 log.SetFlags 启用标志位。关键组合是:

log.SetFlags(log.LstdFlags | log.Lshortfile)

log.LstdFlags 包含日期、时间、微秒;log.Lshortfile 输出 file.go:23 形式,比 Llongfile 更紧凑。

立即学习go语言免费学习笔记(深入)”;

容易忽略的点:

  • log.SetFlags 必须在首次调用 log.Print* 前设置,否则无效
  • 不要同时设 LdateLtime —— LstdFlags 已包含它们,重复设置会导致时间重复打印
  • Lshortfile 在交叉编译或使用 go run 时可能显示 command-line-arguments,这是正常行为,不影响运行时定位

能否把 log 输出重定向到文件而不是终端

可以,核心是替换默认的输出目标:把 log.SetOutput 指向一个 *os.File

典型做法:

file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil {     log.Fatal(err) } log.SetOutput(file)

注意事项:

  • 务必检查 err,否则日志静默丢失,极难排查
  • 进程退出前不用手动 file.Close() —— log 包不负责关闭底层 Writer
  • 若需滚动日志(如按天切分),标准库不支持,得换 lumberjack 或自行封装
  • 多 goroutine 写同一文件安全,log 内部有锁,但高并发下可能成瓶颈

log.Fatal 和 panic 的实际差异是什么

log.Fatal 本质是 log.Print + os.Exit(1),它不会触发 defer,也不会被 recover 捕获;panic 则会执行 defer 并可被 recover 拦截。

使用场景判断:

  • 遇到无法继续初始化的错误(如配置文件缺失、端口被占),用 log.Fatal —— 明确表示“这个进程必须停”
  • 业务逻辑中出现异常但想兜底处理(如降级返回默认值),用 panic + recover,但需谨慎,golang 官方更倾向显式错误返回
  • 误用 log.Fatalhttp handler 中会导致整个服务退出,这是严重事故

最常被忽略的一点:无论 log.Fatal 还是 log.Panic,它们调用的都是 log.Output,所以之前设置的 FlagsOutput 依然生效 —— 日志内容仍会写入文件或带上时间戳。

text=ZqhQzanResources