I'm deploying apps to a cloud service provider and logs can only be picked up line by line. I want to be able to replace the new-line characters from stack dumps with other characters so I can keep my stack trace together.
Is it possible to do anything to manipulate the stack trace that gets dumped when the program fails?
You can run everything in a function that recovers panics, then do what you want with any panics recovered:
func main() {
defer func() {
if r := recover(); r != nil {
// Log whatever/however you want
os.Exit(1) // to terminate the program
}
}()
// the rest of your code here
}
Note that this has limitations. It won't catch any panics that happen outside of main()
which, in some programs, will be almost everything. In particular, it won't catch panics in:
init()
functionsFor these cases, a more general panic-handler may be used (and called) at every juncture. i.e.
func handlePanic() {
if r := recover(); r != nil {
// Do your logging
os.Exit(1)
}
}
// then later ...
func init() {
defer handlePanic()
// do stuff
}
// or ...
go func() {
defer handlePanic()
// do things that may panic
}()
In any of these cases, you'll be forced to do your own stack-trace handling. Use runtime.Caller
or similar, to build a stack trace, then create the desired output. Note that the stack trace won't be identical to what you've seen before, since it's now being created at a different part of the code. Getting the ideal stack trace for your one's case, by skipping frames, or recording the stack trace elsewhere, etc, is left as an exercise for the reader.