-
Notifications
You must be signed in to change notification settings - Fork 583
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
otelzap: Use pool for encoder #5719
Changes from 11 commits
7e9fa35
0b69a51
ea2f69b
aa469d2
1aa6bf0
8db2a5e
d0c73eb
5584bc6
04edfe5
eacc943
c480950
d064339
7eea197
3dc1d31
c6ab05d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -6,13 +6,47 @@ package otelzap // import "go.opentelemetry.io/contrib/bridges/otelzap" | |||||||
import ( | ||||||||
"fmt" | ||||||||
"reflect" | ||||||||
"sync" | ||||||||
"time" | ||||||||
|
||||||||
"go.uber.org/zap/zapcore" | ||||||||
|
||||||||
"go.opentelemetry.io/otel/log" | ||||||||
) | ||||||||
|
||||||||
var arrayEncoderPool = sync.Pool{ | ||||||||
New: func() interface{} { | ||||||||
// Similar to console_encoder which uses capacity of 2 | ||||||||
return &arrayEncoder{elems: make([]log.Value, 0, 2)} | ||||||||
}, | ||||||||
} | ||||||||
|
||||||||
func getArrayEncoder() (arr *arrayEncoder, free func()) { | ||||||||
arr = arrayEncoderPool.Get().(*arrayEncoder) | ||||||||
return arr, func() { | ||||||||
arr.elems = arr.elems[:0] | ||||||||
arrayEncoderPool.Put(arr) | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
var objectEncoderPool = sync.Pool{ | ||||||||
New: func() interface{} { | ||||||||
// Similar to console_encoder which uses capacity of 2 | ||||||||
return newObjectEncoder(2) | ||||||||
}, | ||||||||
} | ||||||||
|
||||||||
func getObjectEncoder() (obj *objectEncoder, free func()) { | ||||||||
obj = objectEncoderPool.Get().(*objectEncoder) | ||||||||
return obj, func() { | ||||||||
obj.root.attrs = obj.root.attrs[:0] | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add this comment? opentelemetry-go-contrib/bridges/otelslog/handler.go Lines 352 to 354 in c80e464
|
||||||||
obj.root.name = "" | ||||||||
obj.root.next = nil | ||||||||
obj.cur = obj.root | ||||||||
objectEncoderPool.Put(obj) | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
var ( | ||||||||
_ zapcore.ObjectEncoder = (*objectEncoder)(nil) | ||||||||
_ zapcore.ArrayEncoder = (*arrayEncoder)(nil) | ||||||||
|
@@ -55,16 +89,16 @@ func (m *objectEncoder) calculate(o *namespace) { | |||||||
} | ||||||||
|
||||||||
func (m *objectEncoder) AddArray(key string, v zapcore.ArrayMarshaler) error { | ||||||||
// TODO: Use arrayEncoder from a pool. | ||||||||
arr := &arrayEncoder{} | ||||||||
arr, free := getArrayEncoder() | ||||||||
defer free() | ||||||||
err := v.MarshalLogArray(arr) | ||||||||
m.cur.attrs = append(m.cur.attrs, log.Slice(key, arr.elems...)) | ||||||||
return err | ||||||||
} | ||||||||
|
||||||||
func (m *objectEncoder) AddObject(k string, v zapcore.ObjectMarshaler) error { | ||||||||
// TODO: Use objectEncoder from a pool. | ||||||||
newobj := newObjectEncoder(2) | ||||||||
newobj, free := getObjectEncoder() | ||||||||
defer free() | ||||||||
err := v.MarshalLogObject(newobj) | ||||||||
newobj.calculate(newobj.root) | ||||||||
m.cur.attrs = append(m.cur.attrs, log.Map(k, newobj.root.attrs...)) | ||||||||
|
@@ -196,15 +230,13 @@ type arrayEncoder struct { | |||||||
} | ||||||||
|
||||||||
func (a *arrayEncoder) AppendArray(v zapcore.ArrayMarshaler) error { | ||||||||
// TODO: Use arrayEncoder from a pool. | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What benchmark was used to see this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At quick glance, I think that the issue is caused by the fact that in array encoder
which causes to reuse the same underlying array. The next
before the logs are emitted I suggest not using the pooled encoder for I think (hope) that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the same problem with using shared memory applies for Probably we miss some unit test that would detect it. |
||||||||
arr := &arrayEncoder{} | ||||||||
err := v.MarshalLogArray(arr) | ||||||||
a.elems = append(a.elems, log.SliceValue(arr.elems...)) | ||||||||
return err | ||||||||
} | ||||||||
|
||||||||
func (a *arrayEncoder) AppendObject(v zapcore.ObjectMarshaler) error { | ||||||||
// TODO: Use objectEncoder from a pool. | ||||||||
m := newObjectEncoder(2) | ||||||||
err := v.MarshalLogObject(m) | ||||||||
m.calculate(m.root) | ||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add this comment?
opentelemetry-go-contrib/bridges/otelslog/handler.go
Lines 352 to 354 in c80e464