Skip to content

Commit 33b6352

Browse files
authored
Merge pull request #8 from thockin/log-caller
Add an option to log the file and line
2 parents 2e39664 + 921cfc1 commit 33b6352

File tree

2 files changed

+61
-20
lines changed

2 files changed

+61
-20
lines changed

example/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ func (e E) Error() string {
3333

3434
func main() {
3535
stdr.SetVerbosity(1)
36-
log := stdr.New(stdlog.New(os.Stderr, "", stdlog.LstdFlags|stdlog.Lshortfile))
36+
log := stdr.NewWithOptions(stdlog.New(os.Stderr, "", stdlog.LstdFlags), stdr.Options{LogCaller: stdr.All})
3737
log = log.WithName("MyName").WithValues("user", "you")
3838
log.Info("hello", "val1", 1, "val2", map[string]int{"k": 1})
3939
log.V(1).Info("you should see this")

stdr.go

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"encoding/json"
2424
"fmt"
2525
"log"
26+
"path/filepath"
2627
"runtime"
2728
"sort"
2829

@@ -60,22 +61,39 @@ func NewWithOptions(std StdLogger, opts Options) logr.Logger {
6061
}
6162

6263
return logger{
63-
std: std,
64-
level: 0,
65-
prefix: "",
66-
values: nil,
67-
depth: opts.Depth,
64+
std: std,
65+
level: 0,
66+
prefix: "",
67+
values: nil,
68+
depth: opts.Depth,
69+
logCaller: opts.LogCaller,
6870
}
6971
}
7072

7173
type Options struct {
72-
// DepthOffset biases the assumed number of call frames to the "true"
73-
// caller. This is useful when the calling code calls a function which then
74-
// calls glogr (e.g. a logging shim to another API). Values less than zero
75-
// will be treated as zero.
74+
// Depth biases the assumed number of call frames to the "true" caller.
75+
// This is useful when the calling code calls a function which then calls
76+
// stdr (e.g. a logging shim to another API). Values less than zero will
77+
// be treated as zero.
7678
Depth int
79+
80+
// LogCaller tells glogr to add a "caller" key to some or all log lines.
81+
// The glog implementation always logs this information in its per-line
82+
// header, whether this option is set or not.
83+
LogCaller MessageClass
84+
85+
// TODO: add an option to log the date/time
7786
}
7887

88+
type MessageClass int
89+
90+
const (
91+
None MessageClass = iota
92+
All
93+
Info
94+
Error
95+
)
96+
7997
// StdLogger is the subset of the Go stdlib log.Logger API that is needed for
8098
// this adapter.
8199
type StdLogger interface {
@@ -84,11 +102,12 @@ type StdLogger interface {
84102
}
85103

86104
type logger struct {
87-
std StdLogger
88-
level int
89-
prefix string
90-
values []interface{}
91-
depth int
105+
std StdLogger
106+
level int
107+
prefix string
108+
values []interface{}
109+
depth int
110+
logCaller MessageClass
92111
}
93112

94113
func (l logger) clone() logger {
@@ -159,13 +178,30 @@ func pretty(value interface{}) string {
159178
return string(jb)
160179
}
161180

181+
type callerID struct {
182+
File string `json:"file"`
183+
Line int `json:"line"`
184+
}
185+
186+
func (l logger) caller() callerID {
187+
_, file, line, ok := runtime.Caller(framesToCaller() + l.depth + 1) // +1 for this frame
188+
if !ok {
189+
return callerID{"<unknown>", 0}
190+
}
191+
return callerID{filepath.Base(file), line}
192+
}
193+
162194
func (l logger) Info(msg string, kvList ...interface{}) {
163195
if l.Enabled() {
164-
lvlStr := flatten("level", l.level)
165-
msgStr := flatten("msg", msg)
196+
builtin := make([]interface{}, 0, 4)
197+
if l.logCaller == All || l.logCaller == Info {
198+
builtin = append(builtin, "caller", l.caller())
199+
}
200+
builtin = append(builtin, "level", l.level, "msg", msg)
201+
builtinStr := flatten(builtin...)
166202
fixedStr := flatten(l.values...)
167203
userStr := flatten(kvList...)
168-
l.output(framesToCaller()+l.depth, fmt.Sprintln(l.prefix, lvlStr, msgStr, fixedStr, userStr))
204+
l.output(framesToCaller()+l.depth, fmt.Sprintln(l.prefix, builtinStr, fixedStr, userStr))
169205
}
170206
}
171207

@@ -174,15 +210,20 @@ func (l logger) Enabled() bool {
174210
}
175211

176212
func (l logger) Error(err error, msg string, kvList ...interface{}) {
177-
msgStr := flatten("msg", msg)
213+
builtin := make([]interface{}, 0, 4)
214+
if l.logCaller == All || l.logCaller == Info {
215+
builtin = append(builtin, "caller", l.caller())
216+
}
217+
builtin = append(builtin, "msg", msg)
218+
builtinStr := flatten(builtin...)
178219
var loggableErr interface{}
179220
if err != nil {
180221
loggableErr = err.Error()
181222
}
182223
errStr := flatten("error", loggableErr)
183224
fixedStr := flatten(l.values...)
184225
userStr := flatten(kvList...)
185-
l.output(framesToCaller()+l.depth, fmt.Sprintln(l.prefix, errStr, msgStr, fixedStr, userStr))
226+
l.output(framesToCaller()+l.depth, fmt.Sprintln(l.prefix, builtinStr, errStr, fixedStr, userStr))
186227
}
187228

188229
func (l logger) output(calldepth int, s string) {

0 commit comments

Comments
 (0)