Debian Golang日志格式化技巧分享
在Debian系统中,Golang日志格式化可根据需求选择标准库log(基础需求)或第三方库(logrus/zap/slog,高级需求)实现。以下是具体技巧与示例:
log:基础格式化配置标准库log提供简单日志功能,通过SetPrefix(设置前缀)和SetFlags(设置标志)自定义格式:
log.Ldate(日期,格式2006/01/02)、log.Ltime(时间,格式15:04:05)、log.Lshortfile(文件名+行号,如main.go:10)、log.Llongfile(完整文件路径+行号)。package main
import (
"log"
"os"
)
func main() {
log.SetPrefix("INFO: ") // 设置日志前缀
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) // 组合标志
log.Println("这是一条基础格式化日志") // 输出:INFO: 2025/09/25 14:30:00 main.go:10: 这是一条基础格式化日志
}
logrus:灵活文本/JSON格式化logrus是Golang经典结构化日志库,支持文本(带字段)和JSON格式,可通过TextFormatter或JSONFormatter自定义:
TextFormatter设置时间戳、调用者信息、字段输出。package main
import (
"github.com/sirupsen/logrus"
)
func main() {
logrus.SetFormatter(&logrus.TextFormatter{
FullTimestamp: true, // 显示完整时间戳(如2025-09-25 14:30:00.123)
CallerPrettyfier: func(f *runtime.Frame) (string, string) {
return "", f.File + ":" + strconv.Itoa(f.Line) // 仅显示文件名+行号
},
})
logrus.SetReportCaller(true) // 启用调用者信息
logrus.WithFields(logrus.Fields{
"animal": "walrus",
"size": 10,
}).Info("A group of walrus emerges from the ocean")
// 输出:INFO[2025-09-25 14:30:00.123] A group of walrus emerges from the ocean animal=walrus size=10 file=main.go:15
}
JSONFormatter设置时间戳格式、字段名称,输出结构化JSON。logrus.SetFormatter(&logrus.JSONFormatter{
TimestampFormat: "2006-01-02 15:04:05", // 自定义时间戳格式
FieldMap: logrus.FieldMap{
logrus.FieldKeyTime: "@timestamp", // 自定义时间字段名
logrus.FieldKeyLevel: "severity", // 自定义级别字段名
logrus.FieldKeyMsg: "message", // 自定义消息字段名
},
})
logrus.Info("This is a JSON formatted log")
// 输出:{"@timestamp":"2025-09-25 14:30:00","severity":"info","message":"This is a JSON formatted log"}
zap:高性能结构化日志zap是Uber开源的高性能结构化日志库,适合高并发场景,通过EncoderConfig自定义JSON/控制台格式:
EncodeTime(时间格式)、EncodeLevel(级别编码)、EncodeCaller(调用者编码),输出紧凑JSON。package main
import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func main() {
encoderConfig := zapcore.EncoderConfig{
TimeKey: "timestamp",
LevelKey: "level",
NameKey: "logger",
CallerKey: "caller",
MessageKey: "message",
EncodeTime: zapcore.ISO8601TimeEncoder, // ISO8601时间格式
EncodeLevel: zapcore.LowercaseLevelEncoder, // 小写级别(info/warn/error)
EncodeCaller: zapcore.ShortCallerEncoder, // 短调用者(文件名:行号)
}
core := zapcore.NewCore(
zapcore.NewJSONEncoder(encoderConfig), // JSON编码器
zapcore.AddSync(os.Stdout), // 输出到控制台
zap.InfoLevel, // 日志级别
)
logger := zap.New(core)
defer logger.Sync() // 确保日志刷新
logger.Info("This is a high-performance structured log",
zap.String("key", "value"),
zap.Int("count", 1),
)
// 输出:{"level":"info","timestamp":"2025-09-25T14:30:00+08:00","caller":"main.go:15","message":"This is a high-performance structured log","key":"value","count":1}
}
slog:Go 1.21+原生结构化日志slog(Structured Logging)是Go 1.21引入的原生结构化日志库,无需第三方依赖,支持JSON和文本格式:
NewJSONHandler创建处理器,输出结构化JSON。package main
import (
"log/slog"
"os"
)
func main() {
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
logger.Info("User logged in",
"username", "gopher",
"user_id", 123,
)
// 输出:{"time":"2025-09-25T14:30:00+08:00","level":"INFO","msg":"User logged in","username":"gopher","user_id":123}
}
NewTextHandler创建处理器,自定义前缀和标志。logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
AddSource: true, // 显示源代码位置
}))
logger.Info("This is a text formatted log")
// 输出:INFO\tmain.go:10\tThis is a text formatted log
无论使用哪种库,添加上下文信息(如请求ID、用户ID)是提升日志可观测性的关键:
logrus示例:log := logrus.WithFields(logrus.Fields{
"request_id": "123e4567-e89b-12d3-a456-426614174000",
"user_id": 1001,
})
log.Info("Request received") // 输出包含request_id和user_id的日志
zap示例:logger.Info("Request processed",
zap.String("request_id", "123e4567-e89b-12d3-a456-426614174000"),
zap.Int("user_id", 1001),
)
slog示例:logger.Info("Request completed",
slog.String("request_id", "123e4567-e89b-12d3-a456-426614174000"),
slog.Int("user_id", 1001),
)
request_id串联请求链路)。zap的AsyncCore或zerolog的异步写入,减少对主程序的影响。DEBUG日志进行采样(如每100条记录1条),降低磁盘IO。lumberjack库实现日志文件按大小/时间轮转,避免日志文件过大。以上技巧覆盖了Debian环境下Golang日志格式化的常见需求,可根据项目规模、性能要求选择合适的方案。