-
Notifications
You must be signed in to change notification settings - Fork 0
/
logger_json.go
85 lines (73 loc) · 1.87 KB
/
logger_json.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package dglogger
import (
jsoniter "github.com/json-iterator/go"
"github.com/modern-go/reflect2"
"reflect"
"unsafe"
)
var jsonLogger jsoniter.API
func init() {
jsonLogger = jsoniter.Config{
EscapeHTML: true,
SortMapKeys: true,
ValidateJsonRawMessage: true,
}.Froze()
strValEncoder := jsonLogger.EncoderOf(reflect2.TypeOf(""))
jsonLogger.RegisterExtension(&secretEncoderExtension{
strValueEncoder: strValEncoder,
})
}
func Json(value any) ([]byte, error) {
return jsonLogger.Marshal(value)
}
type secretEncoderExtension struct {
jsoniter.EncoderExtension
strValueEncoder jsoniter.ValEncoder
}
type secretValEncoder struct {
strValueEncoder jsoniter.ValEncoder
typ reflect.Type
}
func (sve *secretValEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return false
}
func (sve *secretValEncoder) Encode(ptr unsafe.Pointer, stream *jsoniter.Stream) {
newObj := reflect.NewAt(sve.typ, ptr)
var iface interface{}
isPointer := false
if sve.typ.Kind() == reflect.Pointer {
iface = newObj.Elem().Interface()
isPointer = true
} else {
iface = newObj.Elem().Addr().Interface()
}
secret := iface.(SecretString)
isNilValue := reflect.ValueOf(secret).IsNil()
if isPointer && isNilValue {
stream.WriteNil()
return
}
strValue := ""
if !isNilValue {
strValue = secret.Secret()
}
sve.strValueEncoder.Encode(unsafe.Pointer(&strValue), stream)
}
func (se *secretEncoderExtension) CreateEncoder(typ reflect2.Type) jsoniter.ValEncoder {
typ1 := typ.Type1()
if typ1.Implements(SecretStringType) {
return &secretValEncoder{
strValueEncoder: se.strValueEncoder,
typ: typ1,
}
}
if typ1.Kind() == reflect.Pointer {
if reflect.PtrTo(typ1).Implements(SecretStringType) {
return &secretValEncoder{
strValueEncoder: se.strValueEncoder,
typ: typ1,
}
}
}
return se.EncoderExtension.CreateEncoder(typ)
}