add Errorv/Infov/Slowv (#909)

This commit is contained in:
Kevin Wan
2021-08-13 18:28:39 +08:00
committed by GitHub
parent dc43430812
commit fbf2eebc42
5 changed files with 166 additions and 34 deletions

View File

@@ -31,6 +31,12 @@ func (l *durationLogger) Errorf(format string, v ...interface{}) {
} }
} }
func (l *durationLogger) Errorv(v interface{}) {
if shallLog(ErrorLevel) {
l.write(errorLog, levelError, v)
}
}
func (l *durationLogger) Info(v ...interface{}) { func (l *durationLogger) Info(v ...interface{}) {
if shallLog(InfoLevel) { if shallLog(InfoLevel) {
l.write(infoLog, levelInfo, fmt.Sprint(v...)) l.write(infoLog, levelInfo, fmt.Sprint(v...))
@@ -43,6 +49,12 @@ func (l *durationLogger) Infof(format string, v ...interface{}) {
} }
} }
func (l *durationLogger) Infov(v interface{}) {
if shallLog(InfoLevel) {
l.write(infoLog, levelInfo, v)
}
}
func (l *durationLogger) Slow(v ...interface{}) { func (l *durationLogger) Slow(v ...interface{}) {
if shallLog(ErrorLevel) { if shallLog(ErrorLevel) {
l.write(slowLog, levelSlow, fmt.Sprint(v...)) l.write(slowLog, levelSlow, fmt.Sprint(v...))
@@ -55,14 +67,20 @@ func (l *durationLogger) Slowf(format string, v ...interface{}) {
} }
} }
func (l *durationLogger) Slowv(v interface{}) {
if shallLog(ErrorLevel) {
l.write(slowLog, levelSlow, v)
}
}
func (l *durationLogger) WithDuration(duration time.Duration) Logger { func (l *durationLogger) WithDuration(duration time.Duration) Logger {
l.Duration = timex.ReprOfDuration(duration) l.Duration = timex.ReprOfDuration(duration)
return l return l
} }
func (l *durationLogger) write(writer io.Writer, level, content string) { func (l *durationLogger) write(writer io.Writer, level string, val interface{}) {
l.Timestamp = getTimestamp() l.Timestamp = getTimestamp()
l.Level = level l.Level = level
l.Content = content l.Content = val
outputJson(writer, logEntry(*l)) outputJson(writer, l)
} }

View File

@@ -81,10 +81,10 @@ var (
type ( type (
logEntry struct { logEntry struct {
Timestamp string `json:"@timestamp"` Timestamp string `json:"@timestamp"`
Level string `json:"level"` Level string `json:"level"`
Duration string `json:"duration,omitempty"` Duration string `json:"duration,omitempty"`
Content string `json:"content"` Content interface{} `json:"content"`
} }
logOptions struct { logOptions struct {
@@ -100,10 +100,13 @@ type (
Logger interface { Logger interface {
Error(...interface{}) Error(...interface{})
Errorf(string, ...interface{}) Errorf(string, ...interface{})
Errorv(interface{})
Info(...interface{}) Info(...interface{})
Infof(string, ...interface{}) Infof(string, ...interface{})
Infov(interface{})
Slow(...interface{}) Slow(...interface{})
Slowf(string, ...interface{}) Slowf(string, ...interface{})
Slowv(interface{})
WithDuration(time.Duration) Logger WithDuration(time.Duration) Logger
} }
) )
@@ -135,7 +138,7 @@ func SetUp(c LogConf) error {
// Alert alerts v in alert level, and the message is written to error log. // Alert alerts v in alert level, and the message is written to error log.
func Alert(v string) { func Alert(v string) {
output(errorLog, levelAlert, v) outputText(errorLog, levelAlert, v)
} }
// Close closes the logging. // Close closes the logging.
@@ -207,19 +210,19 @@ func Error(v ...interface{}) {
ErrorCaller(1, v...) ErrorCaller(1, v...)
} }
// Errorf writes v with format into error log.
func Errorf(format string, v ...interface{}) {
ErrorCallerf(1, format, v...)
}
// ErrorCaller writes v with context into error log. // ErrorCaller writes v with context into error log.
func ErrorCaller(callDepth int, v ...interface{}) { func ErrorCaller(callDepth int, v ...interface{}) {
errorSync(fmt.Sprint(v...), callDepth+callerInnerDepth) errorTextSync(fmt.Sprint(v...), callDepth+callerInnerDepth)
} }
// ErrorCallerf writes v with context in format into error log. // ErrorCallerf writes v with context in format into error log.
func ErrorCallerf(callDepth int, format string, v ...interface{}) { func ErrorCallerf(callDepth int, format string, v ...interface{}) {
errorSync(fmt.Sprintf(format, v...), callDepth+callerInnerDepth) errorTextSync(fmt.Sprintf(format, v...), callDepth+callerInnerDepth)
}
// Errorf writes v with format into error log.
func Errorf(format string, v ...interface{}) {
ErrorCallerf(1, format, v...)
} }
// ErrorStack writes v along with call stack into error log. // ErrorStack writes v along with call stack into error log.
@@ -234,14 +237,25 @@ func ErrorStackf(format string, v ...interface{}) {
stackSync(fmt.Sprintf(format, v...)) stackSync(fmt.Sprintf(format, v...))
} }
// Errorv writes v into error log with json content.
// No call stack attached, because not elegant to pack the messages.
func Errorv(v interface{}) {
errorAnySync(v)
}
// Info writes v into access log. // Info writes v into access log.
func Info(v ...interface{}) { func Info(v ...interface{}) {
infoSync(fmt.Sprint(v...)) infoTextSync(fmt.Sprint(v...))
} }
// Infof writes v with format into access log. // Infof writes v with format into access log.
func Infof(format string, v ...interface{}) { func Infof(format string, v ...interface{}) {
infoSync(fmt.Sprintf(format, v...)) infoTextSync(fmt.Sprintf(format, v...))
}
// Infov writes v into access log with json content.
func Infov(v interface{}) {
infoAnySync(v)
} }
// Must checks if err is nil, otherwise logs the err and exits. // Must checks if err is nil, otherwise logs the err and exits.
@@ -249,7 +263,7 @@ func Must(err error) {
if err != nil { if err != nil {
msg := formatWithCaller(err.Error(), 3) msg := formatWithCaller(err.Error(), 3)
log.Print(msg) log.Print(msg)
output(severeLog, levelFatal, msg) outputText(severeLog, levelFatal, msg)
os.Exit(1) os.Exit(1)
} }
} }
@@ -271,12 +285,17 @@ func Severef(format string, v ...interface{}) {
// Slow writes v into slow log. // Slow writes v into slow log.
func Slow(v ...interface{}) { func Slow(v ...interface{}) {
slowSync(fmt.Sprint(v...)) slowTextSync(fmt.Sprint(v...))
} }
// Slowf writes v with format into slow log. // Slowf writes v with format into slow log.
func Slowf(format string, v ...interface{}) { func Slowf(format string, v ...interface{}) {
slowSync(fmt.Sprintf(format, v...)) slowTextSync(fmt.Sprintf(format, v...))
}
// Slowv writes v into slow log with json content.
func Slowv(v interface{}) {
slowAnySync(v)
} }
// Stat writes v into stat log. // Stat writes v into stat log.
@@ -319,7 +338,13 @@ func createOutput(path string) (io.WriteCloser, error) {
options.gzipEnabled), options.gzipEnabled) options.gzipEnabled), options.gzipEnabled)
} }
func errorSync(msg string, callDepth int) { func errorAnySync(v interface{}) {
if shallLog(ErrorLevel) {
outputAny(errorLog, levelError, v)
}
}
func errorTextSync(msg string, callDepth int) {
if shallLog(ErrorLevel) { if shallLog(ErrorLevel) {
outputError(errorLog, msg, callDepth) outputError(errorLog, msg, callDepth)
} }
@@ -369,13 +394,28 @@ func handleOptions(opts []LogOption) {
} }
} }
func infoSync(msg string) { func infoAnySync(val interface{}) {
if shallLog(InfoLevel) { if shallLog(InfoLevel) {
output(infoLog, levelInfo, msg) outputAny(infoLog, levelInfo, val)
} }
} }
func output(writer io.Writer, level, msg string) { func infoTextSync(msg string) {
if shallLog(InfoLevel) {
outputText(infoLog, levelInfo, msg)
}
}
func outputAny(writer io.Writer, level string, val interface{}) {
info := logEntry{
Timestamp: getTimestamp(),
Level: level,
Content: val,
}
outputJson(writer, info)
}
func outputText(writer io.Writer, level, msg string) {
info := logEntry{ info := logEntry{
Timestamp: getTimestamp(), Timestamp: getTimestamp(),
Level: level, Level: level,
@@ -386,7 +426,7 @@ func output(writer io.Writer, level, msg string) {
func outputError(writer io.Writer, msg string, callDepth int) { func outputError(writer io.Writer, msg string, callDepth int) {
content := formatWithCaller(msg, callDepth) content := formatWithCaller(msg, callDepth)
output(writer, levelError, content) outputText(writer, levelError, content)
} }
func outputJson(writer io.Writer, info interface{}) { func outputJson(writer io.Writer, info interface{}) {
@@ -489,7 +529,7 @@ func setupWithVolume(c LogConf) error {
func severeSync(msg string) { func severeSync(msg string) {
if shallLog(SevereLevel) { if shallLog(SevereLevel) {
output(severeLog, levelSevere, fmt.Sprintf("%s\n%s", msg, string(debug.Stack()))) outputText(severeLog, levelSevere, fmt.Sprintf("%s\n%s", msg, string(debug.Stack())))
} }
} }
@@ -501,21 +541,27 @@ func shallLogStat() bool {
return atomic.LoadUint32(&disableStat) == 0 return atomic.LoadUint32(&disableStat) == 0
} }
func slowSync(msg string) { func slowAnySync(v interface{}) {
if shallLog(ErrorLevel) { if shallLog(ErrorLevel) {
output(slowLog, levelSlow, msg) outputAny(slowLog, levelSlow, v)
}
}
func slowTextSync(msg string) {
if shallLog(ErrorLevel) {
outputText(slowLog, levelSlow, msg)
} }
} }
func stackSync(msg string) { func stackSync(msg string) {
if shallLog(ErrorLevel) { if shallLog(ErrorLevel) {
output(stackLog, levelError, fmt.Sprintf("%s\n%s", msg, string(debug.Stack()))) outputText(stackLog, levelError, fmt.Sprintf("%s\n%s", msg, string(debug.Stack())))
} }
} }
func statSync(msg string) { func statSync(msg string) {
if shallLogStat() && shallLog(InfoLevel) { if shallLogStat() && shallLog(InfoLevel) {
output(statLog, levelStat, msg) outputText(statLog, levelStat, msg)
} }
} }

View File

@@ -92,6 +92,30 @@ func TestStructedLogAlert(t *testing.T) {
}) })
} }
func TestStructedLogError(t *testing.T) {
doTestStructedLog(t, levelError, func(writer io.WriteCloser) {
errorLog = writer
}, func(v ...interface{}) {
Error(v...)
})
}
func TestStructedLogErrorf(t *testing.T) {
doTestStructedLog(t, levelError, func(writer io.WriteCloser) {
errorLog = writer
}, func(v ...interface{}) {
Errorf("%s", fmt.Sprint(v...))
})
}
func TestStructedLogErrorv(t *testing.T) {
doTestStructedLog(t, levelError, func(writer io.WriteCloser) {
errorLog = writer
}, func(v ...interface{}) {
Errorv(fmt.Sprint(v...))
})
}
func TestStructedLogInfo(t *testing.T) { func TestStructedLogInfo(t *testing.T) {
doTestStructedLog(t, levelInfo, func(writer io.WriteCloser) { doTestStructedLog(t, levelInfo, func(writer io.WriteCloser) {
infoLog = writer infoLog = writer
@@ -100,6 +124,22 @@ func TestStructedLogInfo(t *testing.T) {
}) })
} }
func TestStructedLogInfof(t *testing.T) {
doTestStructedLog(t, levelInfo, func(writer io.WriteCloser) {
infoLog = writer
}, func(v ...interface{}) {
Infof("%s", fmt.Sprint(v...))
})
}
func TestStructedLogInfov(t *testing.T) {
doTestStructedLog(t, levelInfo, func(writer io.WriteCloser) {
infoLog = writer
}, func(v ...interface{}) {
Infov(fmt.Sprint(v...))
})
}
func TestStructedLogSlow(t *testing.T) { func TestStructedLogSlow(t *testing.T) {
doTestStructedLog(t, levelSlow, func(writer io.WriteCloser) { doTestStructedLog(t, levelSlow, func(writer io.WriteCloser) {
slowLog = writer slowLog = writer
@@ -116,6 +156,14 @@ func TestStructedLogSlowf(t *testing.T) {
}) })
} }
func TestStructedLogSlowv(t *testing.T) {
doTestStructedLog(t, levelSlow, func(writer io.WriteCloser) {
slowLog = writer
}, func(v ...interface{}) {
Slowv(fmt.Sprint(v...))
})
}
func TestStructedLogStat(t *testing.T) { func TestStructedLogStat(t *testing.T) {
doTestStructedLog(t, levelStat, func(writer io.WriteCloser) { doTestStructedLog(t, levelStat, func(writer io.WriteCloser) {
statLog = writer statLog = writer
@@ -368,7 +416,9 @@ func doTestStructedLog(t *testing.T, level string, setup func(writer io.WriteClo
t.Error(err) t.Error(err)
} }
assert.Equal(t, level, entry.Level) assert.Equal(t, level, entry.Level)
assert.True(t, strings.Contains(entry.Content, message)) val, ok := entry.Content.(string)
assert.True(t, ok)
assert.True(t, strings.Contains(val, message))
} }
func testSetLevelTwiceWithMode(t *testing.T, mode string) { func testSetLevelTwiceWithMode(t *testing.T, mode string) {

View File

@@ -44,5 +44,5 @@ func captureOutput(f func()) string {
func getContent(jsonStr string) string { func getContent(jsonStr string) string {
var entry logEntry var entry logEntry
json.Unmarshal([]byte(jsonStr), &entry) json.Unmarshal([]byte(jsonStr), &entry)
return entry.Content return entry.Content.(string)
} }

View File

@@ -29,6 +29,12 @@ func (l *traceLogger) Errorf(format string, v ...interface{}) {
} }
} }
func (l *traceLogger) Errorv(v interface{}) {
if shallLog(ErrorLevel) {
l.write(errorLog, levelError, v)
}
}
func (l *traceLogger) Info(v ...interface{}) { func (l *traceLogger) Info(v ...interface{}) {
if shallLog(InfoLevel) { if shallLog(InfoLevel) {
l.write(infoLog, levelInfo, fmt.Sprint(v...)) l.write(infoLog, levelInfo, fmt.Sprint(v...))
@@ -41,6 +47,12 @@ func (l *traceLogger) Infof(format string, v ...interface{}) {
} }
} }
func (l *traceLogger) Infov(v interface{}) {
if shallLog(InfoLevel) {
l.write(infoLog, levelInfo, v)
}
}
func (l *traceLogger) Slow(v ...interface{}) { func (l *traceLogger) Slow(v ...interface{}) {
if shallLog(ErrorLevel) { if shallLog(ErrorLevel) {
l.write(slowLog, levelSlow, fmt.Sprint(v...)) l.write(slowLog, levelSlow, fmt.Sprint(v...))
@@ -53,15 +65,21 @@ func (l *traceLogger) Slowf(format string, v ...interface{}) {
} }
} }
func (l *traceLogger) Slowv(v interface{}) {
if shallLog(ErrorLevel) {
l.write(slowLog, levelSlow, v)
}
}
func (l *traceLogger) WithDuration(duration time.Duration) Logger { func (l *traceLogger) WithDuration(duration time.Duration) Logger {
l.Duration = timex.ReprOfDuration(duration) l.Duration = timex.ReprOfDuration(duration)
return l return l
} }
func (l *traceLogger) write(writer io.Writer, level, content string) { func (l *traceLogger) write(writer io.Writer, level string, val interface{}) {
l.Timestamp = getTimestamp() l.Timestamp = getTimestamp()
l.Level = level l.Level = level
l.Content = content l.Content = val
l.Trace = traceIdFromContext(l.ctx) l.Trace = traceIdFromContext(l.ctx)
l.Span = spanIdFromContext(l.ctx) l.Span = spanIdFromContext(l.ctx)
outputJson(writer, l) outputJson(writer, l)