github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/error-reporting/main.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "os" 9 "os/exec" 10 "syscall" 11 ) 12 13 type TailWriter struct { 14 Head int // writing head 15 TotalWritten int 16 Buffer []byte 17 } 18 19 func NewTail(size int) *TailWriter { 20 return &TailWriter{0, 0, make([]byte, size, size)} 21 } 22 23 func (w *TailWriter) Write(data []byte) (int, error) { 24 w.TotalWritten += len(data) 25 26 if len(data) > len(w.Buffer) { 27 copy(w.Buffer, data[len(data)-len(w.Buffer):]) 28 w.Head = 0 29 } else { 30 n := copy(w.Buffer[w.Head:], data) 31 if w.Head >= len(w.Buffer) { 32 w.Head = 0 33 } 34 35 n = copy(w.Buffer[:], data[n:]) 36 w.Head += n 37 } 38 39 return len(data), nil 40 } 41 42 func (tw *TailWriter) WriteTo(w io.Writer) { 43 if tw.TotalWritten <= len(tw.Buffer) { 44 w.Write(tw.Buffer[0:tw.TotalWritten]) 45 return 46 } 47 w.Write(tw.Buffer[tw.Head:]) 48 w.Write(tw.Buffer[:tw.Head]) 49 } 50 51 func monitor() { 52 if os.Getenv("__NOMONITOR__") != "" { 53 return 54 } 55 56 cmd := exec.Command(os.Args[0], os.Args...) 57 cmd.Env = []string{"__NOMONITOR__=true"} 58 cmd.Env = append(cmd.Env, os.Environ()...) 59 60 tailout := NewTail(2 << 10) 61 tailerr := NewTail(2 << 10) 62 63 cmd.Stdin = os.Stdin 64 cmd.Stdout = io.MultiWriter(os.Stdout, tailout) 65 cmd.Stderr = io.MultiWriter(os.Stderr, tailerr) 66 67 // TODO: also propagate signals 68 69 err := cmd.Run() 70 if err != nil { 71 // send email here 72 var data bytes.Buffer 73 data.WriteString("=== STDOUT ===\n") 74 tailout.WriteTo(&data) 75 data.WriteString("\n\n=== STDERR ===\n") 76 tailerr.WriteTo(&data) 77 data.WriteString("\n\n") 78 79 ioutil.WriteFile("error.txt", data.Bytes(), 0755) 80 } 81 82 // propagate exit-code 83 if exiterr, ok := err.(*exec.ExitError); ok { 84 if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { 85 os.Exit(status.ExitStatus()) 86 } 87 } 88 89 os.Exit(0) 90 } 91 92 func main() { 93 monitor() 94 95 fmt.Println("hello") 96 panic("we broke stuff") 97 }