如何在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
相关产品推荐
相关产品推荐

