From 53d005ac22f594e4b223529a90cd9a268f170e89 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Wed, 1 Mar 2023 11:47:51 -0500 Subject: [PATCH] feat(log): add callerFormat to set short/long file location Fixes: https://github.com/charmbracelet/log/issues/22 --- log.go | 13 ++++++++++++- logger.go | 16 ++++++++++++++++ options.go | 8 ++++++++ pkg.go | 5 +++++ pkg_test.go | 16 ++++++++++++++++ 5 files changed, 57 insertions(+), 1 deletion(-) diff --git a/log.go b/log.go index c28f359..19971d9 100644 --- a/log.go +++ b/log.go @@ -36,6 +36,7 @@ type logger struct { timeFunc TimeFunction timeFormat string callerOffset int + callerFormat CallerFormat formatter Formatter caller bool @@ -103,7 +104,10 @@ func (l *logger) log(level Level, msg interface{}, keyvals ...interface{}) { if l.caller { // Call stack is log.Error -> log.log (2) file, line, _ := l.fillLoc(l.callerOffset + 2) - caller := fmt.Sprintf("%s:%d", trimCallerPath(file), line) + if l.callerFormat == CallerShort { + file = trimCallerPath(file) + } + caller := fmt.Sprintf("%s:%d", file, line) kvs = append(kvs, CallerKey, caller) } @@ -220,6 +224,13 @@ func (l *logger) SetReportCaller(report bool) { l.caller = report } +// SetCallerFormat sets the caller format. +func (l *logger) SetCallerFormat(format CallerFormat) { + l.mu.Lock() + defer l.mu.Unlock() + l.callerFormat = format +} + // GetLevel returns the current level. func (l *logger) GetLevel() Level { l.mu.RLock() diff --git a/logger.go b/logger.go index 7878c31..20f6771 100644 --- a/logger.go +++ b/logger.go @@ -23,6 +23,19 @@ func NowUTC() time.Time { return time.Now().UTC() } +// CallerFormat is the format of the caller location. +type CallerFormat uint8 + +const ( + // CallerShort is the short format of the caller location. + // The short format is the file name and one level of directory, and the + // line number. + CallerShort CallerFormat = iota + // CallerLong is the long format of the caller location. + // The long format is the full path of the file and the line number. + CallerLong +) + // Logger is an interface for logging. type Logger interface { // SetLevel sets the allowed level. @@ -39,6 +52,9 @@ type Logger interface { SetReportTimestamp(bool) // SetReportCaller sets whether the logger should report the caller location. SetReportCaller(bool) + // SetCallerFormat sets the caller format. The default is CallerShort. + // This is only used when SetReportCaller is true. + SetCallerFormat(format CallerFormat) // SetTimeFunction sets the time function used to get the time. // The default is time.Now. // diff --git a/options.go b/options.go index a1581df..f2d4406 100644 --- a/options.go +++ b/options.go @@ -55,6 +55,14 @@ func WithCaller() LoggerOption { } } +// WithCallerFormat returns a LoggerOption that sets the caller format for the +// logger. +func WithCallerFormat(format CallerFormat) LoggerOption { + return func(l *logger) { + l.callerFormat = format + } +} + // WithFields returns a LoggerOption that sets the fields for the logger. func WithFields(keyvals ...interface{}) LoggerOption { return func(l *logger) { diff --git a/pkg.go b/pkg.go index 3edd771..82628db 100644 --- a/pkg.go +++ b/pkg.go @@ -23,6 +23,11 @@ func SetReportCaller(report bool) { defaultLogger.SetReportCaller(report) } +// SetCallerFormat sets the caller format. The default is CallerShort. +func SetCallerFormat(format CallerFormat) { + defaultLogger.SetCallerFormat(format) +} + // SetLevel sets the level for the default logger. func SetLevel(level Level) { defaultLogger.SetLevel(level) diff --git a/pkg_test.go b/pkg_test.go index 238afef..f3adc33 100644 --- a/pkg_test.go +++ b/pkg_test.go @@ -2,8 +2,10 @@ package log import ( "bytes" + "fmt" "os" "os/exec" + "runtime" "testing" "github.com/stretchr/testify/assert" @@ -51,6 +53,20 @@ func TestGlobal(t *testing.T) { } } +func TestFullCallerSource(t *testing.T) { + var buf bytes.Buffer + SetOutput(&buf) + SetCallerFormat(CallerLong) + SetReportCaller(true) + SetReportTimestamp(false) + _, file, line, _ := runtime.Caller(0) + Error("error") + assert.Equal(t, fmt.Sprintf("ERROR <%s:%d> error\n", file, line+1), buf.String()) + SetReportTimestamp(true) + SetReportCaller(false) + SetCallerFormat(CallerShort) +} + func TestPrint(t *testing.T) { var buf bytes.Buffer SetOutput(&buf)