Skip to content

Commit c741557

Browse files
committed
log: add *Depth function for log wrapping.
This makes it possible for other packages to wrap the log package.
1 parent b83197c commit c741557

File tree

2 files changed

+80
-6
lines changed

2 files changed

+80
-6
lines changed

glog.go

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ var timeNow = time.Now // Stubbed out for testing.
518518
/*
519519
header formats a log header as defined by the C++ implementation.
520520
It returns a buffer containing the formatted header and the user's file and line number.
521+
The depth specifies how many stack frames above lives the source line to be identified in the log message.
521522
522523
Log lines have this form:
523524
Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
@@ -531,8 +532,8 @@ where the fields are defined as follows:
531532
line The line number
532533
msg The user-supplied message
533534
*/
534-
func (l *loggingT) header(s severity) (*buffer, string, int) {
535-
_, file, line, ok := runtime.Caller(3) // It's always the same number of frames to the user's call.
535+
func (l *loggingT) header(s severity, depth int) (*buffer, string, int) {
536+
_, file, line, ok := runtime.Caller(3 + depth)
536537
if !ok {
537538
file = "???"
538539
line = 1
@@ -627,13 +628,17 @@ func (buf *buffer) someDigits(i, d int) int {
627628
}
628629

629630
func (l *loggingT) println(s severity, args ...interface{}) {
630-
buf, file, line := l.header(s)
631+
buf, file, line := l.header(s, 0)
631632
fmt.Fprintln(buf, args...)
632633
l.output(s, buf, file, line, false)
633634
}
634635

635636
func (l *loggingT) print(s severity, args ...interface{}) {
636-
buf, file, line := l.header(s)
637+
l.printDepth(s, 1, args...)
638+
}
639+
640+
func (l *loggingT) printDepth(s severity, depth int, args ...interface{}) {
641+
buf, file, line := l.header(s, depth)
637642
fmt.Fprint(buf, args...)
638643
if buf.Bytes()[buf.Len()-1] != '\n' {
639644
buf.WriteByte('\n')
@@ -642,7 +647,7 @@ func (l *loggingT) print(s severity, args ...interface{}) {
642647
}
643648

644649
func (l *loggingT) printf(s severity, format string, args ...interface{}) {
645-
buf, file, line := l.header(s)
650+
buf, file, line := l.header(s, 0)
646651
fmt.Fprintf(buf, format, args...)
647652
if buf.Bytes()[buf.Len()-1] != '\n' {
648653
buf.WriteByte('\n')
@@ -1038,6 +1043,12 @@ func Info(args ...interface{}) {
10381043
logging.print(infoLog, args...)
10391044
}
10401045

1046+
// InfoDepth acts as Info but uses depth to determine which call frame to log.
1047+
// InfoDepth(0, "msg") is the same as Info("msg").
1048+
func InfoDepth(depth int, args ...interface{}) {
1049+
logging.printDepth(infoLog, depth, args...)
1050+
}
1051+
10411052
// Infoln logs to the INFO log.
10421053
// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
10431054
func Infoln(args ...interface{}) {
@@ -1056,6 +1067,12 @@ func Warning(args ...interface{}) {
10561067
logging.print(warningLog, args...)
10571068
}
10581069

1070+
// WarningDepth acts as Warning but uses depth to determine which call frame to log.
1071+
// WarningDepth(0, "msg") is the same as Warning("msg").
1072+
func WarningDepth(depth int, args ...interface{}) {
1073+
logging.printDepth(warningLog, depth, args...)
1074+
}
1075+
10591076
// Warningln logs to the WARNING and INFO logs.
10601077
// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
10611078
func Warningln(args ...interface{}) {
@@ -1074,6 +1091,12 @@ func Error(args ...interface{}) {
10741091
logging.print(errorLog, args...)
10751092
}
10761093

1094+
// ErrorDepth acts as Error but uses depth to determine which call frame to log.
1095+
// ErrorDepth(0, "msg") is the same as Error("msg").
1096+
func ErrorDepth(depth int, args ...interface{}) {
1097+
logging.printDepth(errorLog, depth, args...)
1098+
}
1099+
10771100
// Errorln logs to the ERROR, WARNING, and INFO logs.
10781101
// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
10791102
func Errorln(args ...interface{}) {
@@ -1093,6 +1116,12 @@ func Fatal(args ...interface{}) {
10931116
logging.print(fatalLog, args...)
10941117
}
10951118

1119+
// FatalDepth acts as Fatal but uses depth to determine which call frame to log.
1120+
// FatalDepth(0, "msg") is the same as Fatal("msg").
1121+
func FatalDepth(depth int, args ...interface{}) {
1122+
logging.printDepth(fatalLog, depth, args...)
1123+
}
1124+
10961125
// Fatalln logs to the FATAL, ERROR, WARNING, and INFO logs,
10971126
// including a stack trace of all running goroutines, then calls os.Exit(255).
10981127
// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.

glog_test.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
stdLog "log"
2323
"path/filepath"
2424
"runtime"
25+
"strconv"
2526
"strings"
2627
"testing"
2728
"time"
@@ -97,6 +98,50 @@ func TestInfo(t *testing.T) {
9798
}
9899
}
99100

101+
func TestInfoDepth(t *testing.T) {
102+
setFlags()
103+
defer logging.swap(logging.newBuffers())
104+
105+
f := func() { InfoDepth(1, "depth-test1") }
106+
107+
// The next three lines must stay together
108+
_, _, wantLine, _ := runtime.Caller(0)
109+
InfoDepth(0, "depth-test0")
110+
f()
111+
112+
msgs := strings.Split(strings.TrimSuffix(contents(infoLog), "\n"), "\n")
113+
if len(msgs) != 2 {
114+
t.Fatalf("Got %d lines, expected 2", len(msgs))
115+
}
116+
117+
for i, m := range msgs {
118+
if !strings.HasPrefix(m, "I") {
119+
t.Errorf("InfoDepth[%d] has wrong character: %q", i, m)
120+
}
121+
w := fmt.Sprintf("depth-test%d", i)
122+
if !strings.Contains(m, w) {
123+
t.Errorf("InfoDepth[%d] missing %q: %q", i, w, m)
124+
}
125+
126+
// pull out the line number (between : and ])
127+
msg := m[strings.LastIndex(m, ":")+1:]
128+
x := strings.Index(msg, "]")
129+
if x < 0 {
130+
t.Errorf("InfoDepth[%d]: missing ']': %q", i, m)
131+
continue
132+
}
133+
line, err := strconv.Atoi(msg[:x])
134+
if err != nil {
135+
t.Errorf("InfoDepth[%d]: bad line number: %q", i, m)
136+
continue
137+
}
138+
wantLine++
139+
if wantLine != line {
140+
t.Errorf("InfoDepth[%d]: got line %d, want %d", i, line, wantLine)
141+
}
142+
}
143+
}
144+
100145
func init() {
101146
CopyStandardLogTo("INFO")
102147
}
@@ -357,7 +402,7 @@ func TestLogBacktraceAt(t *testing.T) {
357402

358403
func BenchmarkHeader(b *testing.B) {
359404
for i := 0; i < b.N; i++ {
360-
buf, _, _ := logging.header(infoLog)
405+
buf, _, _ := logging.header(infoLog, 0)
361406
logging.putBuffer(buf)
362407
}
363408
}

0 commit comments

Comments
 (0)