性能优化
DD 在设计上追求高性能,以下是一些进一步优化日志性能的建议。
低分配优化
DD 在热路径上最小化内存分配:
IsLevelEnabled()检查使用原子操作,无锁- 结构化字段使用预分配缓冲区
- 避免在日志级别不匹配时格式化消息
级别检查
在高频路径上先检查级别,避免不必要的字段构造:
go
// 推荐:先检查级别
if logger.IsDebugEnabled() {
logger.DebugWith("详细信息",
dd.String("data", expensiveToString()),
dd.Int("size", len(largeSlice)),
)
}
// 不推荐:总是构造字段
logger.DebugWith("详细信息",
dd.String("data", expensiveToString()),
)缓冲写入
使用 BufferedWriter 减少 I/O 系统调用:
go
fw, _ := dd.NewFileWriter("logs/app.log", dd.DefaultFileWriterConfig())
bwCfg := dd.DefaultBufferedWriterConfig()
bwCfg.BufferSize = 8192
bw, _ := dd.NewBufferedWriter(fw, bwCfg) // 8KB 缓冲
logger, _ := dd.New(dd.Config{
Targets: []dd.OutputTarget{dd.CustomOutput(bw)},
})
defer logger.Close() // Close 会自动 Flush缓冲区大小
推荐 4KB-16KB。太小的缓冲区无法有效减少系统调用,太大的缓冲区增加内存使用和延迟。
日志采样
高吞吐场景下可启用日志采样,减少重复日志:
go
logger.SetSampling(&dd.SamplingConfig{
Enabled: true,
Initial: 100, // 前 100 条全部记录
Thereafter: 10, // 之后每 10 条记录 1 条
Tick: time.Minute, // 每分钟重置计数器
})
// 运行时动态调整
cfg := logger.GetSampling()文件写入优化
合理的轮换配置
go
fw, _ := dd.NewFileWriter("logs/app.log", dd.DefaultFileWriterConfig())
// 默认:100MB / 30 天 / 10 个备份- 文件过小导致频繁轮换,增加 I/O
- 备份过多占用磁盘空间
- 根据实际日志量调整参数
多文件分离
go
// 按级别分离
infoWriter, _ := dd.NewFileWriter("logs/info.log", dd.DefaultFileWriterConfig())
errorWriter, _ := dd.NewFileWriter("logs/error.log", dd.DefaultFileWriterConfig())Writer 管理
动态增减 Writer
go
// 运行时动态添加
logger.AddWriter(newWriter)
// 移除不再需要的 Writer
logger.RemoveWriter(oldWriter)避免过多 Writer
每个 Writer 都会增加写入延迟。推荐不超过 3-4 个 Writer。
字段优化
使用类型化字段
go
// 推荐:类型化构造器
dd.Int("count", 42)
dd.String("name", "test")
// 避免:Any(需要额外类型断言)
dd.Any("count", 42)避免大对象
go
// 不推荐:记录大对象
logger.InfoWith("数据", dd.Any("payload", hugeStruct))
// 推荐:仅记录关键信息
logger.InfoWith("数据",
dd.Int("count", len(items)),
dd.String("first", items[0].Name),
)关闭与清理
go
// 等待过滤协程完成
logger.WaitForFilterGoroutines(3 * time.Second)
// 优雅关闭,等待所有缓冲刷新
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
logger.Shutdown(ctx)