-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcontext.go
More file actions
68 lines (55 loc) · 1.6 KB
/
Copy pathcontext.go
File metadata and controls
68 lines (55 loc) · 1.6 KB
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
package logger
import "context"
type contextKey struct{}
type ctxFields struct {
b []byte
}
// WithContext returns a new context carrying the given fields.
// Any fields previously attached via WithContext are preserved;
// the new fields are appended after them. Any fields already
// added to the logger are not attached to the context.
//
// If the logger discards output or no fields are given, ctx is returned
// unchanged.
func WithContext(ctx context.Context, log *Logger, fields ...Field) context.Context {
if log.isDiscard || len(fields) == 0 {
return ctx
}
e := newEvent(log.fmtr)
defer putEvent(e)
if existing, _ := ctx.Value(contextKey{}).(*ctxFields); existing != nil {
e.buf.Write(existing.b)
}
for _, field := range fields {
field(e)
}
b := make([]byte, e.buf.Len())
copy(b, e.buf.Bytes())
return context.WithValue(ctx, contextKey{}, &ctxFields{b: b})
}
// FromContext returns a new Logger extended with any fields attached to ctx
// via WithContext. The context fields appear after the logger's own pre-rendered
// fields (set via With) and before per-call fields.
//
// If the logger discards output or ctx carries no fields, the receiver is
// returned unchanged.
func (l *Logger) FromContext(ctx context.Context) *Logger {
if l.isDiscard {
return l
}
fields, ok := ctx.Value(contextKey{}).(*ctxFields)
if !ok || len(fields.b) == 0 {
return l
}
b := make([]byte, len(l.ctx)+len(fields.b))
copy(b, l.ctx)
copy(b[len(l.ctx):], fields.b)
return &Logger{
w: l.w,
isDiscard: l.isDiscard,
fmtr: l.fmtr,
timeFn: l.timeFn,
lvl: l.lvl,
ctx: b,
}
}