github.com/ydb-platform/ydb-go-sdk/v3@v3.89.2/metrics/driver.go (about) 1 package metrics 2 3 import ( 4 "strconv" 5 "sync" 6 7 "github.com/ydb-platform/ydb-go-sdk/v3/internal/repeater" 8 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors" 9 "github.com/ydb-platform/ydb-go-sdk/v3/trace" 10 ) 11 12 // driver makes driver with New publishing 13 // 14 //nolint:funlen 15 func driver(config Config) (t trace.Driver) { 16 config = config.WithSystem("driver") 17 endpoints := config.WithSystem("balancer").GaugeVec("endpoints", "az") 18 balancersDiscoveries := config.WithSystem("balancer").CounterVec("discoveries", "status", "cause") 19 balancerUpdates := config.WithSystem("balancer").CounterVec("updates", "cause") 20 conns := config.GaugeVec("conns", "endpoint", "node_id") 21 banned := config.WithSystem("conn").GaugeVec("banned", "endpoint", "node_id", "cause") 22 requestStatuses := config.WithSystem("conn").CounterVec("request_statuses", "status", "endpoint", "node_id") 23 requestMethods := config.WithSystem("conn").CounterVec("request_methods", "method", "endpoint", "node_id") 24 tli := config.CounterVec("transaction_locks_invalidated") 25 26 type endpointKey struct { 27 az string 28 } 29 knownEndpoints := make(map[endpointKey]struct{}) 30 endpointsMu := sync.RWMutex{} 31 32 t.OnConnInvoke = func(info trace.DriverConnInvokeStartInfo) func(trace.DriverConnInvokeDoneInfo) { 33 var ( 34 method = info.Method 35 endpoint = info.Endpoint.Address() 36 nodeID = info.Endpoint.NodeID() 37 ) 38 39 return func(info trace.DriverConnInvokeDoneInfo) { 40 if config.Details()&trace.DriverConnEvents != 0 { 41 requestStatuses.With(map[string]string{ 42 "status": errorBrief(info.Error), 43 "endpoint": endpoint, 44 "node_id": strconv.FormatUint(uint64(nodeID), 10), 45 }).Inc() 46 requestMethods.With(map[string]string{ 47 "method": string(method), 48 "endpoint": endpoint, 49 "node_id": strconv.FormatUint(uint64(nodeID), 10), 50 }).Inc() 51 if xerrors.IsOperationErrorTransactionLocksInvalidated(info.Error) { 52 tli.With(nil).Inc() 53 } 54 } 55 } 56 } 57 t.OnConnNewStream = func(info trace.DriverConnNewStreamStartInfo) func( 58 trace.DriverConnNewStreamDoneInfo, 59 ) { 60 var ( 61 method = info.Method 62 endpoint = info.Endpoint.Address() 63 nodeID = info.Endpoint.NodeID() 64 ) 65 66 return func(info trace.DriverConnNewStreamDoneInfo) { 67 if config.Details()&trace.DriverConnStreamEvents != 0 { 68 requestStatuses.With(map[string]string{ 69 "status": errorBrief(info.Error), 70 "endpoint": endpoint, 71 "node_id": strconv.FormatUint(uint64(nodeID), 10), 72 }).Inc() 73 requestMethods.With(map[string]string{ 74 "method": string(method), 75 "endpoint": endpoint, 76 "node_id": strconv.FormatUint(uint64(nodeID), 10), 77 }).Inc() 78 } 79 } 80 } 81 t.OnConnBan = func(info trace.DriverConnBanStartInfo) func(trace.DriverConnBanDoneInfo) { 82 if config.Details()&trace.DriverConnEvents != 0 { 83 banned.With(map[string]string{ 84 "endpoint": info.Endpoint.Address(), 85 "node_id": idToString(info.Endpoint.NodeID()), 86 "cause": errorBrief(info.Cause), 87 }).Add(1) 88 } 89 90 return nil 91 } 92 t.OnBalancerClusterDiscoveryAttempt = func(info trace.DriverBalancerClusterDiscoveryAttemptStartInfo) func( 93 trace.DriverBalancerClusterDiscoveryAttemptDoneInfo, 94 ) { 95 eventType := repeater.EventType(*info.Context) 96 97 return func(info trace.DriverBalancerClusterDiscoveryAttemptDoneInfo) { 98 if config.Details()&trace.DriverBalancerEvents != 0 { 99 balancersDiscoveries.With(map[string]string{ 100 "status": errorBrief(info.Error), 101 "cause": eventType, 102 }).Inc() 103 } 104 } 105 } 106 t.OnBalancerUpdate = func(info trace.DriverBalancerUpdateStartInfo) func(trace.DriverBalancerUpdateDoneInfo) { 107 eventType := repeater.EventType(*info.Context) 108 109 return func(info trace.DriverBalancerUpdateDoneInfo) { 110 if config.Details()&trace.DriverBalancerEvents != 0 { 111 endpointsMu.Lock() 112 defer endpointsMu.Unlock() 113 balancerUpdates.With(map[string]string{ 114 "cause": eventType, 115 }).Inc() 116 newEndpoints := make(map[endpointKey]int, len(info.Endpoints)) 117 for _, e := range info.Endpoints { 118 e := endpointKey{ 119 az: e.Location(), 120 } 121 newEndpoints[e]++ 122 } 123 for e := range knownEndpoints { 124 if _, has := newEndpoints[e]; !has { 125 delete(knownEndpoints, e) 126 endpoints.With(map[string]string{ 127 "az": e.az, 128 }).Set(0) 129 } 130 } 131 for e, count := range newEndpoints { 132 knownEndpoints[e] = struct{}{} 133 endpoints.With(map[string]string{ 134 "az": e.az, 135 }).Set(float64(count)) 136 } 137 } 138 } 139 } 140 t.OnConnDial = func(info trace.DriverConnDialStartInfo) func(trace.DriverConnDialDoneInfo) { 141 endpoint := info.Endpoint.Address() 142 nodeID := info.Endpoint.NodeID() 143 144 return func(info trace.DriverConnDialDoneInfo) { 145 if config.Details()&trace.DriverConnEvents != 0 { 146 if info.Error == nil { 147 conns.With(map[string]string{ 148 "endpoint": endpoint, 149 "node_id": idToString(nodeID), 150 }).Add(1) 151 } 152 } 153 } 154 } 155 t.OnConnClose = func(info trace.DriverConnCloseStartInfo) func(trace.DriverConnCloseDoneInfo) { 156 if config.Details()&trace.DriverConnEvents != 0 { 157 conns.With(map[string]string{ 158 "endpoint": info.Endpoint.Address(), 159 "node_id": idToString(info.Endpoint.NodeID()), 160 }).Add(-1) 161 } 162 163 return nil 164 } 165 166 return t 167 }