Skip to content

Commit a442ac2

Browse files
committed
golog to print stack when PRINT_STACK=true
1 parent b1d6ba6 commit a442ac2

File tree

1 file changed

+39
-9
lines changed

1 file changed

+39
-9
lines changed

src/github.com/getlantern/golog/golog.go

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
// package golog implements logging functions that log errors to stderr and
2-
// debug messages to stdout. Trace logging is also supported. Trace logs go to
3-
// stdout as well, but they are only written if the program is run with
4-
// environment variable "TRACE=true"
2+
// debug messages to stdout. Trace logging is also supported.
3+
// Trace logs go to stdout as well, but they are only written if the program
4+
// is run with environment variable "TRACE=true".
5+
// A stack dump will be printed after the message if "PRINT_STACK=true".
56
package golog
67

78
import (
89
"bufio"
10+
"bytes"
911
"fmt"
1012
"io"
1113
"io/ioutil"
@@ -106,16 +108,20 @@ func LoggerFor(prefix string) Logger {
106108
l.traceOut = ioutil.Discard
107109
}
108110

111+
printStack := os.Getenv("PRINT_STACK")
112+
l.printStack, _ = strconv.ParseBool(printStack)
113+
109114
return l
110115
}
111116

112117
type logger struct {
113-
prefix string
114-
traceOn bool
115-
traceOut io.Writer
116-
outs atomic.Value
117-
pc []uintptr
118-
funcForPc *runtime.Func
118+
prefix string
119+
traceOn bool
120+
traceOut io.Writer
121+
printStack bool
122+
outs atomic.Value
123+
pc []uintptr
124+
funcForPc *runtime.Func
119125
}
120126

121127
// attaches the file and line number corresponding to
@@ -132,13 +138,19 @@ func (l *logger) print(out io.Writer, skipFrames int, severity string, arg inter
132138
if err != nil {
133139
errorOnLogging(err)
134140
}
141+
if l.printStack {
142+
l.doPrintStack()
143+
}
135144
}
136145

137146
func (l *logger) printf(out io.Writer, skipFrames int, severity string, message string, args ...interface{}) {
138147
_, err := fmt.Fprintf(out, severity+" "+l.linePrefix(skipFrames)+message+"\n", args...)
139148
if err != nil {
140149
errorOnLogging(err)
141150
}
151+
if l.printStack {
152+
l.doPrintStack()
153+
}
142154
}
143155

144156
func (l *logger) Debug(arg interface{}) {
@@ -232,6 +244,24 @@ func (l *logger) AsStdLogger() *log.Logger {
232244
return log.New(&errorWriter{l}, "", 0)
233245
}
234246

247+
func (l *logger) doPrintStack() {
248+
var b []byte
249+
buf := bytes.NewBuffer(b)
250+
for _, pc := range l.pc {
251+
funcForPc := runtime.FuncForPC(pc)
252+
if funcForPc == nil {
253+
break
254+
}
255+
file, line := funcForPc.FileLine(pc)
256+
name := funcForPc.Name()
257+
if strings.HasPrefix(name, "runtime.") {
258+
break
259+
}
260+
fmt.Fprintf(buf, "\t%s\t%s: %d\n", name, file, line)
261+
}
262+
buf.WriteTo(os.Stderr)
263+
}
264+
235265
func errorOnLogging(err error) {
236266
fmt.Fprintf(os.Stderr, "Unable to log: %v\n", err)
237267
}

0 commit comments

Comments
 (0)