
log.Println() 默认输出到标准错误,若要写入文件需用 os.OpenFile() 配置正确的打开模式(如 O_RDWR | O_CREATE | O_APPEND),而 os.Open() 仅以只读方式打开,无法创建文件或写入日志。
go语言中使用log包将日志写入文件的正确方法:`log.println()` 默认输出到标准错误,若要写入文件需用 `os.openfile()` 配置正确的打开模式(如 `o_rdwr | o_create | o_append`),而 `os.open()` 仅以只读方式打开,无法创建文件或写入日志。
在 Go 中,log.Println() 默认将日志输出到 os.Stderr。若希望将日志持久化到文件,必须通过 log.SetOutput(io.Writer) 显式设置输出目标。但一个常见误区是直接使用 os.Open("logfile") —— 这会导致日志“静默失败”:程序不报错、也不写入内容。
原因在于:os.Open(filename) 是 os.OpenFile(filename, os.O_RDONLY, 0) 的简写,它仅以只读(O_RDONLY)模式打开文件,且不会自动创建文件。如果文件不存在,os.Open 返回 *os.PathError;即使文件存在,由于是只读打开,后续 log.Println() 的写入操作会因底层 io.Writer 不支持写入而被忽略(实际调用 file.Write() 时返回 &os.SyscallError{Syscall: "write", Err: syscall.EBADF},但 log 包默认不暴露该错误)。
✅ 正确做法是使用 os.OpenFile() 并指定可写、可创建、可追加的标志:
package main
import (
"log"
"os"
)
func main() {
// ✅ 推荐:以读写、创建、追加模式打开日志文件
file, err := os.OpenFile("logfile.txt", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
log.Fatalf("无法打开或创建日志文件: %v", err)
}
defer file.Close()
log.SetOutput(file)
log.Println("这条日志已成功写入 logfile.txt")
}
? 关键标志说明:
-
os.O_RDWR:允许写入(必需,否则log写入失败); -
os.O_CREATE:文件不存在时自动创建; -
os.O_APPEND:每次写入自动定位到文件末尾,避免覆盖历史日志; - 权限
0644:Unix 系统下设为-rw-r--r--,兼顾安全性与可读性。
⚠️ 注意事项:
-
永远不要忽略
os.OpenFile的错误:_忽略错误会导致调试困难; -
defer file.Close()应在log.SetOutput(file)之后立即设置,确保文件句柄及时释放; - 若需多 goroutine 安全写入,
log.Logger本身是并发安全的,无需额外加锁; - 生产环境建议使用更成熟的日志库(如
zap或logrus)支持分级、轮转、结构化等功能。
通过正确配置文件打开模式,即可让 Go 的标准 log 包稳定、可靠地将日志写入磁盘文件。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











