-
Notifications
You must be signed in to change notification settings - Fork 45
/
label.go
77 lines (62 loc) · 1.67 KB
/
label.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
package zapdriver
import (
"strings"
"sync"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
const labelsKey = "logging.googleapis.com/labels"
// Label adds an optional label to the payload.
//
// Labels are a set of user-defined (key, value) data that provides additional
// information about the log entry.
//
// Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.
func Label(key, value string) zap.Field {
return zap.String("labels."+key, value)
}
// Labels takes Zap fields, filters the ones that have their key start with the
// string `labels.` and their value type set to StringType. It then wraps those
// key/value pairs in a top-level `labels` namespace.
func Labels(fields ...zap.Field) zap.Field {
lbls := newLabels()
lbls.mutex.Lock()
for i := range fields {
if isLabelField(fields[i]) {
lbls.store[strings.Replace(fields[i].Key, "labels.", "", 1)] = fields[i].String
}
}
lbls.mutex.Unlock()
return labelsField(lbls)
}
func isLabelField(field zap.Field) bool {
return strings.HasPrefix(field.Key, "labels.") && field.Type == zapcore.StringType
}
func labelsField(l *labels) zap.Field {
return zap.Object(labelsKey, l)
}
type labels struct {
store map[string]string
mutex *sync.RWMutex
}
func newLabels() *labels {
return &labels{store: map[string]string{}, mutex: &sync.RWMutex{}}
}
func (l *labels) Add(key, value string) {
l.mutex.Lock()
l.store[key] = value
l.mutex.Unlock()
}
func (l *labels) reset() {
l.mutex.Lock()
l.store = map[string]string{}
l.mutex.Unlock()
}
func (l labels) MarshalLogObject(enc zapcore.ObjectEncoder) error {
l.mutex.RLock()
for k, v := range l.store {
enc.AddString(k, v)
}
l.mutex.RUnlock()
return nil
}