记录到stdout并获取堆栈跟踪的字符串值

时间:2018-02-25 15:05:02

标签: go

我有一个记录器,将堆栈跟踪记录到stdout。我想获取记录到字符串值中的堆栈跟踪,以便将其作为调试电子邮件发送。

这是我目前的代码:

func (l *Logger) withStack(writer io.Writer, err error) error {
    err = errors.WithStack(err)
    fmt.Fprintf(writer, "%+v\n", err)
    return err
}

func (l *Logger) Error(err error) error {
    // Logs stack trace to `stdout`...
    l.withStack(os.Stdout, err)

    // Here I want to get the string value of what was logged to `stdout`.
}

但如果stdout堆栈跟踪如下所示:

foo
infrastructure/logger.(*Logger).withStack
    /Users/lansana/Projects/Go/src/app/src/infrastructure/logger/logger.go:40
infrastructure/logger.(*Logger).Error
    /Users/lansana/Projects/Go/src/app/src/infrastructure/logger/logger.go:50
main.main
    /Users/lansana/Projects/Go/src/app/src/microservices/api/main.go:44
runtime.main
    /usr/local/Cellar/go/1.9/libexec/src/runtime/proc.go:185
runtime.goexit
    /usr/local/Cellar/go/1.9/libexec/src/runtime/asm_amd64.s:2337

...然后电子邮件中err.Error()的结果只是foo

我想这是有道理的,因为错误本身只包含foo而不是堆栈跟踪本身,但是如何才能将精确的堆栈跟踪作为字符串值?

1 个答案:

答案 0 :(得分:1)

withStack没有登录到stdout:它会记录到您提供的io.Writer的任何实现。要轻松获取字符串,请考虑将其传递给bytes.Buffer

您的Error功能可能如下所示:

func sendErrorMail(s string) error {
    // Send the stack trace `s` by email
}

func (l *Logger) Error(err error) {
    // Get the stack trace as a string
    buf := new(bytes.Buffer)
    l.withStack(buf, err)

    sendErrorMail(buf.String())
}

Simple demonstration of this idea as a playground