第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

在 golang 中捕獲 panic()

在 golang 中捕獲 panic()

Go
尚方寶劍之說 2021-12-07 10:20:28
我們有一個(gè)大型 golang 應(yīng)用程序,它使用記錄器(實(shí)際上是一個(gè)自定義記錄器)將輸出寫入定期輪換的日志文件。但是,當(dāng)應(yīng)用程序崩潰或 panic() 時(shí),這些消息會(huì)轉(zhuǎn)為標(biāo)準(zhǔn)錯(cuò)誤。有沒有辦法覆蓋恐慌功能以使用我們的記錄器?
查看完整描述

3 回答

?
冉冉說

TA貢獻(xiàn)1877條經(jīng)驗(yàn) 獲得超1個(gè)贊

據(jù)我所知,您無法將 panic 的輸出重定向到遠(yuǎn)離標(biāo)準(zhǔn)錯(cuò)誤或您的記錄器。您能做的最好的事情是將標(biāo)準(zhǔn)錯(cuò)誤重定向到您可以在外部或程序內(nèi)部執(zhí)行的文件。


對(duì)于我的rclone程序,我重定向了標(biāo)準(zhǔn)錯(cuò)誤以將所有內(nèi)容捕獲到一個(gè)選項(xiàng)的文件中,不幸的是,這在跨平臺(tái)方式中并不是特別容易做到。這是我是如何做到的(請(qǐng)參閱 redirect*.go 文件)


對(duì)于 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

}


查看完整回答
反對(duì) 回復(fù) 2021-12-07
?
慕碼人2483693

TA貢獻(xiàn)1860條經(jīng)驗(yàn) 獲得超9個(gè)贊

您可以使用recover()從同一個(gè) goroutine 中恢復(fù)恐慌。當(dāng)調(diào)用recover()延遲方法時(shí)(請(qǐng)記住,延遲方法仍然會(huì)被調(diào)用,即使在panic()ing 時(shí)),它將返回panic()作為參數(shù)傳遞給最后一次調(diào)用的任何內(nèi)容(或者nil當(dāng)程序沒有發(fā)生恐慌時(shí))。


defer func() {

    if x := recover(); x != nil {

        // recovering from a panic; x contains whatever was passed to panic()

        log.Printf("run time panic: %v", x)


        // if you just want to log the panic, panic again

        panic(x)

    }

}()


panic("foo");

但是請(qǐng)注意,您無法從不同 goroutine 中觸發(fā)的恐慌中恢復(fù)(感謝 JimB 的提示)。使用單個(gè)recover()從任何 goroutine 的恐慌中恢復(fù)是不可能的。


查看完整回答
反對(duì) 回復(fù) 2021-12-07
?
慕森卡

TA貢獻(xiàn)1806條經(jīng)驗(yàn) 獲得超8個(gè)贊

擴(kuò)展@nick-craig-wood 的回答:如果您使用的是 Linux,您可以生成一個(gè) logger(1) 實(shí)例并將 stderr 重定向到它。這樣你就可以在系統(tǒng)日志中獲得完整的回溯。這就是gocryptfs所做的:


// redirectStdFds redirects stderr and stdout to syslog; stdin to /dev/null

func redirectStdFds() {

    // stderr and stdout

    pr, pw, err := os.Pipe()

    if err != nil {

        tlog.Warn.Printf("redirectStdFds: could not create pipe: %v\n", err)

        return

    }

    tag := fmt.Sprintf("gocryptfs-%d-logger", os.Getpid())

    cmd := exec.Command("logger", "-t", tag)

    cmd.Stdout = os.Stdout

    cmd.Stderr = os.Stderr

    cmd.Stdin = pr

    err = cmd.Start()

    if err != nil {

        tlog.Warn.Printf("redirectStdFds: could not start logger: %v\n", err)

    }

    pr.Close()

    err = syscall.Dup2(int(pw.Fd()), 1)

    if err != nil {

        tlog.Warn.Printf("redirectStdFds: stdout dup error: %v\n", err)

    }

    syscall.Dup2(int(pw.Fd()), 2)

    if err != nil {

        tlog.Warn.Printf("redirectStdFds: stderr dup error: %v\n", err)

    }

    pw.Close()


    // stdin

    nullFd, err := os.Open("/dev/null")

    if err != nil {

        tlog.Warn.Printf("redirectStdFds: could not open /dev/null: %v\n", err)

        return

    }

    err = syscall.Dup2(int(nullFd.Fd()), 0)

    if err != nil {

        tlog.Warn.Printf("redirectStdFds: stdin dup error: %v\n", err)

    }

    nullFd.Close()

}


查看完整回答
反對(duì) 回復(fù) 2021-12-07
  • 3 回答
  • 0 關(guān)注
  • 314 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)