mirror of
https://github.com/hanzokv/go.git
synced 2026-09-24 00:31:51 +00:00
* First draft. One metric - command duration. Signed-off-by: Elena Kolevska <[email protected]> * Adds connection state metrics Signed-off-by: Elena Kolevska <[email protected]> * wip Signed-off-by: Elena Kolevska <[email protected]> * Add phase 1 metrics * Add client api configurations * remove redundent code * refactor: move otel-metrics example to separate module * refactor: move otel-metrics example to separate module * remove internal test * Resolve merge conflicts with upstream/master * Fix linting issues * Fix pool idle connection counter bug * Add OTel performance benchmarking suite * Improve perf compatison script * Add phase 2,3 metrics * Remove local benchmark tests * Add new fields to tests * Change db.client.connection.count and db.client.connection.pending_request metric type from UpAndDownCounter to Async gauge. * fix golangci lint * Add piplined commands metrics support * Redesign otel init method * Address comments * Fix golangci-lint errors * Fix passing nil pointer * Add metric prefix to callbacks and atomic batch registration * Add unique name for pool.name attr * Fix unique pool name for pubsub * Refactor all hardcoded OTel attribute strings to use constants * Refactor all hardcoded OTel attribute strings to use constants * extract metric names and pool names as constants, improve error handling --------- Signed-off-by: Elena Kolevska <[email protected]> Co-authored-by: Elena Kolevska <[email protected]>
124 lines
3.2 KiB
Go
124 lines
3.2 KiB
Go
// EXAMPLE: otel_metrics
|
|
// HIDE_START
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"math/rand"
|
|
"strconv"
|
|
"sync"
|
|
"time"
|
|
|
|
redisotel "github.com/redis/go-redis/extra/redisotel-native/v9"
|
|
"github.com/redis/go-redis/v9"
|
|
"go.opentelemetry.io/otel"
|
|
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
|
|
"go.opentelemetry.io/otel/sdk/metric"
|
|
)
|
|
|
|
// ExampleClient_otel_metrics demonstrates how to enable OpenTelemetry metrics
|
|
// for Redis operations and export them to an OTLP collector.
|
|
func main() {
|
|
ctx := context.Background()
|
|
|
|
// HIDE_END
|
|
|
|
// STEP_START otel_exporter_setup
|
|
// Create OTLP exporter that sends metrics to the collector
|
|
// Default endpoint is localhost:4317 (gRPC)
|
|
exporter, err := otlpmetricgrpc.New(ctx,
|
|
otlpmetricgrpc.WithInsecure(), // Use insecure for local development
|
|
// For production, configure TLS and authentication:
|
|
// otlpmetricgrpc.WithEndpoint("your-collector:4317"),
|
|
// otlpmetricgrpc.WithTLSCredentials(...),
|
|
)
|
|
if err != nil {
|
|
log.Fatalf("Failed to create OTLP exporter: %v", err)
|
|
}
|
|
// STEP_END
|
|
|
|
// STEP_START otel_meter_provider
|
|
// Create meter provider with periodic reader
|
|
// Metrics are exported every 10 seconds
|
|
meterProvider := metric.NewMeterProvider(
|
|
metric.WithReader(
|
|
metric.NewPeriodicReader(exporter,
|
|
metric.WithInterval(10*time.Second),
|
|
),
|
|
),
|
|
)
|
|
defer func() {
|
|
if err := meterProvider.Shutdown(ctx); err != nil {
|
|
log.Printf("Error shutting down meter provider: %v", err)
|
|
}
|
|
}()
|
|
|
|
// Set the global meter provider
|
|
otel.SetMeterProvider(meterProvider)
|
|
// STEP_END
|
|
|
|
// STEP_START redis_client_setup
|
|
// Initialize OTel instrumentation BEFORE creating Redis clients
|
|
otelInstance := redisotel.GetObservabilityInstance()
|
|
config := redisotel.NewConfig().WithEnabled(true)
|
|
if err := otelInstance.Init(config); err != nil {
|
|
log.Fatalf("Failed to initialize OTel: %v", err)
|
|
}
|
|
defer otelInstance.Shutdown()
|
|
|
|
// Create Redis client - automatically instrumented
|
|
rdb := redis.NewClient(&redis.Options{
|
|
Addr: "localhost:6379",
|
|
})
|
|
defer rdb.Close()
|
|
// STEP_END
|
|
|
|
// STEP_START redis_operations
|
|
// Execute Redis operations - metrics are automatically collected
|
|
log.Println("Executing Redis operations...")
|
|
var wg sync.WaitGroup
|
|
wg.Add(50)
|
|
for i := range 50 {
|
|
go func(i int) {
|
|
defer wg.Done()
|
|
|
|
for j := range 10 {
|
|
if err := rdb.Set(ctx, "key"+strconv.Itoa(i*10+j), "value", 0).Err(); err != nil {
|
|
log.Printf("Error setting key: %v", err)
|
|
}
|
|
time.Sleep(time.Millisecond * time.Duration(rand.Intn(400)))
|
|
}
|
|
}(i)
|
|
}
|
|
wg.Wait()
|
|
|
|
wg.Add(10)
|
|
for i := range 10 {
|
|
go func(i int) {
|
|
defer wg.Done()
|
|
|
|
for j := range 10 {
|
|
if err := rdb.Set(ctx, "key"+strconv.Itoa(i*10+j), "value", 0).Err(); err != nil {
|
|
log.Printf("Error setting key: %v", err)
|
|
}
|
|
time.Sleep(time.Millisecond * time.Duration(rand.Intn(400)))
|
|
}
|
|
}(i)
|
|
}
|
|
wg.Wait()
|
|
|
|
for j := range 10 {
|
|
if err := rdb.Set(ctx, "key"+strconv.Itoa(j), "value", 0).Err(); err != nil {
|
|
log.Printf("Error setting key: %v", err)
|
|
}
|
|
time.Sleep(time.Millisecond * time.Duration(rand.Intn(400)))
|
|
}
|
|
|
|
log.Println("Operations complete. Waiting for metrics to be exported...")
|
|
|
|
// Wait for metrics to be exported
|
|
time.Sleep(15 * time.Second)
|
|
// STEP_END
|
|
}
|