diff --git a/funcr/funcr.go b/funcr/funcr.go index d2913ec..e162226 100644 --- a/funcr/funcr.go +++ b/funcr/funcr.go @@ -46,7 +46,7 @@ type Underlier interface { } func newSink(fn func(prefix, args string), opts Options) logr.LogSink { - return &fnlogger{ + l := &fnlogger{ prefix: "", values: nil, depth: 0, @@ -54,7 +54,14 @@ func newSink(fn func(prefix, args string), opts Options) logr.LogSink { logCaller: opts.LogCaller, logTimestamp: opts.LogTimestamp, verbosity: opts.Verbosity, + helper: opts.Helper, } + if l.helper == nil { + // We have to have a valid function for GetHelper, so + // we might as well just cover the nil case once here. + l.helper = func() {} + } + return l } // Options carries parameters which influence the way logs are generated. @@ -70,6 +77,10 @@ type Options struct { // Verbosity tells funcr which V logs to be write. Higher values enable // more logs. Verbosity int + + // Helper is an optional function that funcr will call to mark its own + // stack frames as helper functions. + Helper func() } // MessageClass indicates which category or categories of messages to consider. @@ -89,6 +100,7 @@ type fnlogger struct { values []interface{} depth int write func(prefix, args string) + helper func() logCaller MessageClass logTimestamp bool verbosity int @@ -98,6 +110,7 @@ type fnlogger struct { var _ logr.LogSink = &fnlogger{} var _ logr.CallDepthLogSink = &fnlogger{} var _ Underlier = &fnlogger{} +var _ logr.CallStackHelperLogSink = &fnlogger{} func flatten(kvList ...interface{}) string { if len(kvList)%2 != 0 { @@ -293,6 +306,7 @@ func (l fnlogger) Info(level int, msg string, kvList ...interface{}) { args = append(args, l.values...) args = append(args, kvList...) argsStr := flatten(args...) + l.helper() l.write(l.prefix, argsStr) } @@ -313,6 +327,7 @@ func (l fnlogger) Error(err error, msg string, kvList ...interface{}) { args = append(args, l.values...) args = append(args, kvList...) argsStr := flatten(args...) + l.helper() l.write(l.prefix, argsStr) } @@ -342,3 +357,7 @@ func (l fnlogger) WithCallDepth(depth int) logr.LogSink { func (l fnlogger) GetUnderlying() func(prefix, args string) { return l.write } + +func (l fnlogger) GetHelper() func() { + return l.helper +} diff --git a/testing/test.go b/testing/test.go index 98f7f78..861357f 100644 --- a/testing/test.go +++ b/testing/test.go @@ -27,7 +27,8 @@ import ( // Info logs are only enabled at V(0). func NewTestLogger(t *testing.T) logr.Logger { fn := func(prefix, args string) { + t.Helper() t.Logf("%s: %s", prefix, args) } - return funcr.New(fn, funcr.Options{}) + return funcr.New(fn, funcr.Options{Helper: t.Helper}) } diff --git a/testing/test_test.go b/testing/test_test.go index 467518d..e4678c3 100644 --- a/testing/test_test.go +++ b/testing/test_test.go @@ -19,12 +19,27 @@ package testing import ( "fmt" "testing" + + "github.com/go-logr/logr" ) func TestTestLogger(t *testing.T) { - logger := NewTestLogger(t) - logger.Info("info") - logger.V(0).Info("V(0).info") - logger.V(1).Info("v(1).info") - logger.Error(fmt.Errorf("error"), "error") + log := NewTestLogger(t) + log.Info("info") + log.V(0).Info("V(0).info") + log.V(1).Info("v(1).info") + log.Error(fmt.Errorf("error"), "error") + Helper(log, "hello world") +} + +func Helper(log logr.Logger, msg string) { + helper, log := log.Helper() + helper() + helper2(log, msg) +} + +func helper2(log logr.Logger, msg string) { + helper, log := log.Helper() + helper() + log.Info(msg) }