Browse Source

增加用于打印日志的结构体格式化函数

pull/1/head
Sydonian 2 years ago
parent
commit
9656f5c57c
2 changed files with 122 additions and 0 deletions
  1. +39
    -0
      pkg/logger/logger_test.go
  2. +83
    -0
      pkg/logger/utils.go

+ 39
- 0
pkg/logger/logger_test.go View File

@@ -0,0 +1,39 @@
package logger

import (
"fmt"
"testing"

. "github.com/smartystreets/goconvey/convey"
)

func Test_FormatStruct(t *testing.T) {
Convey("检查输出格式", t, func() {

type Struct2 struct {
Int int
}

type Struct struct {
Arr []int
NilArr []int
FixedArr [5]int
St2 Struct2
St2Ptr *Struct2
NilSt2Ptr *Struct2
}

So(fmt.Sprintf("%v", FormatStruct(Struct{
Arr: []int{1, 2, 3, 4},
NilArr: nil,
FixedArr: [5]int{1, 2, 3, 4, 5},
St2: Struct2{
Int: 123,
},
St2Ptr: &Struct2{
Int: 456,
},
NilSt2Ptr: nil,
})), ShouldEqual, "len(Arr): 4, len(NilArr): 0, len(FixedArr): 5, St2: <Struct2>, St2Ptr: &<Struct2>, NilSt2Ptr: <nil>")
})
}

+ 83
- 0
pkg/logger/utils.go View File

@@ -0,0 +1,83 @@
package logger

import (
"fmt"
"reflect"
"strings"
)

type structFormatter struct {
val any
}

func (f *structFormatter) String() string {
typ := reflect.TypeOf(f.val)
val := reflect.ValueOf(f.val)

kind := typ.Kind()

if kind != reflect.Struct {
return fmt.Sprintf("%v", f.val)
}

strBuilder := strings.Builder{}
for i := 0; i < val.NumField(); i++ {
fieldInfo := typ.Field(i)
fieldValue := val.Field(i)
fieldType := fieldInfo.Type
fieldKind := fieldType.Kind()

switch fieldKind {
case reflect.Slice:
fallthrough
case reflect.Array:
if i > 0 {
strBuilder.WriteString(", ")
}

strBuilder.WriteString("len(")
strBuilder.WriteString(fieldInfo.Name)
strBuilder.WriteString("): ")
strBuilder.WriteString(fmt.Sprintf("%d", fieldValue.Len()))

case reflect.Struct:
if i > 0 {
strBuilder.WriteString(", ")
}

strBuilder.WriteString(fieldInfo.Name)
strBuilder.WriteString(": <")
strBuilder.WriteString(fieldType.Name())
strBuilder.WriteString(">")

case reflect.Pointer:
if i > 0 {
strBuilder.WriteString(", ")
}
strBuilder.WriteString(fieldInfo.Name)
if fieldValue.IsNil() {
strBuilder.WriteString(": <nil>")
} else {
strBuilder.WriteString(": &<")
strBuilder.WriteString(fieldType.Elem().Name())
strBuilder.WriteString(">")
}

default:
if i > 0 {
strBuilder.WriteString(", ")
}
strBuilder.WriteString(fieldInfo.Name)
strBuilder.WriteString(": ")
strBuilder.WriteString(fmt.Sprintf("%v", fieldValue))
}
}

return strBuilder.String()
}

func FormatStruct(val any) any {
return &structFormatter{
val: val,
}
}

Loading…
Cancel
Save