fsm: improve and convert to interface #178

Merged
vtolstov merged 2 commits from fsm into v3 2023-01-30 00:31:50 +03:00
4 changed files with 15 additions and 247 deletions
Showing only changes of commit cb743cee3f - Show all commits

View File

@ -12,10 +12,8 @@ import (
) )
type defaultLogger struct { type defaultLogger struct {
enc *json.Encoder enc *json.Encoder
logFunc LogFunc opts Options
logfFunc LogfFunc
opts Options
sync.RWMutex sync.RWMutex
} }
@ -27,10 +25,6 @@ func (l *defaultLogger) Init(opts ...Option) error {
} }
l.enc = json.NewEncoder(l.opts.Out) l.enc = json.NewEncoder(l.opts.Out)
// wrap the Log func // wrap the Log func
for i := len(l.opts.Wrappers); i > 0; i-- {
l.logFunc = l.opts.Wrappers[i-1].Log(l.logFunc)
l.logfFunc = l.opts.Wrappers[i-1].Logf(l.logfFunc)
}
l.Unlock() l.Unlock()
return nil return nil
} }
@ -47,17 +41,10 @@ func (l *defaultLogger) Clone(opts ...Option) Logger {
o(&oldopts) o(&oldopts)
} }
oldopts.Wrappers = newopts.Wrappers
l.Lock() l.Lock()
cl := &defaultLogger{opts: oldopts, logFunc: l.logFunc, logfFunc: l.logfFunc, enc: json.NewEncoder(l.opts.Out)} cl := &defaultLogger{opts: oldopts, enc: json.NewEncoder(l.opts.Out)}
l.Unlock() l.Unlock()
// wrap the Log func
for i := len(newopts.Wrappers); i > 0; i-- {
cl.logFunc = newopts.Wrappers[i-1].Log(cl.logFunc)
cl.logfFunc = newopts.Wrappers[i-1].Logf(cl.logfFunc)
}
return cl return cl
} }
@ -83,12 +70,6 @@ func (l *defaultLogger) Fields(fields ...interface{}) Logger {
} else if len(fields)%2 != 0 { } else if len(fields)%2 != 0 {
fields = fields[:len(fields)-1] fields = fields[:len(fields)-1]
} }
nl.logFunc = nl.Log
nl.logfFunc = nl.Logf
for i := len(nl.opts.Wrappers); i > 0; i-- {
nl.logFunc = nl.opts.Wrappers[i-1].Log(nl.logFunc)
nl.logfFunc = nl.opts.Wrappers[i-1].Logf(nl.logfFunc)
}
nl.opts.Fields = copyFields(l.opts.Fields) nl.opts.Fields = copyFields(l.opts.Fields)
nl.opts.Fields = append(nl.opts.Fields, fields...) nl.opts.Fields = append(nl.opts.Fields, fields...)
l.RUnlock() l.RUnlock()
@ -126,52 +107,52 @@ func logCallerfilePath(loggingFilePath string) string {
} }
func (l *defaultLogger) Info(ctx context.Context, args ...interface{}) { func (l *defaultLogger) Info(ctx context.Context, args ...interface{}) {
l.logFunc(ctx, InfoLevel, args...) l.Log(ctx, InfoLevel, args...)
} }
func (l *defaultLogger) Error(ctx context.Context, args ...interface{}) { func (l *defaultLogger) Error(ctx context.Context, args ...interface{}) {
l.logFunc(ctx, ErrorLevel, args...) l.Log(ctx, ErrorLevel, args...)
} }
func (l *defaultLogger) Debug(ctx context.Context, args ...interface{}) { func (l *defaultLogger) Debug(ctx context.Context, args ...interface{}) {
l.logFunc(ctx, DebugLevel, args...) l.Log(ctx, DebugLevel, args...)
} }
func (l *defaultLogger) Warn(ctx context.Context, args ...interface{}) { func (l *defaultLogger) Warn(ctx context.Context, args ...interface{}) {
l.logFunc(ctx, WarnLevel, args...) l.Log(ctx, WarnLevel, args...)
} }
func (l *defaultLogger) Trace(ctx context.Context, args ...interface{}) { func (l *defaultLogger) Trace(ctx context.Context, args ...interface{}) {
l.logFunc(ctx, TraceLevel, args...) l.Log(ctx, TraceLevel, args...)
} }
func (l *defaultLogger) Fatal(ctx context.Context, args ...interface{}) { func (l *defaultLogger) Fatal(ctx context.Context, args ...interface{}) {
l.logFunc(ctx, FatalLevel, args...) l.Log(ctx, FatalLevel, args...)
os.Exit(1) os.Exit(1)
} }
func (l *defaultLogger) Infof(ctx context.Context, msg string, args ...interface{}) { func (l *defaultLogger) Infof(ctx context.Context, msg string, args ...interface{}) {
l.logfFunc(ctx, InfoLevel, msg, args...) l.Logf(ctx, InfoLevel, msg, args...)
} }
func (l *defaultLogger) Errorf(ctx context.Context, msg string, args ...interface{}) { func (l *defaultLogger) Errorf(ctx context.Context, msg string, args ...interface{}) {
l.logfFunc(ctx, ErrorLevel, msg, args...) l.Logf(ctx, ErrorLevel, msg, args...)
} }
func (l *defaultLogger) Debugf(ctx context.Context, msg string, args ...interface{}) { func (l *defaultLogger) Debugf(ctx context.Context, msg string, args ...interface{}) {
l.logfFunc(ctx, DebugLevel, msg, args...) l.Logf(ctx, DebugLevel, msg, args...)
} }
func (l *defaultLogger) Warnf(ctx context.Context, msg string, args ...interface{}) { func (l *defaultLogger) Warnf(ctx context.Context, msg string, args ...interface{}) {
l.logfFunc(ctx, WarnLevel, msg, args...) l.Logf(ctx, WarnLevel, msg, args...)
} }
func (l *defaultLogger) Tracef(ctx context.Context, msg string, args ...interface{}) { func (l *defaultLogger) Tracef(ctx context.Context, msg string, args ...interface{}) {
l.logfFunc(ctx, TraceLevel, msg, args...) l.Logf(ctx, TraceLevel, msg, args...)
} }
func (l *defaultLogger) Fatalf(ctx context.Context, msg string, args ...interface{}) { func (l *defaultLogger) Fatalf(ctx context.Context, msg string, args ...interface{}) {
l.logfFunc(ctx, FatalLevel, msg, args...) l.Logf(ctx, FatalLevel, msg, args...)
os.Exit(1) os.Exit(1)
} }
@ -244,8 +225,6 @@ func NewLogger(opts ...Option) Logger {
l := &defaultLogger{ l := &defaultLogger{
opts: NewOptions(opts...), opts: NewOptions(opts...),
} }
l.logFunc = l.Log
l.logfFunc = l.Logf
l.enc = json.NewEncoder(l.opts.Out) l.enc = json.NewEncoder(l.opts.Out)
return l return l
} }

