Skip to content

Commit dfd910d

Browse files
sallyomclaude
andcommitted
Initial distributed tracing instrumentation
- Add OpenTelemetry distributed tracing support to kv-cache-manager - Instrument Redis operations with automatic OTel tracing and metrics Co-Authored-By: Claude <[email protected]>
1 parent 3bcc158 commit dfd910d

File tree

7 files changed

+291
-4
lines changed

7 files changed

+291
-4
lines changed

examples/kv_cache_index/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ func runPrompts(ctx context.Context, kvCacheIndexer *kvcache.Indexer) error {
132132
ModelName: modelName,
133133
ChunkHash: h,
134134
}
135-
}), []kvblock.PodEntry{{"pod1", "gpu"}})
135+
}), []kvblock.PodEntry{{PodIdentifier: "pod1", DeviceTier: "gpu"}})
136136

137137
// Sleep 3 secs
138138
time.Sleep(3 * time.Second)

go.mod

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,14 @@ require (
1111
github.com/pebbe/zmq4 v1.4.0
1212
github.com/prometheus/client_golang v1.22.0
1313
github.com/prometheus/client_model v0.6.1
14+
github.com/redis/go-redis/extra/redisotel/v9 v9.7.3
1415
github.com/redis/go-redis/v9 v9.7.3
1516
github.com/stretchr/testify v1.10.0
1617
github.com/vmihailenco/msgpack/v5 v5.4.1
18+
go.opentelemetry.io/otel v1.36.0
19+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0
20+
go.opentelemetry.io/otel/sdk v1.36.0
21+
go.opentelemetry.io/otel/trace v1.36.0
1722
k8s.io/apimachinery v0.33.0
1823
k8s.io/client-go v0.33.0
1924
k8s.io/klog/v2 v2.130.1
@@ -22,17 +27,20 @@ require (
2227

2328
require (
2429
github.com/beorn7/perks v1.0.1 // indirect
30+
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
2531
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
2632
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
2733
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
2834
github.com/go-logr/logr v1.4.2 // indirect
35+
github.com/go-logr/stdr v1.2.2 // indirect
2936
github.com/go-openapi/jsonpointer v0.21.0 // indirect
3037
github.com/go-openapi/jsonreference v0.20.2 // indirect
3138
github.com/go-openapi/swag v0.23.0 // indirect
3239
github.com/gogo/protobuf v1.3.2 // indirect
3340
github.com/google/gnostic-models v0.6.9 // indirect
3441
github.com/google/go-cmp v0.7.0 // indirect
3542
github.com/google/uuid v1.6.0 // indirect
43+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
3644
github.com/josharian/intern v1.0.0 // indirect
3745
github.com/json-iterator/go v1.1.12 // indirect
3846
github.com/mailru/easyjson v0.7.7 // indirect
@@ -43,15 +51,23 @@ require (
4351
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
4452
github.com/prometheus/common v0.62.0 // indirect
4553
github.com/prometheus/procfs v0.15.1 // indirect
54+
github.com/redis/go-redis/extra/rediscmd/v9 v9.7.3 // indirect
4655
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
4756
github.com/x448/float16 v0.8.4 // indirect
4857
github.com/yuin/gopher-lua v1.1.1 // indirect
58+
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
59+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect
60+
go.opentelemetry.io/otel/metric v1.36.0 // indirect
61+
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
4962
golang.org/x/net v0.38.0 // indirect
5063
golang.org/x/oauth2 v0.27.0 // indirect
51-
golang.org/x/sys v0.31.0 // indirect
64+
golang.org/x/sys v0.33.0 // indirect
5265
golang.org/x/term v0.30.0 // indirect
5366
golang.org/x/text v0.23.0 // indirect
5467
golang.org/x/time v0.9.0 // indirect
68+
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
69+
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
70+
google.golang.org/grpc v1.68.1 // indirect
5571
google.golang.org/protobuf v1.36.5 // indirect
5672
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
5773
gopkg.in/inf.v0 v0.9.1 // indirect

go.sum

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
66
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
77
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
88
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
9+
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
10+
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
911
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
1012
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
1113
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@@ -21,8 +23,11 @@ github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxER
2123
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
2224
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
2325
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
26+
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
2427
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
2528
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
29+
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
30+
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
2631
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
2732
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
2833
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
@@ -35,6 +40,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v
3540
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
3641
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
3742
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
43+
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
44+
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
3845
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
3946
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
4047
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
@@ -45,6 +52,8 @@ github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgY
4552
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
4653
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
4754
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
55+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
56+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
4857
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
4958
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
5059
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
@@ -88,6 +97,10 @@ github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ
8897
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
8998
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
9099
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
100+
github.com/redis/go-redis/extra/rediscmd/v9 v9.7.3 h1:1AXQZkJkFxGV3f78mSnUI70l0orO6FHnYoSmBos8SZM=
101+
github.com/redis/go-redis/extra/rediscmd/v9 v9.7.3/go.mod h1:OgkpkwJYex1oyVAabK+VhVUKhUXw8uZUfewJYH1wG90=
102+
github.com/redis/go-redis/extra/redisotel/v9 v9.7.3 h1:ICBA9xYh+SmZqMfBtjKpp1ohi/V5R1TEZglLZc8IxTc=
103+
github.com/redis/go-redis/extra/redisotel/v9 v9.7.3/go.mod h1:DMzxd0CDyZ9VFw9sEPIVpIgKTAaubfGuaPQSUaS7/fo=
91104
github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
92105
github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
93106
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
@@ -115,6 +128,22 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
115128
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
116129
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
117130
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
131+
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
132+
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
133+
go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
134+
go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
135+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA=
136+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI=
137+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM=
138+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA=
139+
go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
140+
go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
141+
go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
142+
go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
143+
go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
144+
go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
145+
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
146+
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
118147
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
119148
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
120149
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -136,8 +165,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
136165
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
137166
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
138167
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
139-
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
140-
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
168+
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
169+
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
141170
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
142171
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
143172
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -156,6 +185,12 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
156185
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
157186
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
158187
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
188+
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q=
189+
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
190+
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY=
191+
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
192+
google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0=
193+
google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw=
159194
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
160195
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
161196
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

pkg/kvcache/indexer.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ import (
2020
"context"
2121
"fmt"
2222

23+
"go.opentelemetry.io/otel/attribute"
2324
"k8s.io/apimachinery/pkg/util/sets"
2425
"k8s.io/klog/v2"
2526

2627
"github.com/llm-d/llm-d-kv-cache-manager/pkg/kvcache/kvblock"
2728
"github.com/llm-d/llm-d-kv-cache-manager/pkg/tokenization"
2829
"github.com/llm-d/llm-d-kv-cache-manager/pkg/tokenization/prefixstore"
30+
"github.com/llm-d/llm-d-kv-cache-manager/pkg/tracing"
2931
"github.com/llm-d/llm-d-kv-cache-manager/pkg/utils/logging"
3032
)
3133

@@ -117,36 +119,83 @@ func (k *Indexer) KVBlockIndex() kvblock.Index {
117119
func (k *Indexer) GetPodScores(ctx context.Context, prompt, modelName string,
118120
podIdentifiers []string,
119121
) (map[string]int, error) {
122+
ctx, span := tracing.StartSpan(ctx, "kv-cache-manager.GetPodScores", tracing.OperationGetPodScores)
123+
defer span.End()
124+
125+
span.SetAttributes(
126+
attribute.String(tracing.AttrGenAIRequestModel, modelName),
127+
attribute.Int(tracing.AttrKVCachePodCount, len(podIdentifiers)),
128+
)
129+
120130
traceLogger := klog.FromContext(ctx).V(logging.TRACE).WithName("kvcache.GetPodScores")
121131
// 0. add to tokenizers pool
122132
k.tokenizersPool.AddTask(prompt, modelName)
123133

124134
// 1. get available tokens of longest prefix
135+
ctx, findTokensSpan := tracing.StartSpan(ctx, "kv-cache-manager.FindTokens", tracing.OperationFindTokens)
125136
tokens := k.tokensIndexer.FindLongestContainedTokens(prompt, modelName)
126137
if len(tokens) == 0 {
138+
span.SetAttributes(
139+
attribute.Int(tracing.AttrKVCacheTokenCount, 0),
140+
attribute.String(tracing.AttrOperationOutcome, tracing.OutcomeSuccess),
141+
)
142+
tracing.SetSpanError(findTokensSpan, nil)
143+
findTokensSpan.End()
127144
//nolint:nilnil // no need to return an error
128145
return nil, nil
129146
}
147+
tracing.SetSpanError(findTokensSpan, nil)
148+
findTokensSpan.End()
149+
150+
// Set token count attribute
151+
span.SetAttributes(attribute.Int(tracing.AttrKVCacheTokenCount, len(tokens)))
130152

131153
// 2. get block keys
132154
blockKeys := k.tokensProcessor.TokensToKVBlockKeys(tokens, modelName)
133155
traceLogger.Info("found tokens", "tokens", tokens, "block-keys", blockKeys)
134156

157+
// Set block keys attribute
158+
span.SetAttributes(attribute.Int(tracing.AttrKVCacheBlockKeys, len(blockKeys)))
159+
135160
// 3. query kvblock indexer for pods
136161
keyToPods, err := k.kvBlockIndex.Lookup(ctx, blockKeys, sets.New(podIdentifiers...))
137162
if err != nil {
163+
tracing.SetSpanError(span, err)
138164
return nil, fmt.Errorf("failed to query kvblock indexer: %w", err)
139165
}
140166
traceLogger.Info("found block keys", "block-keys", blockKeys,
141167
"pods", podsPerKeyPrintHelper(keyToPods))
142168

143169
// 4. score pods
170+
_, scorePodSpan := tracing.StartSpan(ctx, "kv-cache-manager.ScorePods", tracing.OperationScorePods)
144171
podScores, err := k.kvBlockScorer.Score(blockKeys, keyToPods)
145172
if err != nil {
173+
tracing.SetSpanError(scorePodSpan, err)
174+
scorePodSpan.End()
175+
tracing.SetSpanError(span, err)
146176
return nil, fmt.Errorf("failed to query kvblock scorer: %w", err)
147177
}
178+
tracing.SetSpanError(scorePodSpan, nil)
179+
scorePodSpan.End()
148180
traceLogger.Info("found pod scores", "pod-scores", podScores)
149181

182+
// Calculate hit ratio for observability
183+
totalPods := len(podIdentifiers)
184+
if totalPods == 0 {
185+
// If no specific pods requested, use all pods with scores
186+
totalPods = len(podScores)
187+
}
188+
189+
var hitRatio float64
190+
if totalPods > 0 {
191+
hitRatio = float64(len(podScores)) / float64(totalPods)
192+
}
193+
194+
span.SetAttributes(
195+
attribute.Float64(tracing.AttrKVCacheHitRatio, hitRatio),
196+
attribute.String(tracing.AttrOperationOutcome, tracing.OutcomeSuccess),
197+
)
198+
150199
return podScores, nil
151200
}
152201

pkg/kvcache/kvblock/index.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ type IndexConfig struct {
4646
func DefaultIndexConfig() *IndexConfig {
4747
return &IndexConfig{
4848
InMemoryConfig: DefaultInMemoryIndexConfig(),
49+
RedisConfig: DefaultRedisIndexConfig(),
4950
EnableMetrics: false,
5051
}
5152
}

pkg/kvcache/kvblock/redis.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"strings"
2424
"time"
2525

26+
"github.com/redis/go-redis/extra/redisotel/v9"
2627
"github.com/redis/go-redis/v9"
2728
"k8s.io/apimachinery/pkg/util/sets"
2829
"k8s.io/klog/v2"
@@ -57,6 +58,17 @@ func NewRedisIndex(config *RedisIndexConfig) (Index, error) {
5758
}
5859

5960
redisClient := redis.NewClient(redisOpt)
61+
62+
// Enable automatic OpenTelemetry tracing for Redis operations
63+
if err := redisotel.InstrumentTracing(redisClient); err != nil {
64+
return nil, fmt.Errorf("failed to instrument Redis tracing: %w", err)
65+
}
66+
67+
// Enable automatic OpenTelemetry metrics for Redis operations
68+
if err := redisotel.InstrumentMetrics(redisClient); err != nil {
69+
return nil, fmt.Errorf("failed to instrument Redis metrics: %w", err)
70+
}
71+
6072
if err := redisClient.Ping(context.Background()).Err(); err != nil {
6173
return nil, fmt.Errorf("failed to connect to Redis: %w", err)
6274
}

0 commit comments

Comments
 (0)