// NOTE: this function does not return when you call it, instead it // re-exec()s the current process with panic monitoring. func defaultPanicHandler() { defer defaultNotifier.dontPanic() exitStatus, err := panicwrap.Wrap(&panicwrap.WrapConfig{ CookieKey: "bugsnag_wrapped", CookieValue: "bugsnag_wrapped", Handler: func(output string) { toNotify, err := errors.ParsePanic(output) if err != nil { defaultNotifier.Config.log("bugsnag.handleUncaughtPanic: %v", err) } Notify(toNotify, SeverityError, Configuration{Synchronous: true}) }, }) if err != nil { defaultNotifier.Config.log("bugsnag.handleUncaughtPanic: %v", err) return } if exitStatus >= 0 { os.Exit(exitStatus) } else { return } }
func realMain() int { var wrapConfig panicwrap.WrapConfig if !panicwrap.Wrapped(&wrapConfig) { // Determine where logs should go in general (requested by the user) logWriter, err := logOutput() if err != nil { fmt.Fprintf(os.Stderr, "Couldn't setup log output: %s", err) return 1 } if logWriter == nil { logWriter = ioutil.Discard } // We always send logs to a temporary file that we use in case // there is a panic. Otherwise, we delete it. logTempFile, err := ioutil.TempFile("", "terraform-log") if err != nil { fmt.Fprintf(os.Stderr, "Couldn't setup logging tempfile: %s", err) return 1 } defer os.Remove(logTempFile.Name()) defer logTempFile.Close() // Tell the logger to log to this file os.Setenv(EnvLog, "") os.Setenv(EnvLogFile, "") // Setup the prefixed readers that send data properly to // stdout/stderr. outR, outW := io.Pipe() go copyOutput(outR) // Create the configuration for panicwrap and wrap our executable wrapConfig.Handler = panicHandler(logTempFile) wrapConfig.Writer = io.MultiWriter(logTempFile, logWriter) wrapConfig.Stdout = outW exitStatus, err := panicwrap.Wrap(&wrapConfig) if err != nil { fmt.Fprintf(os.Stderr, "Couldn't start Terraform: %s", err) return 1 } // If >= 0, we're the parent, so just exit if exitStatus >= 0 { return exitStatus } // We're the child, so just close the tempfile we made in order to // save file handles since the tempfile is only used by the parent. logTempFile.Close() } // Call the real main return wrappedMain() }
// realMain is executed from main and returns the exit status to exit with. func realMain() int { // If there is no explicit number of Go threads to use, then set it if os.Getenv("GOMAXPROCS") == "" { runtime.GOMAXPROCS(runtime.NumCPU()) } // Determine where logs should go in general (requested by the user) logWriter, err := logOutput() if err != nil { fmt.Fprintf(os.Stderr, "Couldn't setup log output: %s", err) return 1 } // We also always send logs to a temporary file that we use in case // there is a panic. Otherwise, we delete it. logTempFile, err := ioutil.TempFile("", "packer-log") if err != nil { fmt.Fprintf(os.Stderr, "Couldn't setup logging tempfile: %s", err) return 1 } defer os.Remove(logTempFile.Name()) defer logTempFile.Close() // Reset the log variables to minimize work in the subprocess os.Setenv("PACKER_LOG", "") os.Setenv("PACKER_LOG_FILE", "") // Create the configuration for panicwrap and wrap our executable wrapConfig := &panicwrap.WrapConfig{ Handler: panicHandler(logTempFile), Writer: io.MultiWriter(logTempFile, logWriter), } exitStatus, err := panicwrap.Wrap(wrapConfig) if err != nil { fmt.Fprintf(os.Stderr, "Couldn't start Packer: %s", err) return 1 } if exitStatus >= 0 { return exitStatus } // We're the child, so just close the tempfile we made in order to // save file handles since the tempfile is only used by the parent. logTempFile.Close() return wrappedMain() }
func realMain() int { var wrapConfig panicwrap.WrapConfig // don't re-exec terraform as a child process for easier debugging if os.Getenv("TF_FORK") == "0" { return wrappedMain() } if !panicwrap.Wrapped(&wrapConfig) { // Determine where logs should go in general (requested by the user) logWriter, err := logging.LogOutput() if err != nil { fmt.Fprintf(os.Stderr, "Couldn't setup log output: %s", err) return 1 } // We always send logs to a temporary file that we use in case // there is a panic. Otherwise, we delete it. logTempFile, err := ioutil.TempFile("", "terraform-log") if err != nil { fmt.Fprintf(os.Stderr, "Couldn't setup logging tempfile: %s", err) return 1 } defer os.Remove(logTempFile.Name()) defer logTempFile.Close() // Setup the prefixed readers that send data properly to // stdout/stderr. doneCh := make(chan struct{}) outR, outW := io.Pipe() go copyOutput(outR, doneCh) // Create the configuration for panicwrap and wrap our executable wrapConfig.Handler = panicHandler(logTempFile) wrapConfig.Writer = io.MultiWriter(logTempFile, logWriter) wrapConfig.Stdout = outW exitStatus, err := panicwrap.Wrap(&wrapConfig) if err != nil { fmt.Fprintf(os.Stderr, "Couldn't start Terraform: %s", err) return 1 } // If >= 0, we're the parent, so just exit if exitStatus >= 0 { // Close the stdout writer so that our copy process can finish outW.Close() // Wait for the output copying to finish <-doneCh return exitStatus } // We're the child, so just close the tempfile we made in order to // save file handles since the tempfile is only used by the parent. logTempFile.Close() } // Call the real main return wrappedMain() }
func realMain() int { // Set a custom panicwrap cookie key and value. Since we're executing // other panicwrap executables, the default cookie key/value cause // weird errors if we don't change them. var wrapConfig panicwrap.WrapConfig wrapConfig.CookieKey = "OTTO_PANICWRAP_COOKIE" wrapConfig.CookieValue = fmt.Sprintf( "otto-%s-%s-%s", Version, VersionPrerelease, GitCommit) if !panicwrap.Wrapped(&wrapConfig) { // Determine where logs should go in general (requested by the user) logWriter, err := logOutput() if err != nil { fmt.Fprintf(os.Stderr, "Couldn't setup log output: %s", err) return 1 } if logWriter == nil { logWriter = ioutil.Discard } // We always send logs to a temporary file that we use in case // there is a panic. Otherwise, we delete it. logTempFile, err := ioutil.TempFile("", "otto-log") if err != nil { fmt.Fprintf(os.Stderr, "Couldn't setup logging tempfile: %s", err) return 1 } defer os.Remove(logTempFile.Name()) defer logTempFile.Close() // Tell the logger to log to this file os.Setenv(EnvLog, "") os.Setenv(EnvLogFile, "") // Setup the prefixed readers that send data properly to // stdout/stderr. doneCh := make(chan struct{}) outR, outW := io.Pipe() go copyOutput(outR, doneCh) // Create the configuration for panicwrap and wrap our executable wrapConfig.Handler = panicHandler(logTempFile) wrapConfig.Writer = io.MultiWriter(logTempFile, logWriter) wrapConfig.Stdout = outW exitStatus, err := panicwrap.Wrap(&wrapConfig) if err != nil { fmt.Fprintf(os.Stderr, "Couldn't start Otto: %s", err) return 1 } // If >= 0, we're the parent, so just exit if exitStatus >= 0 { // Close the stdout writer so that our copy process can finish outW.Close() // Wait for the output copying to finish <-doneCh return exitStatus } // We're the child, so just close the tempfile we made in order to // save file handles since the tempfile is only used by the parent. logTempFile.Close() } // Call the real main return wrappedMain() }
func realMain() int { //使用panicwrap封装panic var wrapConfig panicwrap.WrapConfig wrapConfig.CookieKey = "OTTO_PANICWRAP_COOKIE" wrapConfig.CookieValue = fmt.Sprintf("otto-%s-%s-%s", Version, VersionPrerelease, GitCommit) //fmt.Printf("warpConfig : %+v\n", wrapConfig) if !panicwrap.Wrapped(&wrapConfig) { fmt.Println("没有封装wrapConfig配置") logWriter, err := logOutput() if err != nil { fmt.Fprintf(os.Stderr, "不能设置Log输出到:%s", err) return 1 } if logWriter == nil { logWriter = ioutil.Discard //Discard实现了io.Writer接口 } //当发生panic时我们发送log到临时文件,否则就删除 logTempFile, err := ioutil.TempFile("", "kuuyee-otto-log") if err != nil { fmt.Fprintf(os.Stderr, "不能设置Log临时文件:%s", err) return 1 } defer os.Remove(logTempFile.Name()) defer logTempFile.Close() // 告诉logger把日志输出到这个文件 os.Setenv(Envlog, "") os.Setenv(EnvLogFile, "") // 设置发送到stdout/stderr数据的读取前缀 doneCh := make(chan struct{}) outR, outW := io.Pipe() go copyOutput(outR, doneCh) // 创建panicwrap配置 wrapConfig.Handler = panicHandler(logTempFile) wrapConfig.Writer = io.MultiWriter(logTempFile, logWriter) wrapConfig.Stdout = outW exitStatus, err := panicwrap.Wrap(&wrapConfig) if err != nil { fmt.Fprintf(os.Stderr, "不能启动Otto: %s", err) return 1 } // 如果>=0,那么我们是父进程,所以退出 if exitStatus >= 0 { outW.Close() <-doneCh return exitStatus } // 我们是子,所以关闭tempfile logTempFile.Close() } fmt.Printf("[KuuYee_DEBUG]====> %s\n", "main.go/realMain/81") //调用真正的main函数 return wrappedMain() }