From 9c5815ee41f29e27774d17382d9a4bd10d208545 Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Mon, 30 Apr 2018 08:18:04 -0700 Subject: Add stdlog interpreter. (#8691) --- mlog/log.go | 2 +- mlog/stdlog.go | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++ mlog/stdlog_test.go | 42 ++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 mlog/stdlog.go create mode 100644 mlog/stdlog_test.go (limited to 'mlog') diff --git a/mlog/log.go b/mlog/log.go index 801030c6c..22db0c7b1 100644 --- a/mlog/log.go +++ b/mlog/log.go @@ -119,7 +119,7 @@ func (l *Logger) With(fields ...Field) *Logger { } func (l *Logger) StdLog(fields ...Field) *log.Logger { - return zap.NewStdLog(l.With(fields...).zap) + return zap.NewStdLog(l.With(fields...).zap.WithOptions(getStdLogOption())) } func (l *Logger) Debug(message string, fields ...Field) { diff --git a/mlog/stdlog.go b/mlog/stdlog.go new file mode 100644 index 000000000..a875b2e32 --- /dev/null +++ b/mlog/stdlog.go @@ -0,0 +1,74 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package mlog + +import ( + "strings" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +// Implementation of zapcore.Core to interpret log messages from a standard logger +// and translate the levels to zapcore levels. +type stdLogLevelInterpreterCore struct { + wrappedCore zapcore.Core +} + +func stdLogInterpretZapEntry(entry zapcore.Entry) zapcore.Entry { + message := entry.Message + if strings.Index(message, "[DEBUG]") == 0 { + entry.Level = zapcore.DebugLevel + entry.Message = message[7:] + } else if strings.Index(message, "[DEBG]") == 0 { + entry.Level = zapcore.DebugLevel + entry.Message = message[6:] + } else if strings.Index(message, "[WARN]") == 0 { + entry.Level = zapcore.WarnLevel + entry.Message = message[6:] + } else if strings.Index(message, "[ERROR]") == 0 { + entry.Level = zapcore.ErrorLevel + entry.Message = message[7:] + } else if strings.Index(message, "[EROR]") == 0 { + entry.Level = zapcore.ErrorLevel + entry.Message = message[6:] + } else if strings.Index(message, "[ERR]") == 0 { + entry.Level = zapcore.ErrorLevel + entry.Message = message[5:] + } else if strings.Index(message, "[INFO]") == 0 { + entry.Level = zapcore.InfoLevel + entry.Message = message[6:] + } + return entry +} + +func (s *stdLogLevelInterpreterCore) Enabled(lvl zapcore.Level) bool { + return s.wrappedCore.Enabled(lvl) +} + +func (s *stdLogLevelInterpreterCore) With(fields []zapcore.Field) zapcore.Core { + return s.wrappedCore.With(fields) +} + +func (s *stdLogLevelInterpreterCore) Check(entry zapcore.Entry, checkedEntry *zapcore.CheckedEntry) *zapcore.CheckedEntry { + entry = stdLogInterpretZapEntry(entry) + return s.wrappedCore.Check(entry, checkedEntry) +} + +func (s *stdLogLevelInterpreterCore) Write(entry zapcore.Entry, fields []zapcore.Field) error { + entry = stdLogInterpretZapEntry(entry) + return s.wrappedCore.Write(entry, fields) +} + +func (s *stdLogLevelInterpreterCore) Sync() error { + return s.wrappedCore.Sync() +} + +func getStdLogOption() zap.Option { + return zap.WrapCore( + func(core zapcore.Core) zapcore.Core { + return &stdLogLevelInterpreterCore{core} + }, + ) +} diff --git a/mlog/stdlog_test.go b/mlog/stdlog_test.go new file mode 100644 index 000000000..e924b406b --- /dev/null +++ b/mlog/stdlog_test.go @@ -0,0 +1,42 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package mlog + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "go.uber.org/zap/zapcore" +) + +func TestStdLogInterpretZapEntry(t *testing.T) { + for _, tc := range []struct { + testname string + message string + expectedMessage string + expectedLevel zapcore.Level + }{ + {"Debug Basic", "[DEBUG]My message", "My message", zapcore.DebugLevel}, + {"Debug Basic2", "[DEBG]My message", "My message", zapcore.DebugLevel}, + {"Warn Basic", "[WARN]My message", "My message", zapcore.WarnLevel}, + {"Error Basic", "[ERROR]My message", "My message", zapcore.ErrorLevel}, + {"Error Basic2", "[EROR]My message", "My message", zapcore.ErrorLevel}, + {"Error Basic3", "[ERR]My message", "My message", zapcore.ErrorLevel}, + {"Info Basic", "[INFO]My message", "My message", zapcore.InfoLevel}, + {"Unknown level", "[UNKNOWN]My message", "[UNKNOWN]My message", zapcore.PanicLevel}, + {"No level", "My message", "My message", zapcore.PanicLevel}, + {"Empty message", "", "", zapcore.PanicLevel}, + {"Malformed level", "INFO]My message", "INFO]My message", zapcore.PanicLevel}, + } { + t.Run(tc.testname, func(t *testing.T) { + inEntry := zapcore.Entry{ + Level: zapcore.PanicLevel, + Message: tc.message, + } + resultEntry := stdLogInterpretZapEntry(inEntry) + assert.Equal(t, tc.expectedMessage, resultEntry.Message) + assert.Equal(t, tc.expectedLevel, resultEntry.Level) + }) + } +} -- cgit v1.2.3-1-g7c22