Skip to content

Commit ed80cc0

Browse files
committed
conflicts
Signed-off-by: Manik2708 <[email protected]>
1 parent 92246c5 commit ed80cc0

File tree

10 files changed

+591
-116
lines changed

10 files changed

+591
-116
lines changed

cmd/jaeger/internal/integration/badger_test.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ func TestBadgerStorage(t *testing.T) {
1616
ConfigFile: "../../config-badger.yaml",
1717
StorageIntegration: integration.StorageIntegration{
1818
CleanUp: purge,
19-
20-
// TODO: remove this once badger supports returning spanKind from GetOperations
21-
// Cf https://github.com/jaegertracing/jaeger/issues/1922
22-
GetOperationsMissingSpanKind: true,
2319
},
2420
}
2521
s.e2eInitialize(t, "badger")

internal/storage/v1/badger/factory.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515

1616
"github.com/dgraph-io/badger/v4"
1717
"github.com/spf13/viper"
18+
"go.opentelemetry.io/collector/featuregate"
1819
"go.uber.org/zap"
1920

2021
depStore "github.com/jaegertracing/jaeger/internal/storage/v1/badger/dependencystore"
@@ -38,11 +39,19 @@ const (
3839
)
3940

4041
var ( // interface comformance checks
41-
_ storage.Factory = (*Factory)(nil)
42-
_ io.Closer = (*Factory)(nil)
43-
_ plugin.Configurable = (*Factory)(nil)
44-
_ storage.Purger = (*Factory)(nil)
45-
_ storage.SamplingStoreFactory = (*Factory)(nil)
42+
_ storage.Factory = (*Factory)(nil)
43+
_ io.Closer = (*Factory)(nil)
44+
_ plugin.Configurable = (*Factory)(nil)
45+
_ storage.Purger = (*Factory)(nil)
46+
_ storage.SamplingStoreFactory = (*Factory)(nil)
47+
includeDualLookUp = featuregate.GlobalRegistry().MustRegister(
48+
"jaeger.badger.dualLookUp",
49+
featuregate.StageBeta, // enabed by default
50+
featuregate.WithRegisterFromVersion("v2.2.0"),
51+
featuregate.WithRegisterToVersion("v2.5.0"),
52+
featuregate.WithRegisterDescription("Allows reader to look up for traces from old index key"),
53+
featuregate.WithRegisterReferenceURL("https://github.com/jaegertracing/jaeger/pull/6376"),
54+
)
4655
)
4756

4857
// Factory implements storage.Factory for Badger backend.
@@ -146,7 +155,7 @@ func (f *Factory) Initialize(metricsFactory metrics.Factory, logger *zap.Logger)
146155
}
147156
f.store = store
148157

149-
f.cache = badgerStore.NewCacheStore(f.store, f.Config.TTL.Spans)
158+
f.cache = badgerStore.NewCacheStore(f.Config.TTL.Spans)
150159

