在 golang 中捕获 panic() [英] Capturing panic() in golang

查看:50
本文介绍了在 golang 中捕获 panic()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个大型 golang 应用程序,它使用记录器(实际上是一个自定义记录器)将输出写入定期轮换的日志文件.

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.

但是,当应用程序崩溃或发生 panic() 时,这些消息会转为标准错误.

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?

推荐答案

据我所知,您无法将 panic 的输出重定向到标准错误或您的记录器.您能做的最好的事情是将标准错误重定向到您可以在外部或程序内部执行的文件.

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.

对于我的 rclone 程序,我重定向了标准错误以将所有内容捕获到一个选项的文件中,这很不幸以跨平台方式进行并不是特别容易.这是我是如何做到的(请参阅重定向 *.go 文件)

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)

对于 linux/unix

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)
    }
}

对于窗户

// 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 中捕获 panic()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