-
Notifications
You must be signed in to change notification settings - Fork 378
/
private_field.go
128 lines (99 loc) · 2.23 KB
/
private_field.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package logutil
import (
crand "crypto/rand"
"crypto/sha256"
"encoding/hex"
"fmt"
"sync"
"go.uber.org/zap"
)
var (
global *PrivateField
mu sync.RWMutex
)
type PrivateField struct {
Namespace []byte
Enabled bool
}
func (p *PrivateField) hash(value string) string {
hash := sha256.New()
if _, err := hash.Write(p.Namespace); err != nil {
return "unrepresentable"
}
if _, err := hash.Write([]byte(value)); err != nil {
return "unrepresentable"
}
hashed := hash.Sum(nil)
return hex.EncodeToString(hashed)
}
func (p *PrivateField) PrivateString(key string, value string) zap.Field {
if p.Enabled {
return zap.String(key, p.hash(value))
}
return zap.String(key, value)
}
func (p *PrivateField) PrivateStrings(key string, values []string) zap.Field {
if p.Enabled {
strings := make([]string, len(values))
for i := range values {
strings[i] = p.hash(values[i])
}
return zap.Strings(key, strings)
}
return zap.Strings(key, values)
}
func (p *PrivateField) PrivateAny(key string, value interface{}) zap.Field {
if p.Enabled {
return zap.String(key, p.hash(fmt.Sprintf("%+v", value)))
}
return zap.Any(key, value)
}
func (p *PrivateField) PrivateBinary(key string, value []byte) zap.Field {
if p.Enabled {
return zap.String(key, p.hash(hex.EncodeToString(value)))
}
return zap.Binary(key, value)
}
func PrivateStrings(key string, value []string) zap.Field {
mu.RLock()
g := global
mu.RUnlock()
return g.PrivateStrings(key, value)
}
func PrivateString(key string, value string) zap.Field {
mu.RLock()
g := global
mu.RUnlock()
return g.PrivateString(key, value)
}
func PrivateAny(key string, value interface{}) zap.Field {
mu.RLock()
g := global
mu.RUnlock()
return g.PrivateAny(key, value)
}
func PrivateBinary(key string, value []byte) zap.Field {
mu.RLock()
g := global
mu.RUnlock()
return g.PrivateBinary(key, value)
}
func SetGlobal(namespace []byte, enabled bool) {
mu.Lock()
global = &PrivateField{
Enabled: enabled,
Namespace: namespace,
}
mu.Unlock()
}
func DisablePrivateFields() {
SetGlobal(nil, false)
}
func init() { // nolint:gochecknoinits
namespace := make([]byte, 32)
_, err := crand.Reader.Read(namespace)
if err != nil {
panic(err)
}
SetGlobal(namespace, true)
}