给程序安上“黑匣子”,让BUG无处遁形
01 从一个“赤裸”的日志说起
作为一名Go程序员,我最难忘的教训是:没日志的程序,就像在黑暗中调情——你永远不知道哪里出了问题。
还记得那次线上事故吗?哦,你可能还没遇到过。但我遇到过,而且记忆犹新。
那是一个美妙的周五下午,我提前完成了任务,悠闲地喝着咖啡,想着周末去哪玩。突然,监控系统发来警报:我们的Go服务内存泄漏,容器已经重启多次!
我火急火燎地登录服务器,却发现——日志干净得像刚洗过的盘子,除了几条“服务启动”的记录,几乎什么都没有。当时我就后悔了,为什么不在关键函数加几条日志?
package main
import "log"
func main() {
// 这就是Go日志的最简形式
log.Println("程序启动了,但能正常运行吗?")
processData()
// 当发生严重错误时
log.Fatalln("遇到致命错误,程序即将退出!") // 这会调用os.Exit(1)
}
func processData() {
// 普通的日志记录
log.Println("开始处理数据...")
// 格式化日志
dataSize := 1000
log.Printf("预计处理数据量:%d 条", dataSize)
}
执行这个程序,你会看到类似这样的输出:
2025/10/30 14:30:25 程序启动了,但能正常运行吗?
2025/10/30 14:30:25 开始处理数据...
2025/10/30 14:30:25 预计处理数据量:1000 条
看,Go标准库的log包默认就给我们提供了时间戳,这在排查问题时非常有用!
但这种基础日志在实际项目中远远不够,接下来,让我们进入日志的配置环节。
02 打扮你的日志:让它们变得“好看”又“有用”
默认的日志只显示时间,但在真实的项目环境中,我们需要更多信息:文件名、行号、微秒级时间,这些都能帮助我们快速定位问题。
Go语言考虑到了这一点,提供了丰富的配置选项。
package main
import (
"fmt"
"log"
"os"
)
func main() {
// 配置日志格式
log.SetFlags(log.Ldate | log.Ltime | log.Llongfile | log.Lmicroseconds)
log.Println("这是一条配置后的日志")
// 添加上下文信息
log.SetPrefix("[ORDER-SERVICE] ")
userId := "user-12345"
orderId := "order-67890"
log.Printf("用户 %s 创建订单 %s", userId, orderId)
// 重置前缀,避免影响后续示例
log.SetPrefix("")
}
运行上面的代码,你会看到类似这样的输出:
2025/10/30 14:31:45.123456 /home/user/go/src/main.go:15: 这是一条配置后的日志
[ORDER-SERVICE] 2025/10/30 14:31:45.123678 /home/user/go/src/main.go:19: 用户 user-12345 创建订单 order-67890
Flag常量说明:
Ldate:显示日期(2025/10/30)Ltime:显示时间(14:31:45)Lmicroseconds:显示微秒(.123456)Llongfile:完整文件路径和行号Lshortfile:仅文件名和行号(更简洁)LUTC

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



