-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[processor/tailsampling] Decision cache for "keep" trace IDs (#33533)
**Description:** Adds simple LRU decision cache for sampled trace IDs. The design makes it easy to add another cache for non-sampled IDs. It does not save any other information other than the trace ID that is sampled. It only holds the right half of the trace ID (as a uint64) in the cache. By default the cache remains no-op. Only when the user configures the cache size will the cache become active. **Link to tracking Issue:** #31583 **Testing:** * unit tests on new code * test in `processor_decision_test.go` to test that a trace that was sampled, cached, but the span data was dropped persists a "keep" decision. **Documentation:** Added description to README
- Loading branch information
1 parent
97ce47e
commit 18dc9ac
Showing
16 changed files
with
377 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
change_type: enhancement | ||
component: tailsamplingprocessor | ||
note: Simple LRU Decision Cache for "keep" decisions | ||
issues: [31583] | ||
subtext: | ||
change_logs: [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
processor/tailsamplingprocessor/internal/cache/lru_cache.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package cache // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor/internal/cache" | ||
|
||
import ( | ||
"encoding/binary" | ||
|
||
lru "github.com/hashicorp/golang-lru/v2" | ||
"go.opentelemetry.io/collector/pdata/pcommon" | ||
) | ||
|
||
// lruDecisionCache implements Cache as a simple LRU cache. | ||
// It holds trace IDs that had sampling decisions made on them. | ||
// It does not specify the type of sampling decision that was made, only that | ||
// a decision was made for an ID. You need separate DecisionCaches for caching | ||
// sampled and not sampled trace IDs. | ||
type lruDecisionCache[V any] struct { | ||
cache *lru.Cache[uint64, V] | ||
} | ||
|
||
var _ Cache[any] = (*lruDecisionCache[any])(nil) | ||
|
||
// NewLRUDecisionCache returns a new lruDecisionCache. | ||
// The size parameter indicates the amount of keys the cache will hold before it | ||
// starts evicting the least recently used key. | ||
func NewLRUDecisionCache[V any](size int) (Cache[V], error) { | ||
c, err := lru.New[uint64, V](size) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &lruDecisionCache[V]{cache: c}, nil | ||
} | ||
|
||
func (c *lruDecisionCache[V]) Get(id pcommon.TraceID) (V, bool) { | ||
return c.cache.Get(rightHalfTraceID(id)) | ||
} | ||
|
||
func (c *lruDecisionCache[V]) Put(id pcommon.TraceID, v V) { | ||
_ = c.cache.Add(rightHalfTraceID(id), v) | ||
} | ||
|
||
// Delete is no-op since LRU relies on least recently used key being evicting automatically | ||
func (c *lruDecisionCache[V]) Delete(_ pcommon.TraceID) {} | ||
|
||
func rightHalfTraceID(id pcommon.TraceID) uint64 { | ||
return binary.LittleEndian.Uint64(id[8:]) | ||
} |
83 changes: 83 additions & 0 deletions
83
processor/tailsamplingprocessor/internal/cache/lru_cache_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package cache | ||
|
||
import ( | ||
"encoding/hex" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
"go.opentelemetry.io/collector/pdata/pcommon" | ||
) | ||
|
||
func TestSinglePut(t *testing.T) { | ||
c, err := NewLRUDecisionCache[int](2) | ||
require.NoError(t, err) | ||
id, err := traceIDFromHex("12341234123412341234123412341234") | ||
require.NoError(t, err) | ||
c.Put(id, 123) | ||
v, ok := c.Get(id) | ||
assert.Equal(t, 123, v) | ||
assert.True(t, ok) | ||
} | ||
|
||
func TestExceedsSizeLimit(t *testing.T) { | ||
c, err := NewLRUDecisionCache[bool](2) | ||
require.NoError(t, err) | ||
id1, err := traceIDFromHex("12341234123412341234123412341231") | ||
require.NoError(t, err) | ||
id2, err := traceIDFromHex("12341234123412341234123412341232") | ||
require.NoError(t, err) | ||
id3, err := traceIDFromHex("12341234123412341234123412341233") | ||
require.NoError(t, err) | ||
|
||
c.Put(id1, true) | ||
c.Put(id2, true) | ||
c.Put(id3, true) | ||
|
||
v, ok := c.Get(id1) | ||
assert.False(t, v) // evicted | ||
assert.False(t, ok) // evicted | ||
v, ok = c.Get(id2) | ||
assert.True(t, v) | ||
assert.True(t, ok) | ||
v, ok = c.Get(id3) | ||
assert.True(t, v) | ||
assert.True(t, ok) | ||
} | ||
|
||
func TestLeastRecentlyUsedIsEvicted(t *testing.T) { | ||
c, err := NewLRUDecisionCache[bool](2) | ||
require.NoError(t, err) | ||
id1, err := traceIDFromHex("12341234123412341234123412341231") | ||
require.NoError(t, err) | ||
id2, err := traceIDFromHex("12341234123412341234123412341232") | ||
require.NoError(t, err) | ||
id3, err := traceIDFromHex("12341234123412341234123412341233") | ||
require.NoError(t, err) | ||
|
||
c.Put(id1, true) | ||
c.Put(id2, true) | ||
v, ok := c.Get(id1) // use id1 | ||
assert.True(t, true, v) | ||
assert.True(t, true, ok) | ||
c.Put(id3, true) | ||
|
||
v, ok = c.Get(id1) | ||
assert.True(t, v) | ||
assert.True(t, ok) | ||
v, ok = c.Get(id2) | ||
assert.False(t, v) // evicted, returns zero-value | ||
assert.False(t, ok) // evicted, not OK | ||
v, ok = c.Get(id3) | ||
assert.True(t, v) | ||
assert.True(t, ok) | ||
} | ||
|
||
func traceIDFromHex(idStr string) (pcommon.TraceID, error) { | ||
id := pcommon.NewTraceIDEmpty() | ||
_, err := hex.Decode(id[:], []byte(idStr)) | ||
return id, err | ||
} |
24 changes: 24 additions & 0 deletions
24
processor/tailsamplingprocessor/internal/cache/nop_cache.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package cache // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor/internal/cache" | ||
|
||
import "go.opentelemetry.io/collector/pdata/pcommon" | ||
|
||
type nopDecisionCache[V any] struct{} | ||
|
||
var _ Cache[any] = (*nopDecisionCache[any])(nil) | ||
|
||
func NewNopDecisionCache[V any]() Cache[V] { | ||
return &nopDecisionCache[V]{} | ||
} | ||
|
||
func (n *nopDecisionCache[V]) Get(_ pcommon.TraceID) (V, bool) { | ||
var v V | ||
return v, false | ||
} | ||
|
||
func (n *nopDecisionCache[V]) Put(_ pcommon.TraceID, _ V) { | ||
} | ||
|
||
func (n *nopDecisionCache[V]) Delete(_ pcommon.TraceID) {} |
21 changes: 21 additions & 0 deletions
21
processor/tailsamplingprocessor/internal/cache/nop_cache_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package cache | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestNopCache(t *testing.T) { | ||
c := NewNopDecisionCache[bool]() | ||
id, err := traceIDFromHex("12341234123412341234123412341234") | ||
require.NoError(t, err) | ||
c.Put(id, true) | ||
v, ok := c.Get(id) | ||
assert.False(t, v) | ||
assert.False(t, ok) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package cache // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/tailsamplingprocessor/internal/cache" | ||
|
||
import "go.opentelemetry.io/collector/pdata/pcommon" | ||
|
||
// Cache is a cache using a pcommon.TraceID as the key and any generic type as the value. | ||
type Cache[V any] interface { | ||
// Get returns the value for the given id, and a boolean to indicate whether the key was found. | ||
// If the key is not present, the zero value is returned. | ||
Get(id pcommon.TraceID) (V, bool) | ||
// Put sets the value for a given id | ||
Put(id pcommon.TraceID, v V) | ||
// Delete deletes the value for the given id | ||
Delete(id pcommon.TraceID) | ||
} |
33 changes: 20 additions & 13 deletions
33
processor/tailsamplingprocessor/internal/metadata/generated_telemetry.go
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.