diff --git a/pkg/infrastructure/logs/formatter.go b/pkg/infrastructure/logs/formatter.go index b2599f2d..981ecdbf 100644 --- a/pkg/infrastructure/logs/formatter.go +++ b/pkg/infrastructure/logs/formatter.go @@ -14,12 +14,39 @@ package logs +import ( + "path" + "strconv" +) + var formatterMap = make(map[string]LogFormatter, 4) type LogFormatter interface { Format(lm *LogMsg) string } +// PatternLogFormatter provides a quick format method +// for example: +// tes := PatternLogFormatter{Pattern: "%F:%n|%w %t>> %m", WhenFormat: "2006-01-02"} +// RegisterFormatter("tes", tes) +// SetGlobalFormatter("tes") +type PatternLogFormatter struct { + Pattern string + WhenFormat string +} + +func (p PatternLogFormatter) getWhenFormatter() string { + s := p.WhenFormat + if s == "" { + s = "2006/01/02 15:04:05.123" // default style + } + return s +} + +func (p PatternLogFormatter) Format(lm *LogMsg) string { + return p.ToString(lm) +} + // RegisterFormatter register an formatter. Usually you should use this to extend your custom formatter // for example: // RegisterFormatter("my-fmt", &MyFormatter{}) @@ -32,3 +59,31 @@ func GetFormatter(name string) (LogFormatter, bool) { res, ok := formatterMap[name] return res, ok } + +// 'w' when, 'm' msg,'f' filename,'F' full path,'n' line number +// 'l' level number, 't' prefix of level type, 'T' full name of level type +func (p PatternLogFormatter) ToString(lm *LogMsg) string { + s := []rune(p.Pattern) + m := map[rune]string{ + 'w': lm.When.Format(p.getWhenFormatter()), + 'm': lm.Msg, + 'n': strconv.Itoa(lm.LineNumber), + 'l': strconv.Itoa(lm.Level), + 't': levelPrefix[lm.Level-1], + 'T': levelNames[lm.Level-1], + 'F': lm.FilePath, + } + _, m['f'] = path.Split(lm.FilePath) + res := "" + for i := 0; i < len(s)-1; i++ { + if s[i] == '%' { + if k, ok := m[s[i+1]]; ok { + res += k + i++ + continue + } + } + res += string(s[i]) + } + return res +} diff --git a/pkg/infrastructure/logs/formatter_test.go b/pkg/infrastructure/logs/formatter_test.go new file mode 100644 index 00000000..6ae94a6a --- /dev/null +++ b/pkg/infrastructure/logs/formatter_test.go @@ -0,0 +1,28 @@ +package logs + +import ( + "strconv" + "testing" + "time" +) + +func TestPatternLogFormatter(t *testing.T) { + tes := PatternLogFormatter{ + Pattern: "%F:%n|%w%t>> %m", + WhenFormat: "2006-01-02", + } + when := time.Now() + lm := &LogMsg{ + Msg: "message", + FilePath: "/User/go/beego/main.go", + Level: LevelWarn, + LineNumber: 10, + When: when, + } + got := tes.ToString(lm) + want := lm.FilePath + ":" + strconv.Itoa(lm.LineNumber) + "|" + + when.Format(tes.WhenFormat) + levelPrefix[lm.Level-1] + ">> " + lm.Msg + if got != want { + t.Errorf("want %s, got %s", want, got) + } +}