
Go 的 log 包默认输出到 os.Stderr,调用 log.SetOutput() 可自定义写入目标;若需恢复原始控制台输出,只需重新设置为 os.Stdout 或 os.Stderr 即可。
go 的 `log` 包默认输出到 `os.stderr`,调用 `log.setoutput()` 可自定义写入目标;若需恢复原始控制台输出,只需重新设置为 `os.stdout` 或 `os.stderr` 即可。
在 Go 应用开发与测试过程中,我们常通过 log.SetOutput() 将日志重定向至内存缓冲区(如 bytes.Buffer)、文件或自定义 io.Writer,以实现日志捕获、隔离或格式化。但测试结束后,若希望日志重新打印到终端(即恢复“默认行为”),却容易误以为需要特殊重置函数——实际上,Go 标准库并未提供 ResetOutput() 这类方法,恢复控制台输出的本质,是显式地将输出目标重新设回 os.Stdout 或 os.Stderr。
log 包的初始状态由 log.New() 初始化决定:全局变量 log.Logger(即 log.Print 等函数所用的默认 logger)在包初始化时已通过 log.New(os.Stderr, "", log.LstdFlags) 构建,因此其默认输出目标始终是 os.Stderr。这意味着:
-
✅ 恢复标准错误输出(最常见,默认行为):
log.SetOutput(os.Stderr)
-
✅ 恢复标准输出(如需将日志打印到 stdout 而非 stderr):
log.SetOutput(os.Stdout)
⚠️ 注意事项:
- os.Stdout 和 os.Stderr 是全局、线程安全的 *os.File 实例,可直接作为 io.Writer 使用,无需额外包装;
- 若你在测试中使用了 log.SetOutput(ioutil.Discard) 或 log.SetOutput(&bytes.Buffer{}),务必在 tearDown 阶段(如 TestMain 或 t.Cleanup 中)显式恢复,否则后续测试可能因日志静默而难以调试;
- 多 goroutine 场景下,log.SetOutput() 是并发安全的,但应避免在日志写入高峰期频繁切换输出目标,以防短暂竞态导致日志丢失或错乱;
- 如需更灵活的日志管理(如按模块切换输出、支持多目标),建议迁移到结构化日志库(如 zap 或 zerolog),而非依赖全局 log 包的状态变更。
总结:Go 日志输出没有“隐藏默认句柄”,只有明确的 io.Writer 绑定。所谓“恢复默认”,实则是重新绑定到 os.Stderr(推荐)或 os.Stdout —— 简洁、可靠、符合 Go 的显式设计哲学。










