gitee.com/h79/goutils@v1.22.10/common/logger/tag.go (about)

     1  package logger
     2  
     3  import (
     4  	"gitee.com/h79/goutils/common/tag"
     5  	"go.uber.org/zap/zapcore"
     6  	"reflect"
     7  	"strconv"
     8  	"strings"
     9  )
    10  
    11  type Decorate struct {
    12  	S string
    13  	E string
    14  }
    15  
    16  func (d *Decorate) UseObject() {
    17  	d.S = "{"
    18  	d.E = "}"
    19  }
    20  
    21  func (d *Decorate) UseSlice() {
    22  	d.S = "["
    23  	d.E = "]"
    24  }
    25  
    26  func ObjectTo(o any) string {
    27  	d := Decorate{}
    28  	s := objectDecorate(o, &d)
    29  	if d.S != "" {
    30  		return d.S + s + d.E
    31  	}
    32  	return s
    33  }
    34  
    35  func NObjectTo(o any) string {
    36  	if !ndebugEnabled {
    37  		return ""
    38  	}
    39  	return DObjectTo(o)
    40  }
    41  
    42  func DObjectTo(o any) string {
    43  	if L().Core().Enabled(zapcore.DebugLevel) {
    44  		return ObjectTo(o)
    45  	}
    46  	return ""
    47  }
    48  
    49  func WObjectTo(o any) string {
    50  	if L().Core().Enabled(zapcore.WarnLevel) {
    51  		return ObjectTo(o)
    52  	}
    53  	return ""
    54  }
    55  
    56  func IObjectTo(o any) string {
    57  	if L().Core().Enabled(zapcore.InfoLevel) {
    58  		return ObjectTo(o)
    59  	}
    60  	return ""
    61  }
    62  
    63  func EObjectTo(o any) string {
    64  	if L().Core().Enabled(zapcore.ErrorLevel) {
    65  		return ObjectTo(o)
    66  	}
    67  	return ""
    68  }
    69  
    70  func objectDecorate(o any, d *Decorate) string {
    71  	b := strings.Builder{}
    72  	objectTo(&b, o, d)
    73  	return b.String()
    74  }
    75  
    76  func objectTo(b *strings.Builder, o any, d *Decorate) {
    77  	value := reflect.ValueOf(o)
    78  	switch value.Kind() {
    79  	case reflect.Ptr:
    80  		if value.IsNil() {
    81  			b.WriteString("")
    82  			return
    83  		}
    84  		v := value.Elem()
    85  		objectTo(b, v.Interface(), d)
    86  	case reflect.Struct:
    87  		d.UseObject()
    88  		structTo(b, value)
    89  	case reflect.Slice:
    90  		d.UseSlice()
    91  		for i := 0; i < value.Len(); i++ {
    92  			if i > 0 {
    93  				b.WriteString(",")
    94  			}
    95  			b.WriteString(objectString(value.Index(i), &Decorate{}))
    96  		}
    97  	case reflect.Map:
    98  		d.UseObject()
    99  		k := value.MapKeys()
   100  		for i := range k {
   101  			if i > 0 {
   102  				b.WriteString(",")
   103  			}
   104  			b.WriteString(objectString(k[i], &Decorate{}))
   105  			b.WriteString(":")
   106  			b.WriteString(objectString(value.MapIndex(k[i]), &Decorate{}))
   107  		}
   108  	default:
   109  		b.WriteString(objectString(value, d))
   110  	}
   111  }
   112  
   113  func structTo(b *strings.Builder, value reflect.Value) {
   114  	begin := 0
   115  	t := value.Type()
   116  	for i := 0; i < t.NumField(); i++ {
   117  		field := t.Field(i)
   118  		if field.PkgPath != "" {
   119  			continue
   120  		}
   121  		l := field.Tag.Get("log")
   122  		if l == "-" {
   123  			continue
   124  		}
   125  		name, opts := tag.Parse(l)
   126  		omitempty := opts.Has("omitempty")
   127  		val := value.FieldByName(field.Name)
   128  
   129  		de := Decorate{}
   130  		vv := objectString(val, &de)
   131  		if omitempty && (vv == "" || vv == "\"\"" || vv == "false" || vv == "0") {
   132  			continue
   133  		}
   134  		if begin > 0 {
   135  			b.WriteString(",")
   136  		}
   137  		begin++
   138  		b.WriteString("\"")
   139  		b.WriteString(name)
   140  		b.WriteString("\":")
   141  		if de.S != "" {
   142  			b.WriteString(de.S)
   143  		}
   144  		b.WriteString(vv)
   145  		if de.E != "" {
   146  			b.WriteString(de.E)
   147  		}
   148  	}
   149  }
   150  
   151  func objectString(val reflect.Value, d *Decorate) string {
   152  	switch val.Kind() {
   153  	case reflect.String:
   154  		return strconv.QuoteToASCII(val.String())
   155  	case reflect.Int:
   156  		fallthrough
   157  	case reflect.Int8:
   158  		fallthrough
   159  	case reflect.Int16:
   160  		fallthrough
   161  	case reflect.Int32:
   162  		fallthrough
   163  	case reflect.Int64:
   164  		return strconv.FormatInt(val.Int(), 10)
   165  
   166  	case reflect.Uint:
   167  		fallthrough
   168  	case reflect.Uint8:
   169  		fallthrough
   170  	case reflect.Uint16:
   171  		fallthrough
   172  	case reflect.Uint32:
   173  		fallthrough
   174  	case reflect.Uint64:
   175  		return strconv.FormatUint(val.Uint(), 10)
   176  	case reflect.Float32:
   177  		fallthrough
   178  	case reflect.Float64:
   179  		return strconv.FormatFloat(val.Float(), 'f', 10, 64)
   180  
   181  	case reflect.Bool:
   182  		if val.Bool() {
   183  			return "true"
   184  		} else {
   185  			return "false"
   186  		}
   187  	case reflect.Invalid:
   188  		return strconv.FormatUint(0, 10)
   189  	case reflect.Interface:
   190  		return objectDecorate(val.Interface(), d)
   191  	case reflect.Struct:
   192  		return objectDecorate(val.Interface(), d)
   193  	case reflect.Slice:
   194  		return objectDecorate(val.Interface(), d)
   195  	case reflect.Chan:
   196  	case reflect.Func:
   197  	case reflect.Pointer:
   198  		if !val.IsNil() {
   199  			v := val.Elem()
   200  			return objectDecorate(v.Interface(), d)
   201  		}
   202  	case reflect.Map:
   203  		return objectDecorate(val.Interface(), d)
   204  	case reflect.UnsafePointer:
   205  	default:
   206  	}
   207  	return ""
   208  }