mirror of
https://github.com/redis/go-redis.git
synced 2025-12-08 08:42:11 +03:00
Adds connection state metrics
Signed-off-by: Elena Kolevska <elena@kolevska.com>
This commit is contained in:
committed by
ofekshenawa
parent
d588c3ca71
commit
2a7725db63
@@ -21,8 +21,9 @@ const (
|
||||
// metricsRecorder implements the otel.Recorder interface
|
||||
type metricsRecorder struct {
|
||||
operationDuration metric.Float64Histogram
|
||||
connectionCount metric.Int64UpDownCounter
|
||||
|
||||
// Client configuration for attributes
|
||||
// Client configuration for attributes (used for operation metrics only)
|
||||
serverAddr string
|
||||
serverPort string
|
||||
dbIndex string
|
||||
@@ -267,3 +268,59 @@ func formatDBIndex(db int) string {
|
||||
}
|
||||
return strconv.Itoa(db)
|
||||
}
|
||||
|
||||
// RecordConnectionStateChange records a change in connection state
|
||||
// This is called from the pool when connections transition between states
|
||||
func (r *metricsRecorder) RecordConnectionStateChange(
|
||||
ctx context.Context,
|
||||
cn redis.ConnInfo,
|
||||
fromState, toState string,
|
||||
) {
|
||||
if r.connectionCount == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Extract server address from connection
|
||||
serverAddr, serverPort := extractServerInfo(cn)
|
||||
|
||||
// Build base attributes
|
||||
attrs := []attribute.KeyValue{
|
||||
attribute.String("db.system", "redis"),
|
||||
attribute.String("server.address", serverAddr),
|
||||
}
|
||||
|
||||
// Add server.port if not default
|
||||
if serverPort != "" && serverPort != "6379" {
|
||||
attrs = append(attrs, attribute.String("server.port", serverPort))
|
||||
}
|
||||
|
||||
// Decrement old state (if not empty)
|
||||
if fromState != "" {
|
||||
fromAttrs := append([]attribute.KeyValue{}, attrs...)
|
||||
fromAttrs = append(fromAttrs, attribute.String("state", fromState))
|
||||
r.connectionCount.Add(ctx, -1, metric.WithAttributes(fromAttrs...))
|
||||
}
|
||||
|
||||
// Increment new state
|
||||
if toState != "" {
|
||||
toAttrs := append([]attribute.KeyValue{}, attrs...)
|
||||
toAttrs = append(toAttrs, attribute.String("state", toState))
|
||||
r.connectionCount.Add(ctx, 1, metric.WithAttributes(toAttrs...))
|
||||
}
|
||||
}
|
||||
|
||||
// extractServerInfo extracts server address and port from connection info
|
||||
func extractServerInfo(cn redis.ConnInfo) (addr, port string) {
|
||||
if cn == nil {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
remoteAddr := cn.RemoteAddr()
|
||||
if remoteAddr == nil {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
addrStr := remoteAddr.String()
|
||||
host, portStr := parseAddr(addrStr)
|
||||
return host, portStr
|
||||
}
|
||||
|
||||
@@ -125,9 +125,20 @@ func initOnce(client redis.UniversalClient, opts ...Option) error {
|
||||
return fmt.Errorf("failed to create operation duration histogram: %w", err)
|
||||
}
|
||||
|
||||
// Create synchronous UpDownCounter for connection count
|
||||
connectionCount, err := meter.Int64UpDownCounter(
|
||||
"db.client.connection.count",
|
||||
metric.WithDescription("The number of connections that are currently in state described by the state attribute"),
|
||||
metric.WithUnit("{connection}"),
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create connection count metric: %w", err)
|
||||
}
|
||||
|
||||
// Create recorder
|
||||
recorder := &metricsRecorder{
|
||||
operationDuration: operationDuration,
|
||||
connectionCount: connectionCount,
|
||||
serverAddr: serverAddr,
|
||||
serverPort: serverPort,
|
||||
dbIndex: dbIndex,
|
||||
|
||||
Reference in New Issue
Block a user