feat: add log debug level (#2411)

master
MarkJoyMa 2 years ago committed by GitHub
parent 4c927624b0
commit e6aa6fc361
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -7,7 +7,7 @@ type LogConf struct {
Encoding string `json:",default=json,options=[json,plain]"`
TimeFormat string `json:",optional"`
Path string `json:",default=logs"`
Level string `json:",default=info,options=[info,error,severe]"`
Level string `json:",default=info,options=[debug,info,error,severe]"`
Compress bool `json:",optional"`
KeepDays int `json:",optional"`
StackCooldownMillis int `json:",default=100"`

@ -7,6 +7,14 @@ import (
// A Logger represents a logger.
type Logger interface {
// Debug logs a message at info level.
Debug(...interface{})
// Debugf logs a message at info level.
Debugf(string, ...interface{})
// Debugv logs a message at info level.
Debugv(interface{})
// Debugw logs a message at info level.
Debugw(string, ...LogField)
// Error logs a message at error level.
Error(...interface{})
// Errorf logs a message at error level.

@ -64,6 +64,26 @@ func Close() error {
return nil
}
// Debug writes v into access log.
func Debug(v ...interface{}) {
writeDebug(fmt.Sprint(v...))
}
// Debugf writes v with format into access log.
func Debugf(format string, v ...interface{}) {
writeDebug(fmt.Sprintf(format, v...))
}
// Debugv writes v into access log with json content.
func Debugv(v interface{}) {
writeDebug(v)
}
// Debugw writes msg along with fields into access log.
func Debugw(msg string, fields ...LogField) {
writeDebug(msg, fields...)
}
// Disable disables the logging.
func Disable() {
atomic.StoreUint32(&disableLog, 1)
@ -352,6 +372,8 @@ func handleOptions(opts []LogOption) {
func setupLogLevel(c LogConf) {
switch c.Level {
case levelDebug:
SetLevel(DebugLevel)
case levelInfo:
SetLevel(InfoLevel)
case levelError:
@ -392,6 +414,12 @@ func shallLogStat() bool {
return atomic.LoadUint32(&disableStat) == 0
}
func writeDebug(val interface{}, fields ...LogField) {
if shallLog(DebugLevel) {
getWriter().Debug(val, addCaller(fields...)...)
}
}
func writeError(val interface{}, fields ...LogField) {
if shallLog(ErrorLevel) {
getWriter().Error(val, addCaller(fields...)...)

@ -35,6 +35,12 @@ func (mw *mockWriter) Alert(v interface{}) {
output(&mw.builder, levelAlert, v)
}
func (mw *mockWriter) Debug(v interface{}, fields ...LogField) {
mw.lock.Lock()
defer mw.lock.Unlock()
output(&mw.builder, levelDebug, v, fields...)
}
func (mw *mockWriter) Error(v interface{}, fields ...LogField) {
mw.lock.Lock()
defer mw.lock.Unlock()
@ -212,6 +218,46 @@ func TestStructedLogAlert(t *testing.T) {
})
}
func TestStructedLogDebug(t *testing.T) {
w := new(mockWriter)
old := writer.Swap(w)
defer writer.Store(old)
doTestStructedLog(t, levelDebug, w, func(v ...interface{}) {
Debug(v...)
})
}
func TestStructedLogDebugf(t *testing.T) {
w := new(mockWriter)
old := writer.Swap(w)
defer writer.Store(old)
doTestStructedLog(t, levelDebug, w, func(v ...interface{}) {
Debugf(fmt.Sprint(v...))
})
}
func TestStructedLogDebugv(t *testing.T) {
w := new(mockWriter)
old := writer.Swap(w)
defer writer.Store(old)
doTestStructedLog(t, levelDebug, w, func(v ...interface{}) {
Debugv(fmt.Sprint(v...))
})
}
func TestStructedLogDebugw(t *testing.T) {
w := new(mockWriter)
old := writer.Swap(w)
defer writer.Store(old)
doTestStructedLog(t, levelDebug, w, func(v ...interface{}) {
Debugw(fmt.Sprint(v...), Field("foo", time.Second))
})
}
func TestStructedLogError(t *testing.T) {
w := new(mockWriter)
old := writer.Swap(w)

@ -40,6 +40,22 @@ type richLogger struct {
fields []LogField
}
func (l *richLogger) Debug(v ...interface{}) {
l.debug(fmt.Sprint(v...))
}
func (l *richLogger) Debugf(format string, v ...interface{}) {
l.debug(fmt.Sprintf(format, v...))
}
func (l *richLogger) Debugv(v interface{}) {
l.debug(v)
}
func (l *richLogger) Debugw(msg string, fields ...LogField) {
l.debug(msg, fields...)
}
func (l *richLogger) Error(v ...interface{}) {
l.err(fmt.Sprint(v...))
}
@ -135,6 +151,12 @@ func (l *richLogger) buildFields(fields ...LogField) []LogField {
return fields
}
func (l *richLogger) debug(v interface{}, fields ...LogField) {
if shallLog(DebugLevel) {
getWriter().Debug(v, l.buildFields(fields...)...)
}
}
func (l *richLogger) err(v interface{}, fields ...LogField) {
if shallLog(ErrorLevel) {
getWriter().Error(v, l.buildFields(fields...)...)

@ -37,6 +37,41 @@ func TestTraceLog(t *testing.T) {
validate(t, w.String(), true, true)
}
func TestTraceDebug(t *testing.T) {
w := new(mockWriter)
old := writer.Swap(w)
writer.lock.RLock()
defer func() {
writer.lock.RUnlock()
writer.Store(old)
}()
otp := otel.GetTracerProvider()
tp := sdktrace.NewTracerProvider(sdktrace.WithSampler(sdktrace.AlwaysSample()))
otel.SetTracerProvider(tp)
defer otel.SetTracerProvider(otp)
ctx, span := tp.Tracer("foo").Start(context.Background(), "bar")
defer span.End()
l := WithContext(ctx)
SetLevel(DebugLevel)
l.WithDuration(time.Second).Debug(testlog)
assert.True(t, strings.Contains(w.String(), traceKey))
assert.True(t, strings.Contains(w.String(), spanKey))
w.Reset()
l.WithDuration(time.Second).Debugf(testlog)
validate(t, w.String(), true, true)
w.Reset()
l.WithDuration(time.Second).Debugv(testlog)
validate(t, w.String(), true, true)
w.Reset()
l.WithDuration(time.Second).Debugw(testlog, Field("foo", "bar"))
validate(t, w.String(), true, true)
assert.True(t, strings.Contains(w.String(), "foo"), w.String())
assert.True(t, strings.Contains(w.String(), "bar"), w.String())
}
func TestTraceError(t *testing.T) {
w := new(mockWriter)
old := writer.Swap(w)

@ -3,8 +3,10 @@ package logx
import "errors"
const (
// InfoLevel logs everything
InfoLevel uint32 = iota
// DebugLevel logs everything
DebugLevel uint32 = iota
// InfoLevel does not include debugs
InfoLevel
// ErrorLevel includes errors, slows, stacks
ErrorLevel
// SevereLevel only log severe messages
@ -37,6 +39,7 @@ const (
levelFatal = "fatal"
levelSlow = "slow"
levelStat = "stat"
levelDebug = "debug"
backupFileDelimiter = "-"
flags = 0x0

@ -18,6 +18,7 @@ type (
Writer interface {
Alert(v interface{})
Close() error
Debug(v interface{}, fields ...LogField)
Error(v interface{}, fields ...LogField)
Info(v interface{}, fields ...LogField)
Severe(v interface{})
@ -194,6 +195,10 @@ func (w *concreteWriter) Close() error {
return w.statLog.Close()
}
func (w *concreteWriter) Debug(v interface{}, fields ...LogField) {
output(w.infoLog, levelDebug, v, fields...)
}
func (w *concreteWriter) Error(v interface{}, fields ...LogField) {
output(w.errorLog, levelError, v, fields...)
}
@ -227,6 +232,9 @@ func (n nopWriter) Close() error {
return nil
}
func (n nopWriter) Debug(_ interface{}, _ ...LogField) {
}
func (n nopWriter) Error(_ interface{}, _ ...LogField) {
}

Loading…
Cancel
Save