You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Go中创建带自定义格式的多文件与Stdout/Stderr日志记录器

Go实现多输出目标的日志记录器(带自定义格式)

核心思路

log包的log.New()函数接受一个io.Writer作为输出目标,而io.MultiWriter()可以把多个Writer合并成一个,让日志同时输出到多个地方。只需要把你之前定义的前缀、格式标志(如日期时间)和合并后的Writer一起传给log.New(),就能完整保留原有的自定义格式配置。

完整实现代码

package main

import (
	"io"
	"log"
	"os"
)

func main() {
	// 打开info日志文件:不存在则创建,以追加模式写入
	infoFile, err := os.OpenFile("info.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		log.Fatalf("无法打开info.log: %v", err)
	}
	defer infoFile.Close()

	// 打开error日志文件
	errorFile, err := os.OpenFile("errors.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		log.Fatalf("无法打开errors.log: %v", err)
	}
	defer errorFile.Close()

	// 合并标准输出与info日志文件为同一个Writer
	infoWriter := io.MultiWriter(os.Stdout, infoFile)
	// 合并标准错误输出与error日志文件为同一个Writer
	errorWriter := io.MultiWriter(os.Stderr, errorFile)

	// 创建带自定义格式的info日志实例
	infoLog := log.New(infoWriter, "INFO: ", log.Ldate|log.Ltime)
	// 创建带自定义格式的error日志实例(额外添加文件行号)
	errorLog := log.New(errorWriter, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)

	// 测试日志输出
	infoLog.Println("用户发起了登录请求")
	errorLog.Println("数据库连接超时")
}

关键细节说明

  • 文件打开配置:os.O_CREATE|os.O_WRONLY|os.O_APPEND确保文件不存在时自动创建,只允许写入操作,且新日志追加到文件末尾不会覆盖原有内容;权限0644表示文件所有者可读可写,其他用户仅可读。
  • MultiWriter工作逻辑:它会将写入的内容同步复制到所有传入的Writer中,所以调用infoLog.Println()时,日志会同时出现在终端标准输出和info.log文件里。
  • 自定义格式保留:log.New()的第二个参数是日志前缀,第三个参数是格式标志(比如log.Ldate|log.Ltime会添加日期时间戳,log.Lshortfile会添加文件名和行号),这些配置和你之前单独创建日志实例时完全一致,只是输出目标换成了合并后的Writer。
  • 资源清理:用defer语句确保程序退出时自动关闭日志文件,避免资源泄漏。

内容的提问来源于stack exchange,提问作者Coldchain9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 15:37:33