Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
0d1ef31764 | |||
d49afa230f | |||
e545eb4e13 | |||
f28b107372 |
@@ -42,7 +42,7 @@ type RawMessage []byte
|
||||
// MarshalJSON returns m as the JSON encoding of m.
|
||||
func (m *RawMessage) MarshalJSON() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
return []byte("null"), nil
|
||||
}
|
||||
return *m, nil
|
||||
}
|
||||
|
@@ -96,8 +96,8 @@ type CallOptions struct {
|
||||
RequestTimeout time.Duration
|
||||
// DialTimeout dial timeout
|
||||
DialTimeout time.Duration
|
||||
// AuthToken flag
|
||||
AuthToken bool
|
||||
// AuthToken string
|
||||
AuthToken string
|
||||
}
|
||||
|
||||
// Context pass context to client
|
||||
@@ -463,9 +463,9 @@ func WithDialTimeout(d time.Duration) CallOption {
|
||||
|
||||
// WithAuthToken is a CallOption which overrides the
|
||||
// authorization header with the services own auth token
|
||||
func WithAuthToken() CallOption {
|
||||
func WithAuthToken(t string) CallOption {
|
||||
return func(o *CallOptions) {
|
||||
o.AuthToken = true
|
||||
o.AuthToken = t
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -24,6 +24,8 @@ type defaultLogger struct {
|
||||
enc *json.Encoder
|
||||
opts Options
|
||||
sync.RWMutex
|
||||
logFunc LogFunc
|
||||
logfFunc LogfFunc
|
||||
}
|
||||
|
||||
// Init(opts...) should only overwrite provided options
|
||||
@@ -33,6 +35,15 @@ func (l *defaultLogger) Init(opts ...Option) error {
|
||||
o(&l.opts)
|
||||
}
|
||||
l.enc = json.NewEncoder(l.opts.Out)
|
||||
|
||||
l.logFunc = l.Log
|
||||
l.logfFunc = l.Logf
|
||||
// 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()
|
||||
return nil
|
||||
}
|
||||
@@ -121,27 +132,27 @@ func (l *defaultLogger) Fatal(ctx context.Context, args ...interface{}) {
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Infof(ctx context.Context, msg string, args ...interface{}) {
|
||||
l.Logf(ctx, InfoLevel, msg, args...)
|
||||
l.logfFunc(ctx, InfoLevel, msg, args...)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Errorf(ctx context.Context, msg string, args ...interface{}) {
|
||||
l.Logf(ctx, ErrorLevel, msg, args...)
|
||||
l.logfFunc(ctx, ErrorLevel, msg, args...)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Debugf(ctx context.Context, msg string, args ...interface{}) {
|
||||
l.Logf(ctx, DebugLevel, msg, args...)
|
||||
l.logfFunc(ctx, DebugLevel, msg, args...)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Warnf(ctx context.Context, msg string, args ...interface{}) {
|
||||
l.Logf(ctx, WarnLevel, msg, args...)
|
||||
l.logfFunc(ctx, WarnLevel, msg, args...)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Tracef(ctx context.Context, msg string, args ...interface{}) {
|
||||
l.Logf(ctx, TraceLevel, msg, args...)
|
||||
l.logfFunc(ctx, TraceLevel, msg, args...)
|
||||
}
|
||||
|
||||
func (l *defaultLogger) Fatalf(ctx context.Context, msg string, args ...interface{}) {
|
||||
l.Logf(ctx, FatalLevel, msg, args...)
|
||||
l.logfFunc(ctx, FatalLevel, msg, args...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
@@ -1,13 +1,15 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLogger(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
l := NewLogger(WithLevel(TraceLevel))
|
||||
buf := bytes.NewBuffer(nil)
|
||||
l := NewLogger(WithLevel(TraceLevel), WithOutput(buf))
|
||||
if err := l.Init(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -15,4 +17,52 @@ func TestLogger(t *testing.T) {
|
||||
l.Warn(ctx, "warn_msg1")
|
||||
l.Fields(map[string]interface{}{"error": "test"}).Info(ctx, "error message")
|
||||
l.Warn(ctx, "first", " ", "second")
|
||||
if !bytes.Contains(buf.Bytes(), []byte(`"level":"trace","msg":"trace_msg1"`)) {
|
||||
t.Fatalf("logger error, buf %s", buf.Bytes())
|
||||
}
|
||||
if !bytes.Contains(buf.Bytes(), []byte(`"warn","msg":"warn_msg1"`)) {
|
||||
t.Fatalf("logger error, buf %s", buf.Bytes())
|
||||
}
|
||||
if !bytes.Contains(buf.Bytes(), []byte(`"error":"test","level":"info","msg":"error message"`)) {
|
||||
t.Fatalf("logger error, buf %s", buf.Bytes())
|
||||
}
|
||||
if !bytes.Contains(buf.Bytes(), []byte(`"level":"warn","msg":"first second"`)) {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,8 @@ type Options struct {
|
||||
CallerSkipCount int
|
||||
// The logging level the logger should log
|
||||
Level Level
|
||||
// Wrappers logger wrapper that called before actual Log/Logf function
|
||||
Wrappers []Wrapper
|
||||
}
|
||||
|
||||
// NewOptions creates new options struct
|
||||
@@ -81,3 +83,10 @@ func WithName(n string) Option {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
150
logger/wrapper.go
Normal file
150
logger/wrapper.go
Normal file
@@ -0,0 +1,150 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
|
||||
rutil "github.com/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
|
||||
}
|
||||
|
||||
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) Options() Options {
|
||||
return w.l.Options()
|
||||
}
|
||||
|
||||
func (w *OmitLogger) Fields(fields map[string]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)
|
||||
switch val.Kind() {
|
||||
case reflect.Ptr:
|
||||
val = val.Elem()
|
||||
}
|
||||
narg := arg
|
||||
if val.Kind() == reflect.Struct {
|
||||
if narg, err = rutil.Zero(arg); err == nil {
|
||||
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)...)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user