mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2024-12-24 20:14:40 +02:00
specialize simplelru(span's lruMap) for attributes only (#328)
* copy of simplelru for attributes without excessive usage of interface{} This also make sure we only add attributes/links if isRecording. Move method to export the attributes list to attributeMap. * run make precommit to update mod files.
This commit is contained in:
parent
eb3b31e12d
commit
3495d74971
@ -95,8 +95,6 @@ github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
|
@ -118,9 +118,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmg
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
|
@ -93,8 +93,6 @@ github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
|
@ -103,8 +103,6 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
|
@ -92,8 +92,6 @@ github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
|
@ -105,8 +105,6 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
|
@ -117,9 +117,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmg
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
|
1
go.mod
1
go.mod
@ -13,7 +13,6 @@ require (
|
||||
github.com/google/go-cmp v0.3.1
|
||||
github.com/google/gofuzz v1.0.0 // indirect
|
||||
github.com/gostaticanalysis/analysisutil v0.0.3 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.3
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
|
||||
github.com/magiconair/properties v1.8.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.10 // indirect
|
||||
|
2
go.sum
2
go.sum
@ -132,8 +132,6 @@ github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
|
90
sdk/trace/attributesMap.go
Normal file
90
sdk/trace/attributesMap.go
Normal file
@ -0,0 +1,90 @@
|
||||
// Copyright 2019, OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package trace
|
||||
|
||||
import (
|
||||
"container/list"
|
||||
|
||||
"go.opentelemetry.io/otel/api/core"
|
||||
"go.opentelemetry.io/otel/sdk/export/trace"
|
||||
)
|
||||
|
||||
// attributesMap is a capped map of attributes, holding the most recent attributes.
|
||||
// Eviction is done via a LRU method, the oldest entry is removed to create room for a new entry.
|
||||
// Updates are allowed and refreshes the usage of the key.
|
||||
//
|
||||
// This is based from https://github.com/hashicorp/golang-lru/blob/master/simplelru/lru.go
|
||||
// With a subset of the its operations and specific for holding core.KeyValue
|
||||
type attributesMap struct {
|
||||
attributes map[core.Key]*list.Element
|
||||
evictList *list.List
|
||||
droppedCount int
|
||||
capacity int
|
||||
}
|
||||
|
||||
func newAttributesMap(capacity int) *attributesMap {
|
||||
lm := &attributesMap{
|
||||
attributes: make(map[core.Key]*list.Element),
|
||||
evictList: list.New(),
|
||||
capacity: capacity,
|
||||
}
|
||||
return lm
|
||||
}
|
||||
|
||||
func (am *attributesMap) add(kv core.KeyValue) {
|
||||
// Check for existing item
|
||||
if ent, ok := am.attributes[kv.Key]; ok {
|
||||
am.evictList.MoveToFront(ent)
|
||||
ent.Value = &kv
|
||||
return
|
||||
}
|
||||
|
||||
// Add new item
|
||||
entry := am.evictList.PushFront(&kv)
|
||||
am.attributes[kv.Key] = entry
|
||||
|
||||
// Verify size not exceeded
|
||||
if am.evictList.Len() > am.capacity {
|
||||
am.removeOldest()
|
||||
am.droppedCount++
|
||||
}
|
||||
}
|
||||
|
||||
func (am *attributesMap) toSpanData(sd *trace.SpanData) {
|
||||
len := am.evictList.Len()
|
||||
if len == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
attributes := make([]core.KeyValue, 0, len)
|
||||
for ent := am.evictList.Back(); ent != nil; ent = ent.Prev() {
|
||||
if value, ok := ent.Value.(*core.KeyValue); ok {
|
||||
attributes = append(attributes, *value)
|
||||
}
|
||||
}
|
||||
|
||||
sd.Attributes = attributes
|
||||
sd.DroppedAttributeCount = am.droppedCount
|
||||
}
|
||||
|
||||
// removeOldest removes the oldest item from the cache.
|
||||
func (am *attributesMap) removeOldest() {
|
||||
ent := am.evictList.Back()
|
||||
if ent != nil {
|
||||
am.evictList.Remove(ent)
|
||||
kv := ent.Value.(*core.KeyValue)
|
||||
delete(am.attributes, kv.Key)
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
// Copyright 2019, OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package trace
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/golang-lru/simplelru"
|
||||
)
|
||||
|
||||
type lruMap struct {
|
||||
simpleLruMap *simplelru.LRU
|
||||
droppedCount int
|
||||
}
|
||||
|
||||
func newLruMap(size int) *lruMap {
|
||||
lm := &lruMap{}
|
||||
lm.simpleLruMap, _ = simplelru.NewLRU(size, nil)
|
||||
return lm
|
||||
}
|
||||
|
||||
func (lm *lruMap) add(key, value interface{}) {
|
||||
evicted := lm.simpleLruMap.Add(key, value)
|
||||
if evicted {
|
||||
lm.droppedCount++
|
||||
}
|
||||
}
|
@ -38,9 +38,9 @@ type span struct {
|
||||
mu sync.Mutex // protects the contents of *data (but not the pointer value.)
|
||||
spanContext core.SpanContext
|
||||
|
||||
// lruAttributes are capped at configured limit. When the capacity is reached an oldest entry
|
||||
// attributes are capped at configured limit. When the capacity is reached an oldest entry
|
||||
// is removed to create room for a new entry.
|
||||
lruAttributes *lruMap
|
||||
attributes *attributesMap
|
||||
|
||||
// messageEvents are stored in FIFO queue capped by configured limit.
|
||||
messageEvents *evictedQueue
|
||||
@ -228,10 +228,9 @@ func (s *span) makeSpanData() *export.SpanData {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
sd = *s.data
|
||||
if s.lruAttributes.simpleLruMap.Len() > 0 {
|
||||
sd.Attributes = s.lruAttributesToAttributeMap()
|
||||
sd.DroppedAttributeCount = s.lruAttributes.droppedCount
|
||||
}
|
||||
|
||||
s.attributes.toSpanData(&sd)
|
||||
|
||||
if len(s.messageEvents.queue) > 0 {
|
||||
sd.MessageEvents = s.interfaceArrayToMessageEventArray()
|
||||
sd.DroppedMessageEventCount = s.messageEvents.droppedCount
|
||||
@ -259,24 +258,11 @@ func (s *span) interfaceArrayToMessageEventArray() []export.Event {
|
||||
return messageEventArr
|
||||
}
|
||||
|
||||
func (s *span) lruAttributesToAttributeMap() []core.KeyValue {
|
||||
attributes := make([]core.KeyValue, 0, s.lruAttributes.simpleLruMap.Len())
|
||||
for _, key := range s.lruAttributes.simpleLruMap.Keys() {
|
||||
value, ok := s.lruAttributes.simpleLruMap.Get(key)
|
||||
if ok {
|
||||
key := key.(core.Key)
|
||||
value := value.(core.Value)
|
||||
attributes = append(attributes, core.KeyValue{Key: key, Value: value})
|
||||
}
|
||||
}
|
||||
return attributes
|
||||
}
|
||||
|
||||
func (s *span) copyToCappedAttributes(attributes ...core.KeyValue) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
for _, a := range attributes {
|
||||
s.lruAttributes.add(a.Key, a.Value)
|
||||
s.attributes.add(a)
|
||||
}
|
||||
}
|
||||
|
||||
@ -328,7 +314,7 @@ func startSpanInternal(tr *tracer, name string, parent core.SpanContext, remoteP
|
||||
Name: name,
|
||||
HasRemoteParent: remoteParent,
|
||||
}
|
||||
span.lruAttributes = newLruMap(cfg.MaxAttributesPerSpan)
|
||||
span.attributes = newAttributesMap(cfg.MaxAttributesPerSpan)
|
||||
span.messageEvents = newEvictedQueue(cfg.MaxEventsPerSpan)
|
||||
span.links = newEvictedQueue(cfg.MaxLinksPerSpan)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user