在golang捕捉恐慌() [英] Capturing panic() in golang
问题描述
我们有一个使用记录器(实际上是一个自定义记录器)的大型golang应用程序将输出写入一个定期旋转的日志文件。
但是,当应用程序崩溃或panic()的时候,这些消息会变成标准错误。
有什么办法可以覆盖panic功能来使用我们的记录器? / p>
据我所知,您不能将输出从恐慌中重定向到标准错误或记录器。您可以做的最好的事情是将标准错误重定向到一个文件,您可以在外部或在程序中执行。
对于我的 rclone 程序我重定向了标准错误,以便将所有内容都捕获到一个选项上,这对于跨平台的方式来说并不是那么容易。对于linux / unix
<$ p $
对于linux / unix,请参阅重定向* .go文件p> //将unix下的恐慌记录到日志文件中
// +编译unix
包主
导入(
log
os
系统调用
)
// redirectStderr传递给在
中传递的文件func redirectStderr (f * os.File){
err:= syscall.Dup2(int(f.Fd()),int(os.Stderr.Fd()))
if err!= nil {
log.Fatalf(无法将stderr重定向到文件:%v,err)
}
}
和windows
//将窗口下的恐慌记录到日志文件
//
//来自minix的代码,通过
//
// http://play.golang.org/p/kLtct7lSUg
// + build windows
主包
导入(
log
os
系统调用
)
var(
kernel32 = syscall.MustLoadDLL(kernel32.dll)
procSetStdHandle = kernel3 2.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传递给在
中传递的文件func redirectStderr( f * os.File){
err:= setStdHandle(syscall.STD_ERROR_HANDLE,syscall.Handle(f.Fd()))
if err!= nil {
log.Fatalf(无法将stderr重定向到文件:%v,err)
}
// SetStdHandle不影响之前对stderr的引用
os.Stderr = f
}
We have a large-ish golang application that uses the logger (actually, a custom logger), to write output to a log file that is periodically rotated.
However, when an application crashes or panic()'s, those messages go to standard error.
Is there any way to override the panic functionality to use our logger?
As far as I know, you can't redirect the output from panic away from standard error, or to your logger. The best thing you can do is redirect standard error to a file which you can do externally, or inside your program.
For my rclone program I redirected standard error to capture everything to a file on an option which is unfortunately isn't particularly easy to do in a cross platform way. Here is how I did it (see the redirect*.go files)
For linux/unix
// Log the panic under unix to the log file
//+build unix
package main
import (
"log"
"os"
"syscall"
)
// 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)
}
}
and for windows
// Log the panic under windows to the log file
//
// Code from minix, via
//
// http://play.golang.org/p/kLtct7lSUg
//+build windows
package main
import (
"log"
"os"
"syscall"
)
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)
}
// SetStdHandle does not affect prior references to stderr
os.Stderr = f
}
这篇关于在golang捕捉恐慌()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!