-
Notifications
You must be signed in to change notification settings - Fork 0
/
logredact.go
88 lines (72 loc) · 1.86 KB
/
logredact.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
86
87
88
package logredact
import (
"reflect"
"strings"
"github.com/sirupsen/logrus"
)
type LogRedact struct {
secrets []string
replacer string
}
func New(secrets []string, replacer string) *LogRedact {
return &LogRedact{secrets: secrets, replacer: replacer}
}
func (h *LogRedact) Levels() []logrus.Level {
return logrus.AllLevels
}
func (h *LogRedact) Fire(entry *logrus.Entry) error {
entry.Message = h.replaceSecrets(entry.Message)
for key, value := range entry.Data {
entry.Data[key] = h.processValue(reflect.ValueOf(value))
}
return nil
}
func (h *LogRedact) processValue(v reflect.Value) interface{} {
if !v.IsValid() {
return nil
}
switch v.Kind() {
case reflect.String:
return h.replaceSecrets(v.String())
case reflect.Ptr:
if v.IsNil() {
return nil
}
elem := v.Elem()
newElem := reflect.New(elem.Type())
h.processValueRecursively(elem, newElem.Elem())
return newElem.Interface()
case reflect.Struct:
newStruct := reflect.New(v.Type()).Elem()
h.processValueRecursively(v, newStruct)
return newStruct.Interface()
case reflect.Slice:
newSlice := reflect.MakeSlice(v.Type(), v.Len(), v.Len())
for i := 0; i < v.Len(); i++ {
newSlice.Index(i).Set(reflect.ValueOf(h.processValue(v.Index(i))))
}
return newSlice.Interface()
case reflect.Map:
newMap := reflect.MakeMap(v.Type())
iter := v.MapRange()
for iter.Next() {
k := iter.Key()
v := iter.Value()
newV := h.processValue(v)
newMap.SetMapIndex(k, reflect.ValueOf(newV))
}
return newMap.Interface()
}
return v.Interface()
}
func (h *LogRedact) processValueRecursively(src, dest reflect.Value) {
for i := 0; i < src.NumField(); i++ {
dest.Field(i).Set(reflect.ValueOf(h.processValue(src.Field(i))))
}
}
func (h *LogRedact) replaceSecrets(s string) string {
for _, secret := range h.secrets {
s = strings.Replace(s, secret, h.replacer, -1)
}
return s
}