terraform/internal/logging/panic.go

72 lines
2.1 KiB
Go
Raw Normal View History

package logging
2014-05-31 01:07:26 +02:00
import (
"fmt"
"io"
"io/ioutil"
2014-05-31 01:07:26 +02:00
"os"
"github.com/mitchellh/panicwrap"
)
// This output is shown if a panic happens.
const panicOutput = `
!!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!!
Terraform crashed! This is always indicative of a bug within Terraform.
A crash log has been placed at %[1]q relative to your current
2014-05-31 01:07:26 +02:00
working directory. It would be immensely helpful if you could please
report the crash with Terraform[1] so that we can fix this.
When reporting bugs, please include your terraform version. That
information is available on the first line of crash.log. You can also
get it by running 'terraform --version' on the command line.
SECURITY WARNING: the %[1]q file that was created may contain
sensitive information that must be redacted before it is safe to share
on the issue tracker.
2014-05-31 01:07:26 +02:00
[1]: https://github.com/hashicorp/terraform/issues
!!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!!
`
// panicHandler is what is called by panicwrap when a panic is encountered
// within Terraform. It is guaranteed to run after the resulting process has
// exited so we can take the log file, add in the panic, and store it
// somewhere locally.
func PanicHandler(tmpLogPath string) panicwrap.HandlerFunc {
2014-05-31 01:07:26 +02:00
return func(m string) {
// Create the crash log file where we'll write the logs
f, err := ioutil.TempFile(".", "crash.*.log")
2014-05-31 01:07:26 +02:00
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create crash log file: %s", err)
return
}
defer f.Close()
tmpLog, err := os.Open(tmpLogPath)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to open log file %q: %v\n", tmpLogPath, err)
2014-05-31 01:07:26 +02:00
return
}
defer tmpLog.Close()
2014-05-31 01:07:26 +02:00
// Copy the contents to the crash file. This will include
// the panic that just happened.
if _, err = io.Copy(f, tmpLog); err != nil {
2014-05-31 01:07:26 +02:00
fmt.Fprintf(os.Stderr, "Failed to write crash log: %s", err)
return
}
2020-10-21 20:57:25 +02:00
// add the trace back to the log
f.WriteString("\n" + m)
2014-05-31 01:07:26 +02:00
// Tell the user a crash occurred in some helpful way that
// they'll hopefully notice.
fmt.Printf("\n\n")
fmt.Printf(panicOutput, f.Name())
2014-05-31 01:07:26 +02:00
}
}