我们可以将所有控制台日志定向到文件吗?
can we direct all console log to file?
当 运行 Web 应用在本地使用命令
go run MainPackageFile.go
我们可以映射记录器,例如用马提尼
m := martini.Classic()
m.Get("/m", func() string {
return "Hello world!"
})
m.Map(log.New(f, "[martini]", log.LstdFlags))
但是,如果代码外部出现问题怎么办,例如 Go 无法下载包等...有没有办法获取这些 Go 运行时日志?
当 运行 本地错误将打印到控制台上。有没有办法在服务器 运行 时,我们可以将所有这些日志写入文本文件?
您可以使用此函数将标准错误重定向到文件。这将收到回溯。
// redirectStderr to the file passed in
func redirectStderr(f *os.File) {
err := syscall.Dup2(int(f.Fd()), int(os.Stderr.Fd()))
if err != nil {
log.Fatalf("Failed to redirect stderr to file: %v", err)
}
}
它只适用于 linux/mac/unix。
下面是如何为 windows
做同样的事情
var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
procSetStdHandle = kernel32.MustFindProc("SetStdHandle")
)
func setStdHandle(stdhandle int32, handle syscall.Handle) error {
r0, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0)
if r0 == 0 {
if e1 != 0 {
return error(e1)
}
return syscall.EINVAL
}
return nil
}
// redirectStderr to the file passed in
func redirectStderr(f *os.File) {
err := setStdHandle(syscall.STD_ERROR_HANDLE, syscall.Handle(f.Fd()))
if err != nil {
log.Fatalf("Failed to redirect stderr to file: %v", err)
}
}
假设您的代码使用日志库到处报告错误,您可以更改默认记录器写入的文件,而不是定义您自己的日志对象并将其四处传递。这是通过日志库的 SetOutput() 函数完成的。
这样,下面的代码将只写入您的日志文件而不是标准错误:
// Call this when your program starts and pass it the file handle for your
// log file.
func SetupErrorLog(logFile io.Writer) {
log.SetOutput(logFile)
}
...
func DoSomething() {
...
if err != nil {
// prints to your log file and exits
log.Fatalln("A fatal error has occurred:", err)
}
}
如果您没有统一使用日志库并且想要捕获所有输出(如恐慌),那么接受的答案就可以了。但是,我更喜欢一种更简单的方法,而不是在调用程序时使用像记录器这样的工具来使代码复杂化:
go run MainPackageFile.go 2>&1 | logger
这会将您程序的所有输出发送到系统日志,而不必弄乱您的代码。 logger 命令有许多选项来自定义日志记录行为,包括选择您自己的日志文件的能力。阅读 logger man page 了解更多信息。
logger 命令在 Unix 系统(包括 Mac)上可用。 Windows 解决方案可能略有不同。
当 运行 Web 应用在本地使用命令
go run MainPackageFile.go
我们可以映射记录器,例如用马提尼
m := martini.Classic()
m.Get("/m", func() string {
return "Hello world!"
})
m.Map(log.New(f, "[martini]", log.LstdFlags))
但是,如果代码外部出现问题怎么办,例如 Go 无法下载包等...有没有办法获取这些 Go 运行时日志? 当 运行 本地错误将打印到控制台上。有没有办法在服务器 运行 时,我们可以将所有这些日志写入文本文件?
您可以使用此函数将标准错误重定向到文件。这将收到回溯。
// redirectStderr to the file passed in
func redirectStderr(f *os.File) {
err := syscall.Dup2(int(f.Fd()), int(os.Stderr.Fd()))
if err != nil {
log.Fatalf("Failed to redirect stderr to file: %v", err)
}
}
它只适用于 linux/mac/unix。
下面是如何为 windows
做同样的事情var (
kernel32 = syscall.MustLoadDLL("kernel32.dll")
procSetStdHandle = kernel32.MustFindProc("SetStdHandle")
)
func setStdHandle(stdhandle int32, handle syscall.Handle) error {
r0, _, e1 := syscall.Syscall(procSetStdHandle.Addr(), 2, uintptr(stdhandle), uintptr(handle), 0)
if r0 == 0 {
if e1 != 0 {
return error(e1)
}
return syscall.EINVAL
}
return nil
}
// redirectStderr to the file passed in
func redirectStderr(f *os.File) {
err := setStdHandle(syscall.STD_ERROR_HANDLE, syscall.Handle(f.Fd()))
if err != nil {
log.Fatalf("Failed to redirect stderr to file: %v", err)
}
}
假设您的代码使用日志库到处报告错误,您可以更改默认记录器写入的文件,而不是定义您自己的日志对象并将其四处传递。这是通过日志库的 SetOutput() 函数完成的。
这样,下面的代码将只写入您的日志文件而不是标准错误:
// Call this when your program starts and pass it the file handle for your
// log file.
func SetupErrorLog(logFile io.Writer) {
log.SetOutput(logFile)
}
...
func DoSomething() {
...
if err != nil {
// prints to your log file and exits
log.Fatalln("A fatal error has occurred:", err)
}
}
如果您没有统一使用日志库并且想要捕获所有输出(如恐慌),那么接受的答案就可以了。但是,我更喜欢一种更简单的方法,而不是在调用程序时使用像记录器这样的工具来使代码复杂化:
go run MainPackageFile.go 2>&1 | logger
这会将您程序的所有输出发送到系统日志,而不必弄乱您的代码。 logger 命令有许多选项来自定义日志记录行为,包括选择您自己的日志文件的能力。阅读 logger man page 了解更多信息。
logger 命令在 Unix 系统(包括 Mac)上可用。 Windows 解决方案可能略有不同。