git.frostfs.info/TrueCloudLab/frostfs-sdk-go@v0.0.0-20241022124111-5361f0ecebd3/pool/statistic.go (about) 1 package pool 2 3 import ( 4 "errors" 5 "sync" 6 "time" 7 ) 8 9 // Statistic is metrics of the pool. 10 type Statistic struct { 11 overallErrors uint64 12 nodes []NodeStatistic 13 currentNodes []string 14 } 15 16 // OverallErrors returns sum of errors on all connections. It doesn't decrease. 17 func (s Statistic) OverallErrors() uint64 { 18 return s.overallErrors 19 } 20 21 // Nodes returns list of nodes statistic. 22 func (s Statistic) Nodes() []NodeStatistic { 23 return s.nodes 24 } 25 26 // CurrentNodes returns list of nodes of inner pool that has at least one healthy node. 27 // These nodes have the same and the highest priority among the other healthy nodes. 28 func (s Statistic) CurrentNodes() []string { 29 return s.currentNodes 30 } 31 32 // ErrUnknownNode indicate that node with current address is not found in list. 33 var ErrUnknownNode = errors.New("unknown node") 34 35 // Node returns NodeStatistic by node address. 36 // If such node doesn't exist ErrUnknownNode error is returned. 37 func (s Statistic) Node(address string) (*NodeStatistic, error) { 38 for i := range s.nodes { 39 if s.nodes[i].address == address { 40 return &s.nodes[i], nil 41 } 42 } 43 44 return nil, ErrUnknownNode 45 } 46 47 // NodeStatistic is metrics of certain connections. 48 type NodeStatistic struct { 49 address string 50 methods []StatusSnapshot 51 overallErrors uint64 52 currentErrors uint32 53 } 54 55 // OverallErrors returns all errors on current node. 56 // This value never decreases. 57 func (n NodeStatistic) OverallErrors() uint64 { 58 return n.overallErrors 59 } 60 61 // CurrentErrors returns errors on current node. 62 // This value is always less than 'errorThreshold' from InitParameters. 63 func (n NodeStatistic) CurrentErrors() uint32 { 64 return n.currentErrors 65 } 66 67 // Requests returns number of requests. 68 func (n NodeStatistic) Requests() (requests uint64) { 69 for _, val := range n.methods { 70 requests += val.allRequests 71 } 72 return requests 73 } 74 75 // Address returns node endpoint address. 76 func (n NodeStatistic) Address() string { 77 return n.address 78 } 79 80 // AverageGetBalance returns average time to perform BalanceGet request. 81 func (n NodeStatistic) AverageGetBalance() time.Duration { 82 return n.averageTime(methodBalanceGet) 83 } 84 85 // AveragePutContainer returns average time to perform ContainerPut request. 86 func (n NodeStatistic) AveragePutContainer() time.Duration { 87 return n.averageTime(methodContainerPut) 88 } 89 90 // AverageGetContainer returns average time to perform ContainerGet request. 91 func (n NodeStatistic) AverageGetContainer() time.Duration { 92 return n.averageTime(methodContainerGet) 93 } 94 95 // AverageListContainer returns average time to perform ContainerList request. 96 func (n NodeStatistic) AverageListContainer() time.Duration { 97 return n.averageTime(methodContainerList) 98 } 99 100 // AverageDeleteContainer returns average time to perform ContainerDelete request. 101 func (n NodeStatistic) AverageDeleteContainer() time.Duration { 102 return n.averageTime(methodContainerDelete) 103 } 104 105 // AverageEndpointInfo returns average time to perform EndpointInfo request. 106 func (n NodeStatistic) AverageEndpointInfo() time.Duration { 107 return n.averageTime(methodEndpointInfo) 108 } 109 110 // AverageNetworkInfo returns average time to perform NetworkInfo request. 111 func (n NodeStatistic) AverageNetworkInfo() time.Duration { 112 return n.averageTime(methodNetworkInfo) 113 } 114 115 // AveragePutObject returns average time to perform ObjectPut request. 116 func (n NodeStatistic) AveragePutObject() time.Duration { 117 return n.averageTime(methodObjectPut) 118 } 119 120 // AverageDeleteObject returns average time to perform ObjectDelete request. 121 func (n NodeStatistic) AverageDeleteObject() time.Duration { 122 return n.averageTime(methodObjectDelete) 123 } 124 125 // AverageGetObject returns average time to perform ObjectGet request. 126 func (n NodeStatistic) AverageGetObject() time.Duration { 127 return n.averageTime(methodObjectGet) 128 } 129 130 // AverageHeadObject returns average time to perform ObjectHead request. 131 func (n NodeStatistic) AverageHeadObject() time.Duration { 132 return n.averageTime(methodObjectHead) 133 } 134 135 // AverageRangeObject returns average time to perform ObjectRange request. 136 func (n NodeStatistic) AverageRangeObject() time.Duration { 137 return n.averageTime(methodObjectRange) 138 } 139 140 // AverageCreateSession returns average time to perform SessionCreate request. 141 func (n NodeStatistic) AverageCreateSession() time.Duration { 142 return n.averageTime(methodSessionCreate) 143 } 144 145 func (n NodeStatistic) averageTime(method MethodIndex) time.Duration { 146 stat := n.methods[method] 147 if stat.allRequests == 0 { 148 return 0 149 } 150 return time.Duration(stat.allTime / stat.allRequests) 151 } 152 153 // MethodStatus provide statistic for specific method. 154 type MethodStatus struct { 155 name string 156 mu sync.RWMutex // protect counters 157 snapshot StatusSnapshot 158 } 159 160 func NewMethodStatus(name string) *MethodStatus { 161 return &MethodStatus{name: name} 162 } 163 164 func (m *MethodStatus) Snapshot() StatusSnapshot { 165 m.mu.RLock() 166 defer m.mu.RUnlock() 167 return m.snapshot 168 } 169 170 func (m *MethodStatus) IncRequests(elapsed time.Duration) { 171 m.mu.Lock() 172 defer m.mu.Unlock() 173 m.snapshot.allTime += uint64(elapsed) 174 m.snapshot.allRequests++ 175 } 176 177 func (m *MethodStatus) Reset() { 178 m.mu.Lock() 179 defer m.mu.Unlock() 180 m.snapshot.allTime = 0 181 m.snapshot.allRequests = 0 182 } 183 184 // StatusSnapshot is statistic for specific method. 185 type StatusSnapshot struct { 186 allTime uint64 187 allRequests uint64 188 } 189 190 func (s StatusSnapshot) AllRequests() uint64 { 191 return s.allRequests 192 } 193 194 func (s StatusSnapshot) AllTime() uint64 { 195 return s.allTime 196 }