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  }