如何在 Go 中为单个通道配置多个独立的日志协程
一款功能相当强大的录音及音频编辑软件,不仅可以编辑音频,而且还可以录音,功能丰富,操作简单,使用方便,实用性强,并且占用电脑内存小,运行速度快,不卡顿电脑,使电脑系统保持良好的运行状态。支持许多格式的音频文件,包括WAV、OGG、VOC、IFF、AIFF、
Go中多个goroutine并发消费同一channel时,全局log.SetOutput被重复调用导致日志写入覆盖,所有日志仅输出到最后设置的日志文件。解决方案是为每个goroutine创建独立的*log.Logger实例,避免全局状态竞争,确保日志准确分流。
在 Go 中使用多个 goroutine 并发消费同一个 channel,这本是日常开发里的常规操作,但稍不留神就容易翻车——尤其是跟共享状态打交道的时候。你碰到的那个怪现象:“所有日志只写进了第四个文件”,真相并不是 channel 分发逻辑出了岔子,而是对 Go 标准库 log 包的使用踩了坑。
问题出在哪?log.SetOutput() 和 log.SetFlags() 这两个方法,修改的是全局、包级的默认 logger(也就是 log.Default() 返回的那个实例)。当 4 个 LogWorker.Work() 方法依次跑起来之后,每个方法都会调一次 log.SetOutput(...),把全局 logger 的输出目标换成自己的 lumberjack.Logger。最后执行的那个 goroutine(通常是第 4 个)的设置会留下来,覆盖掉前面三个。其余 goroutine 虽然也在老老实实地调 log.Println(...),但实际输出的目标早就被最后那个覆盖成了同一个——第四个文件。这就是为什么你只看到一个日志文件里有内容,其余三个文件干干净净。
✅ 正确的解决方案其实不复杂:给每个 goroutine 创建一个专属的 *log.Logger 实例,别再动全局 logger 了。把 LogWorker.Work 方法改成下面这样:
func (lw *LogWorker) Work(evChannel <-chan Event) {
fmt.Printf("LogWorker started: %s\n", lw.FileName)
// ✅ 为本 goroutine 创建独立 logger
lg := log.New(&lumberjack.Logger{
Filename: lw.FileName,
MaxSize: int64(lw.MaxSize) * 1024 * 1024, // 注意:lumberjack.MaxSize 单位是字节
MaxBackups: lw.MaxBackups,
MaxAge: lw.MaxAge,
}, "", log.LstdFlags) // 可选:加个时间戳之类的标志
// ✅ 使用 range 遍历 channel,优雅退出
for event := range evChannel {
lg.Println(Csv(event))
}
}
这段代码有四个关键改动值得注意:
- 独立 logger:
log.New(...)返回一个全新的实例,每个 goroutine 各持一份,互不干扰,彻底切断全局状态的污染。 - channel 类型注解:参数改成了
<-chan Event(只接收通道),语义更清晰,也防止误写操作。 - range 代替 for-select:
for event := range evChannel在 channel 关闭后会自动结束循环,避免for {}空转;写法也更符合 Go 的惯用风格。 - 单位修正:
lumberjack.MaxSize接收的是字节数,原代码里传的是int(MB),需要转成字节int64(lw.MaxSize) * 1024 * 1024,否则日志轮转可能会失效。
⚠️ 还有几个细节需要留意:
- channel 关闭管理:上面代码没有展示如何关闭
evChannel。生产环境中,建议在服务关闭前(比如收到 SIGINT 信号时)显式关闭 channel,通知所有 worker 退出。可以配合sync.WaitGroup等待 worker 结束。 - 错误处理增强:如果
Csv(event)有可能 panic 或返回 error,那在lg.Println()之前最好加一层防御性检查。 - 性能考量:
lumberjack.Logger本身是线程安全的,不需要额外加锁。但如果 CSV 序列化开销比较大,可以考虑在 worker 内部做批处理——比如先缓冲 N 条记录,再一次性写入。
经过上面这番改造,4 个 LogWorker 就能真正并行、独立地消费 evChannel,各自把日志写到指定的文件里(比如 event_0、event_1……),实现负载分散和日志隔离,再也不会互相干扰了。
Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。
Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。
Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。
Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。















