From 9c33cbc8e2f9c1e07935d304bad59fffc94c886d Mon Sep 17 00:00:00 2001 From: Vasiliy Tolstov Date: Mon, 6 Feb 2023 18:50:00 +0300 Subject: [PATCH 1/2] logger/unwrap: support sql and proto wrapper types Signed-off-by: Vasiliy Tolstov --- logger/unwrap/unwrap.go | 78 +++++++++++++++++++++++++++++++++++------ 1 file changed, 68 insertions(+), 10 deletions(-) diff --git a/logger/unwrap/unwrap.go b/logger/unwrap/unwrap.go index 7659eb40..491ead51 100644 --- a/logger/unwrap/unwrap.go +++ b/logger/unwrap/unwrap.go @@ -47,12 +47,15 @@ var ( ) type unwrap struct { - val interface{} - s fmt.State - pointers map[uintptr]int - opts *Options - depth int - ignoreNextType bool + val interface{} + s fmt.State + pointers map[uintptr]int + opts *Options + depth int + ignoreNextType bool + takeAll bool + protoWrapperType bool + sqlWrapperType bool } // Options struct @@ -242,9 +245,23 @@ func (f *unwrap) format(v reflect.Value) { } // Handle pointers specially. - if kind == reflect.Ptr { + switch kind { + case reflect.Ptr: + if !v.IsZero() { + if strings.HasPrefix(reflect.Indirect(v).Type().String(), "wrapperspb.") { + f.protoWrapperType = true + } else if strings.HasPrefix(reflect.Indirect(v).Type().String(), "sql.Null") { + f.sqlWrapperType = true + } + } f.formatPtr(v) return + case reflect.Struct: + if !v.IsZero() { + if strings.HasPrefix(reflect.Indirect(v).Type().String(), "sql.Null") { + f.sqlWrapperType = true + } + } } // get type information unless already handled elsewhere. @@ -355,8 +372,17 @@ func (f *unwrap) format(v reflect.Value) { prevSkip := false for i := 0; i < numFields; i++ { + f.takeAll = false + if f.protoWrapperType && !vt.Field(i).IsExported() { + prevSkip = true + continue + } else if f.sqlWrapperType && vt.Field(i).Name == "Valid" { + prevSkip = true + continue + } sv, ok := vt.Field(i).Tag.Lookup("logger") - if ok { + switch { + case ok: switch sv { case "omit": prevSkip = true @@ -364,7 +390,9 @@ func (f *unwrap) format(v reflect.Value) { case "take": break } - } else if f.opts.Tagged { + case f.takeAll: + break + case !ok && f.opts.Tagged: prevSkip = true continue } @@ -383,7 +411,9 @@ func (f *unwrap) format(v reflect.Value) { _, _ = f.s.Write([]byte(vtf.Name)) _, _ = f.s.Write(colonBytes) } - f.format(f.unpackValue(v.Field(i))) + unpackValue := f.unpackValue(v.Field(i)) + f.takeAll = f.checkTakeAll(unpackValue) + f.format(unpackValue) numWritten++ } f.depth-- @@ -579,3 +609,31 @@ func (f *unwrap) constructOrigFormat(verb rune) (format string) { format = buf.String() return format } + +func (f *unwrap) checkTakeAll(v reflect.Value) bool { + takeAll := true + + switch v.Kind() { + case reflect.Struct: + break + case reflect.Pointer: + v = v.Elem() + if v.Kind() != reflect.Struct { + return true + } + default: + return true + } + + vt := v.Type() + + for i := 0; i < v.NumField(); i++ { + sv, ok := vt.Field(i).Tag.Lookup("logger") + if ok && sv == "take" { + return false + } + takeAll = f.checkTakeAll(v.Field(i)) + } + + return takeAll +} From 5a554f9f0c9e24dd0404fac548aadb764ee46d55 Mon Sep 17 00:00:00 2001 From: Vasiliy Tolstov Date: Mon, 6 Feb 2023 18:53:27 +0300 Subject: [PATCH 2/2] fixup Signed-off-by: Vasiliy Tolstov --- logger/unwrap/unwrap.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logger/unwrap/unwrap.go b/logger/unwrap/unwrap.go index 491ead51..c5469b47 100644 --- a/logger/unwrap/unwrap.go +++ b/logger/unwrap/unwrap.go @@ -616,7 +616,7 @@ func (f *unwrap) checkTakeAll(v reflect.Value) bool { switch v.Kind() { case reflect.Struct: break - case reflect.Pointer: + case reflect.Ptr: v = v.Elem() if v.Kind() != reflect.Struct { return true