View File

@ -136,39 +136,3 @@ func TestLogger(t *testing.T) {
t.Fatalf("logger error, buf %s", buf.Bytes()) t.Fatalf("logger error, buf %s", buf.Bytes())
} }
} }
func TestLoggerWrapper(t *testing.T) {
ctx := context.TODO()
buf := bytes.NewBuffer(nil)
l := NewLogger(WithLevel(TraceLevel), WithOutput(buf))
if err := l.Init(WrapLogger(NewOmitWrapper())); err != nil {
t.Fatal(err)
}
type secret struct {
Name string
Passw string `logger:"omit"`
}
s := &secret{Name: "name", Passw: "secret"}
l.Errorf(ctx, "test %#+v", s)
if !bytes.Contains(buf.Bytes(), []byte(`logger.secret{Name:\"name\", Passw:\"\"}"`)) {
t.Fatalf("omit not works, struct: %v, output: %s", s, buf.Bytes())
}
}
func TestOmitLoggerWrapper(t *testing.T) {
ctx := context.TODO()
buf := bytes.NewBuffer(nil)
l := NewOmitLogger(NewLogger(WithLevel(TraceLevel), WithOutput(buf)))
if err := l.Init(); err != nil {
t.Fatal(err)
}
type secret struct {
Name string
Passw string `logger:"omit"`
}
s := &secret{Name: "name", Passw: "secret"}
l.Errorf(ctx, "test %#+v", s)
if !bytes.Contains(buf.Bytes(), []byte(`logger.secret{Name:\"name\", Passw:\"\"}"`)) {
t.Fatalf("omit not works, struct: %v, output: %s", s, buf.Bytes())
}
}

View File

@ -19,8 +19,6 @@ type Options struct {
Fields []interface{} Fields []interface{}
// Name holds the logger name // Name holds the logger name
Name string Name string
// Wrappers logger wrapper that called before actual Log/Logf function
Wrappers []Wrapper
// The logging level the logger should log // The logging level the logger should log
Level Level Level Level
// CallerSkipCount number of frmaes to skip // CallerSkipCount number of frmaes to skip
@ -83,10 +81,3 @@ func WithName(n string) Option {
o.Name = n o.Name = n
} }
} }
// WrapLogger adds a logger Wrapper to a list of options passed into the logger
func WrapLogger(w Wrapper) Option {
return func(o *Options) {
o.Wrappers = append(o.Wrappers, w)
}
}