151160
f.metrics.ValueLogSpaceAvailable = metricsFactory.Gauge(metrics.Options{Name: valueLogSpaceAvailableName})
152161
f.metrics.KeyLogSpaceAvailable = metricsFactory.Gauge(metrics.Options{Name: keyLogSpaceAvailableName})
@@ -172,7 +181,7 @@ func initializeDir(path string) {
172181

173182
// CreateSpanReader implements storage.Factory
174183
func (f *Factory) CreateSpanReader() (spanstore.Reader, error) {
175-
tr := badgerStore.NewTraceReader(f.store, f.cache, true)
184+
tr := badgerStore.NewTraceReader(f.store, f.cache, true, includeDualLookUp.IsEnabled())
176185
return spanstoremetrics.NewReaderDecorator(tr, f.metricsFactory), nil
177186
}
178187

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright (c) 2025 The Jaeger Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package spanstore
5+
6+
import (
7+
"context"
8+
"math/rand"
9+
"testing"
10+
"time"
11+
12+
"github.com/dgraph-io/badger/v4"
13+
"github.com/stretchr/testify/assert"
14+
"github.com/stretchr/testify/require"
15+
16+
"github.com/jaegertracing/jaeger-idl/model/v1"
17+
"github.com/jaegertracing/jaeger/storage/spanstore"
18+
)
19+
20+
// This test is for checking the backward compatibility after changing the index.
21+
// Once dual lookup is completely removed, this test can be removed
22+
func TestBackwardCompatibility(t *testing.T) {
23+
runWithBadger(t, func(store *badger.DB, t *testing.T) {
24+
startT := time.Now()
25+
tid := startT
26+
cache := NewCacheStore(1 * time.Hour)
27+
reader := NewTraceReader(store, cache, true, true)
28+
writer := NewSpanWriter(store, cache, 1*time.Hour)
29+
oldSpan := model.Span{
30+
TraceID: model.TraceID{
31+
Low: 0,
32+
High: 1,
33+
},
34+
SpanID: model.SpanID(rand.Uint64()),
35+
OperationName: "operation-1",
36+
Process: &model.Process{
37+
ServiceName: "service",
38+
},
39+
StartTime: tid,
40+
Duration: time.Duration(time.Duration(1) * time.Millisecond),
41+
}
42+
err := writer.writeSpan(&oldSpan, true)
43+
require.NoError(t, err)
44+
traces, err := reader.FindTraces(context.Background(), &spanstore.TraceQueryParameters{
45+
ServiceName: "service",
46+
OperationName: "operation-1",
47+
StartTimeMin: startT,
48+
StartTimeMax: startT.Add(time.Duration(time.Millisecond * 10)),
49+
})
50+
require.NoError(t, err)
51+
assert.Len(t, traces, 1)
52+
assert.Len(t, traces[0].Spans, 1)
53+
assert.Equal(t, oldSpan.TraceID, traces[0].Spans[0].TraceID)
54+
assert.Equal(t, oldSpan.SpanID, traces[0].Spans[0].SpanID)
55+
})
56+
}

internal/storage/v1/badger/spanstore/cache.go

Lines changed: 55 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,37 @@ import (
88
"sync"
99
"time"
1010

11-
"github.com/dgraph-io/badger/v4"
12-
11+
"github.com/jaegertracing/jaeger-idl/model/v1"
1312
"github.com/jaegertracing/jaeger/storage/spanstore"
1413
)
1514

1615
// CacheStore saves expensive calculations from the K/V store
1716
type CacheStore struct {
1817
// Given the small amount of data these will store, we use the same structure as the memory store
19-
cacheLock sync.Mutex // write heavy - Mutex is faster than RWMutex for writes
20-
services map[string]uint64
21-
operations map[string]map[string]uint64
18+
cacheLock sync.Mutex // write heavy - Mutex is faster than RWMutex for writes
19+
services map[string]uint64
20+
// This map is for the hierarchy: service name, kind and operation name.
21+
// Each service contains the span kinds, and then operation names belonging to that kind.
22+
// This structure will look like:
23+
/*
24+
"service1":{
25+
SpanKind.unspecified: {
26+
"operation1": uint64
27+
}
28+
}
29+
*/
30+
// The uint64 value is the expiry time of operation
31+
operations map[string]map[model.SpanKind]map[string]uint64
2232

23-
store *badger.DB
24-
ttl time.Duration
33+
ttl time.Duration
2534
}
2635

2736
// NewCacheStore returns initialized CacheStore for badger use
28-
func NewCacheStore(db *badger.DB, ttl time.Duration) *CacheStore {
37+
func NewCacheStore(ttl time.Duration) *CacheStore {
2938
cs := &CacheStore{
3039
services: make(map[string]uint64),
31-
operations: make(map[string]map[string]uint64),
40+
operations: make(map[string]map[model.SpanKind]map[string]uint64),
3241
ttl: ttl,
33-
store: db,
3442
}
3543
return cs
3644
}
@@ -48,67 +56,73 @@ func (c *CacheStore) AddService(service string, keyTTL uint64) {
4856
}
4957

5058
// AddOperation adds the cache with operation names with most updated expiration time
51-
func (c *CacheStore) AddOperation(service, operation string, keyTTL uint64) {
59+
func (c *CacheStore) AddOperation(service, operation string, kind model.SpanKind, keyTTL uint64) {
5260
c.cacheLock.Lock()
5361
defer c.cacheLock.Unlock()
5462
if _, found := c.operations[service]; !found {
55-
c.operations[service] = make(map[string]uint64)
63+
c.operations[service] = make(map[model.SpanKind]map[string]uint64)
5664
}
57-
if v, found := c.operations[service][operation]; found {
65+
if _, found := c.operations[service][kind]; !found {
66+
c.operations[service][kind] = make(map[string]uint64)
67+
}
68+
if v, found := c.operations[service][kind][operation]; found {
5869
if v > keyTTL {
5970
return
6071
}
6172
}
62-
c.operations[service][operation] = keyTTL
73+
c.operations[service][kind][operation] = keyTTL
6374
}
6475

6576
// Update caches the results of service and service + operation indexes and maintains their TTL
66-
func (c *CacheStore) Update(service, operation string, expireTime uint64) {
77+
func (c *CacheStore) Update(service, operation string, kind model.SpanKind, expireTime uint64) {
6778
c.cacheLock.Lock()
6879

6980
c.services[service] = expireTime
70-
if _, ok := c.operations[service]; !ok {
71-
c.operations[service] = make(map[string]uint64)
81+
if _, found := c.operations[service]; !found {
82+
c.operations[service] = make(map[model.SpanKind]map[string]uint64)
83+
}
84+
if _, found := c.operations[service][kind]; !found {
85+
c.operations[service][kind] = make(map[string]uint64)
7286
}
73-
c.operations[service][operation] = expireTime
87+
c.operations[service][kind][operation] = expireTime
7488
c.cacheLock.Unlock()
7589
}
7690

7791
// GetOperations returns all operations for a specific service & spanKind traced by Jaeger
78-
func (c *CacheStore) GetOperations(service string) ([]spanstore.Operation, error) {
79-
operations := make([]string, 0, len(c.services))
92+
func (c *CacheStore) GetOperations(service string, kind string) ([]spanstore.Operation, error) {
93+
operations := make([]spanstore.Operation, 0, len(c.services))
8094
//nolint: gosec // G115
81-
t := uint64(time.Now().Unix())
95+
currentTime := uint64(time.Now().Unix())
8296
c.cacheLock.Lock()
8397
defer c.cacheLock.Unlock()
84-
85-
if v, ok := c.services[service]; ok {
86-
if v < t {
98+
if expiryTimeOfService, ok := c.services[service]; ok {
99+
if expiryTimeOfService < currentTime {
87100
// Expired, remove
88101
delete(c.services, service)
89102
delete(c.operations, service)
90103
return []spanstore.Operation{}, nil // empty slice rather than nil
91104
}
92-
for o, e := range c.operations[service] {
93-
if e > t {
94-
operations = append(operations, o)
95-
} else {
96-
delete(c.operations[service], o)
105+
for sKind := range c.operations[service] {
106+
if kind != "" && kind != string(sKind) {
107+
continue
108+
}
109+
for o, expiryTimeOfOperation := range c.operations[service][sKind] {
110+
if expiryTimeOfOperation > currentTime {
111+
op := spanstore.Operation{Name: o, SpanKind: string(sKind)}
112+
operations = append(operations, op)
113+
} else {
114+
delete(c.operations[service][sKind], o)
115+
}
116+
sort.Slice(operations, func(i, j int) bool {
117+
if operations[i].SpanKind == operations[j].SpanKind {
118+
return operations[i].Name < operations[j].Name
119+
}
120+
return operations[i].SpanKind < operations[j].SpanKind
121+
})
97122
}
98123
}
99124
}
100-
101-
sort.Strings(operations)
102-
103-
// TODO: https://github.com/jaegertracing/jaeger/issues/1922
104-
// - return the operations with actual spanKind
105-
result := make([]spanstore.Operation, 0, len(operations))
106-
for _, op := range operations {
107-
result = append(result, spanstore.Operation{
108-
Name: op,
109-
})
110-
}
111-
return result, nil
125+
return operations, nil
112126
}
113127

114128
// GetServices returns all services traced by Jaeger

0 commit comments

Comments
 (0)