Valkey
Instrument Valkey clients in Go applications with automatic command tracing using valkey-go and valkeyotel
Use the valkey-go client with its built-in OpenTelemetry instrumentation (valkeyotel) to trace every Valkey command automatically. Each command produces a span with the command name, key, and server address.
Prerequisites
- Go 1.22 or higher
- Valkey server running
- Last9 account with OTLP credentials
Installation
-
Install the Last9 Go Agent and valkey-go
go get github.com/last9/go-agentgo get github.com/valkey-io/valkey-go -
Set Environment Variables
export OTEL_SERVICE_NAME="your-service"export OTEL_EXPORTER_OTLP_ENDPOINT="$last9_otlp_endpoint"export OTEL_EXPORTER_OTLP_HEADERS="Authorization=$last9_otlp_auth_header"export OTEL_TRACES_SAMPLER="always_on"export OTEL_RESOURCE_ATTRIBUTES="deployment.environment=production" -
Create an instrumented Valkey client
package mainimport ("context""log""github.com/last9/go-agent""github.com/valkey-io/valkey-go""github.com/valkey-io/valkey-go/valkeyotel")func main() {if err := agent.Start(); err != nil {log.Fatalf("failed to start agent: %v", err)}defer agent.Shutdown()client, err := valkey.NewClient(valkey.ClientOption{InitAddress: []string{"localhost:6379"},})if err != nil {log.Fatalf("failed to create valkey client: %v", err)}defer client.Close()// Wrap with OTel instrumentation — every command is now tracedtracedClient := valkeyotel.NewClient(client)ctx := context.Background()// Commands are traced automaticallyif err := tracedClient.Do(ctx, tracedClient.B().Set().Key("hello").Value("world").Ex(60).Build()).Error(); err != nil {log.Printf("set failed: %v", err)}val, err := tracedClient.Do(ctx, tracedClient.B().Get().Key("hello").Build()).ToString()if err != nil {log.Printf("get failed: %v", err)}log.Println("got:", val)}
Using with Gin
Pass c.Request.Context() into every Valkey command so the command span is parented to the incoming HTTP request span:
package main
import ( "log" "net/http"
"github.com/gin-gonic/gin" "github.com/last9/go-agent" ginagent "github.com/last9/go-agent/instrumentation/gin" "github.com/valkey-io/valkey-go" "github.com/valkey-io/valkey-go/valkeyotel")
var tracedClient valkey.Client
func main() { if err := agent.Start(); err != nil { log.Fatalf("failed to start agent: %v", err) } defer agent.Shutdown()
client, err := valkey.NewClient(valkey.ClientOption{ InitAddress: []string{"localhost:6379"}, }) if err != nil { log.Fatalf("failed to create valkey client: %v", err) } defer client.Close()
tracedClient = valkeyotel.NewClient(client)
r := ginagent.Default() r.GET("/cache/:key", getCacheHandler) log.Fatal(r.Run(":8080"))}
func getCacheHandler(c *gin.Context) { // Pass c.Request.Context() so this span is a child of the HTTP span val, err := tracedClient.Do(c.Request.Context(), tracedClient.B().Get().Key(c.Param("key")).Build(), ).ToString() if err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "not found"}) return } c.JSON(http.StatusOK, gin.H{"value": val})}What Gets Traced Automatically
| Attribute | Example |
|---|---|
db.system | valkey |
db.operation | GET, SET, HGET |
net.peer.name | localhost |
net.peer.port | 6379 |
View Traces
Navigate to Trace Explorer in Last9. Filter by db.system = valkey to see all Valkey commands.
Troubleshooting
Please get in touch with us on Discord or Email if you have any questions.