登录
首页 >  Golang >  Go教程

Golang日志格式设置技巧

时间:2026-01-20 09:10:34 290浏览 收藏

本篇文章给大家分享《Golang log设置日志格式方法》,覆盖了Golang的常见基础知识,其实一个语言的全部知识点一篇文章是不可能说完的,但希望通过这些问题,让读者对自己的掌握程度有一定的认识(B 数),从而弥补自己的不足,更好的掌握它。

Go标准库log仅支持前缀开关和输出重定向,不支持结构化日志;需用zap等专用库实现JSON、level等字段化功能。

如何使用Golang log设置日志输出格式_Golang log日志格式示例

Go log.SetFlags() 控制日志前缀和格式

Go 标准库 log 包本身不支持自定义字段(如 JSON、level 字段),但能通过 log.SetFlags() 控制时间、文件名、行号等前缀开关。默认只输出内容,没时间戳——这是新手最常忽略的“日志看起来没格式”的原因。

  • log.Ldate | log.Ltime:输出类似 2024/05/12 14:23:56 message
  • log.Lshortfile:显示 main.go:23log.Llongfile 显示完整路径
  • 多个标志用按位或组合:log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
  • 设为 0 可完全禁用所有前缀,只留原始字符串

Go log.SetOutput() 重定向日志到文件或 stderr

默认输出到 os.Stderr,但容易和错误流混在一起。生产环境通常要写入文件,或区分 info/warn/error 流。注意:直接传 *os.File 是安全的,但别传已关闭的文件句柄,否则后续 log.Print() 会 panic 并报 write /dev/stderr: bad file descriptor

  • 写入文件:log.SetOutput(newFile),记得用 os.OpenFile(..., os.O_CREATE|os.O_APPEND|os.O_WRONLY)
  • 同时输出到控制台和文件?需封装 io.MultiWriter
  • 避免在 goroutine 中反复调用 SetOutput —— 它不是并发安全的,且会覆盖全局实例

为什么不要直接用标准 log 做结构化日志

当你需要 {"level":"info","msg":"user login","uid":1001} 这种格式时,log 包无能为力。它不解析内容,只拼接字符串前缀 + fmt.Sprint() 结果。强行用 log.Printf("{\"level\":\"info\",...}") 会导致转义混乱、无法统一字段顺序、缺失堆栈上下文。

  • 推荐替代方案:zap(高性能)、zerolog(零分配)、logrus(易上手)
  • 如果必须用标准库,可封装一个函数生成 JSON 字符串再交给 log.Print(),但无法享受结构化解析优势
  • 注意:log.SetPrefix() 只加固定前缀(如 [INFO]),不能动态插入变量
package main

import (
    "log"
    "os"
)

func main() {
    // 启用日期、时间、短文件名
    log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
    
    // 写入文件而非 stderr
    f, _ := os.OpenFile("app.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
    log.SetOutput(f)
    defer f.Close()
    
    log.Println("server started")
    log.Printf("listening on %s", ":8080")
}
标准库 log 的格式能力仅限于前缀开关和输出目标,真要字段化、分级、采样、Hook,得换专用日志库——这点在项目初期就该明确,别等到日志查不出问题才回头重构。

好了,本文到此结束,带大家了解了《Golang日志格式设置技巧》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

前往漫画官网入口并下载 ➜
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>