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  }