View File

@ -1,166 +0,0 @@
package logger // import "go.unistack.org/micro/v3/logger/wrapper"
import (
"context"
"reflect"
rutil "go.unistack.org/micro/v3/util/reflect"
)
// LogFunc function used for Log method
type LogFunc func(ctx context.Context, level Level, args ...interface{})
// LogfFunc function used for Logf method
type LogfFunc func(ctx context.Context, level Level, msg string, args ...interface{})
type Wrapper interface {
// Log logs message with needed level
Log(LogFunc) LogFunc
// Logf logs message with needed level
Logf(LogfFunc) LogfFunc
}
var _ Logger = &omitLogger{}
type omitLogger struct {
l Logger
}
func NewOmitLogger(l Logger) Logger {
return &omitLogger{l: l}
}
func (w *omitLogger) Init(opts ...Option) error {
return w.l.Init(append(opts, WrapLogger(NewOmitWrapper()))...)
}
func (w *omitLogger) V(level Level) bool {
return w.l.V(level)
}
func (w *omitLogger) Level(level Level) {
w.l.Level(level)
}
func (w *omitLogger) Clone(opts ...Option) Logger {
return w.l.Clone(opts...)
}
func (w *omitLogger) Options() Options {
return w.l.Options()
}
func (w *omitLogger) Fields(fields ...interface{}) Logger {
return w.l.Fields(fields...)
}
func (w *omitLogger) Info(ctx context.Context, args ...interface{}) {
w.l.Info(ctx, args...)
}
func (w *omitLogger) Trace(ctx context.Context, args ...interface{}) {
w.l.Trace(ctx, args...)
}
func (w *omitLogger) Debug(ctx context.Context, args ...interface{}) {
w.l.Debug(ctx, args...)
}
func (w *omitLogger) Warn(ctx context.Context, args ...interface{}) {
w.l.Warn(ctx, args...)
}
func (w *omitLogger) Error(ctx context.Context, args ...interface{}) {
w.l.Error(ctx, args...)
}
func (w *omitLogger) Fatal(ctx context.Context, args ...interface{}) {
w.l.Fatal(ctx, args...)
}
func (w *omitLogger) Infof(ctx context.Context, msg string, args ...interface{}) {
w.l.Infof(ctx, msg, args...)
}
func (w *omitLogger) Tracef(ctx context.Context, msg string, args ...interface{}) {
w.l.Tracef(ctx, msg, args...)
}
func (w *omitLogger) Debugf(ctx context.Context, msg string, args ...interface{}) {
w.l.Debugf(ctx, msg, args...)
}
func (w *omitLogger) Warnf(ctx context.Context, msg string, args ...interface{}) {
w.l.Warnf(ctx, msg, args...)
}
func (w *omitLogger) Errorf(ctx context.Context, msg string, args ...interface{}) {
w.l.Errorf(ctx, msg, args...)
}
func (w *omitLogger) Fatalf(ctx context.Context, msg string, args ...interface{}) {
w.l.Fatalf(ctx, msg, args...)
}
func (w *omitLogger) Log(ctx context.Context, level Level, args ...interface{}) {
w.l.Log(ctx, level, args...)
}
func (w *omitLogger) Logf(ctx context.Context, level Level, msg string, args ...interface{}) {
w.l.Logf(ctx, level, msg, args...)
}
func (w *omitLogger) String() string {
return w.l.String()
}
type omitWrapper struct{}
func NewOmitWrapper() Wrapper {
return &omitWrapper{}
}
func getArgs(args []interface{}) []interface{} {
nargs := make([]interface{}, 0, len(args))
var err error
for _, arg := range args {
val := reflect.ValueOf(arg)
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
narg := arg
if val.Kind() != reflect.Struct {
nargs = append(nargs, narg)
continue
}
if narg, err = rutil.Zero(arg); err != nil {
nargs = append(nargs, narg)
continue
}
rutil.CopyDefaults(narg, arg)
if flds, ferr := rutil.StructFields(narg); ferr == nil {
for _, fld := range flds {
if tv, ok := fld.Field.Tag.Lookup("logger"); ok && tv == "omit" {
fld.Value.Set(reflect.Zero(fld.Value.Type()))
}
}
}
nargs = append(nargs, narg)
}
return nargs
}
func (w *omitWrapper) Log(fn LogFunc) LogFunc {
return func(ctx context.Context, level Level, args ...interface{}) {
fn(ctx, level, getArgs(args)...)
}
}
func (w *omitWrapper) Logf(fn LogfFunc) LogfFunc {
return func(ctx context.Context, level Level, msg string, args ...interface{}) {
fn(ctx, level, msg, getArgs(args)...)
}
}