forked from movio/bramble
-
Notifications
You must be signed in to change notification settings - Fork 0
/
instrumentation.go
81 lines (68 loc) · 1.69 KB
/
instrumentation.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
package bramble
import (
"context"
"sync"
"time"
log "github.com/sirupsen/logrus"
)
const eventKey contextKey = "instrumentation"
type event struct {
name string
timestamp time.Time
fields EventFields
fieldLock sync.Mutex
writeLock sync.Once
}
// EventFields contains fields to be logged for the event
type EventFields map[string]interface{}
func newEvent(name string) *event {
return &event{
name: name,
timestamp: time.Now(),
fields: EventFields{},
}
}
func startEvent(ctx context.Context, name string) (context.Context, *event) {
ev := newEvent(name)
return context.WithValue(ctx, eventKey, ev), ev
}
func (e *event) addField(name string, value interface{}) {
e.fieldLock.Lock()
e.fields[name] = value
e.fieldLock.Unlock()
}
func (e *event) addFields(fields EventFields) {
e.fieldLock.Lock()
for k, v := range fields {
e.fields[k] = v
}
e.fieldLock.Unlock()
}
func (e *event) finish() {
e.writeLock.Do(func() {
log.WithFields(log.Fields{
"timestamp": e.timestamp.Format(time.RFC3339Nano),
"duration": time.Since(e.timestamp).String(),
}).WithFields(log.Fields(e.fields)).Info(e.name)
})
}
// AddField adds the given field to the event contained in the context (if any)
func AddField(ctx context.Context, name string, value interface{}) {
if e := getEvent(ctx); e != nil {
e.addField(name, value)
}
}
// AddFields adds the given fields to the event contained in the context (if any)
func AddFields(ctx context.Context, fields EventFields) {
if e := getEvent(ctx); e != nil {
e.addFields(fields)
}
}
func getEvent(ctx context.Context) *event {
if e := ctx.Value(eventKey); e != nil {
if e, ok := e.(*event); ok {
return e
}
}
return nil
}