I installed golang on a redhat server through epel. I'm trying to analyze the panic logs but I can't find where the logs are stored. Any hint ? There is no trace in /var/log
func main() {
http.HandleFunc("/", panicRecover(test))
log.Fatal(http.ListenAndServe(":80", nil))
}
func test(){
out, err := exec.Command("echo ", "something").Output()
if err != nil {
log.Panic(err)
}
}
func panicRecover(f func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
defer func() {
if r := recover(); r != nil {
log.Printf("PANIC RECOVERED:%s
", r)
}
}()
f(w, r)
}
To stderr
.
For example,
package main
import "log"
func main() {
log.Panic("log.Panic to stderr")
}
$ go run panic.go 2>stderr.txt
stderr.txt
File:
2014/06/09 00:30:54 log.Panic to stderr
panic: log.Panic to stderr
goroutine 16 [running]:
runtime.panic(0x497180, 0xc2080001a0)
/home/peter/go/src/pkg/runtime/panic.c:279 +0xf5
log.Panic(0x7f88770fff20, 0x1, 0x1)
/home/peter/go/src/pkg/log/log.go:307 +0xb6
main.main()
/home/peter/gopath/src/so/panic.go:6 +0xa7
goroutine 17 [runnable]:
runtime.MHeap_Scavenger()
/home/peter/go/src/pkg/runtime/mheap.c:507
runtime.goexit()
/home/peter/go/src/pkg/runtime/proc.c:1445
goroutine 18 [runnable]:
bgsweep()
/home/peter/go/src/pkg/runtime/mgc0.c:1976
runtime.goexit()
/home/peter/go/src/pkg/runtime/proc.c:1445
goroutine 19 [runnable]:
runfinq()
/home/peter/go/src/pkg/runtime/mgc0.c:2606
runtime.goexit()
/home/peter/go/src/pkg/runtime/proc.c:1445
exit status 2
By default it writes them to stderr. You can change this with log.SetOutput(os.Writer)
. If you don't want to use 2>
on the command line (say it's an application you plan on users running from the GUI filesystem instead of terminal), a good way to log to a file involves using the fact that init
is run before the main program starts.
For instance, you may do
package main
import (
"log"
"os"
)
var logFile os.File
func init() {
var err error
// Of course, this name isn't unique,
// I usually use time.Now().Unix() or something
// to get unique log names.
logFile,err = os.Create("logfile.txt")
if err != nil {
// Open a different logfile or something
}
log.SetOutput(logFile)
}
The difficulty is that if you panic you should probably always recover to make sure you Close
the file. This is especially true if you're doing buffered logging with bufio
where if your program panics, you may not see the most recent data without explicitly flushing the buffer.