forked from ipfs/kubo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
log.go
140 lines (115 loc) · 3.93 KB
/
log.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
129
130
131
132
133
134
135
136
137
138
139
140
package eventlog
import (
"fmt"
"time"
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
"github.com/ipfs/go-ipfs/util" // TODO remove IPFS dependency
)
// StandardLogger provides API compatibility with standard printf loggers
// eg. go-logging
type StandardLogger interface {
Critical(args ...interface{})
Criticalf(format string, args ...interface{})
Debug(args ...interface{})
Debugf(format string, args ...interface{})
Error(args ...interface{})
Errorf(format string, args ...interface{})
Fatal(args ...interface{})
Fatalf(format string, args ...interface{})
Info(args ...interface{})
Infof(format string, args ...interface{})
Notice(args ...interface{})
Noticef(format string, args ...interface{})
Panic(args ...interface{})
Panicf(format string, args ...interface{})
Warning(args ...interface{})
Warningf(format string, args ...interface{})
}
// EventLogger extends the StandardLogger interface to allow for log items
// containing structured metadata
type EventLogger interface {
StandardLogger
// Event merges structured data from the provided inputs into a single
// machine-readable log event.
//
// If the context contains metadata, a copy of this is used as the base
// metadata accumulator.
//
// If one or more loggable objects are provided, these are deep-merged into base blob.
//
// Next, the event name is added to the blob under the key "event". If
// the key "event" already exists, it will be over-written.
//
// Finally the timestamp and package name are added to the accumulator and
// the metadata is logged.
Event(ctx context.Context, event string, m ...Loggable)
EventBegin(ctx context.Context, event string, m ...Loggable) *EventInProgress
}
// Logger retrieves an event logger by name
func Logger(system string) EventLogger {
// TODO if we would like to adjust log levels at run-time. Store this event
// logger in a map (just like the util.Logger impl)
return &eventLogger{system: system, StandardLogger: util.Logger(system)}
}
// eventLogger implements the EventLogger and wraps a go-logging Logger
type eventLogger struct {
StandardLogger
system string
// TODO add log-level
}
func (el *eventLogger) EventBegin(ctx context.Context, event string, metadata ...Loggable) *EventInProgress {
start := time.Now()
el.Event(ctx, fmt.Sprintf("%sBegin", event), metadata...)
eip := &EventInProgress{}
eip.doneFunc = func(additional []Loggable) {
metadata = append(metadata, additional...) // anything added during the operation
metadata = append(metadata, LoggableMap(map[string]interface{}{ // finally, duration of event
"duration": time.Now().Sub(start),
}))
el.Event(ctx, event, metadata...)
}
return eip
}
func (el *eventLogger) Event(ctx context.Context, event string, metadata ...Loggable) {
// Collect loggables for later logging
var loggables []Loggable
// get any existing metadata from the context
existing, err := MetadataFromContext(ctx)
if err != nil {
existing = Metadata{}
}
loggables = append(loggables, existing)
for _, datum := range metadata {
loggables = append(loggables, datum)
}
e := entry{
loggables: loggables,
system: el.system,
event: event,
}
e.Log() // TODO replace this when leveled-logs have been implemented
}
type EventInProgress struct {
loggables []Loggable
doneFunc func([]Loggable)
}
// Append adds loggables to be included in the call to Done
func (eip *EventInProgress) Append(l Loggable) {
eip.loggables = append(eip.loggables, l)
}
// SetError includes the provided error
func (eip *EventInProgress) SetError(err error) {
eip.loggables = append(eip.loggables, LoggableMap{
"error": err.Error(),
})
}
// Done creates a new Event entry that includes the duration and appended
// loggables.
func (eip *EventInProgress) Done() {
eip.doneFunc(eip.loggables) // create final event with extra data
}
// Close is an alias for done
func (eip *EventInProgress) Close() error {
eip.Done()
return nil
}