diff --git a/go/vt/vtgate/scatter_conn.go b/go/vt/vtgate/scatter_conn.go index 8b571f7b67d..3be0f608ed2 100644 --- a/go/vt/vtgate/scatter_conn.go +++ b/go/vt/vtgate/scatter_conn.go @@ -72,9 +72,29 @@ type shardActionFunc func(rs *srvtopo.ResolvedShard, i int) error // the results and errors for the caller. type shardActionTransactionFunc func(rs *srvtopo.ResolvedShard, i int, shardActionInfo *shardActionInfo) (*shardActionInfo, error) +var ( + vttabletTimings = stats.NewMultiTimings( + "VttabletCall", + "Scatter connection timings", + []string{"Operation", "Keyspace", "ShardName", "DbType"}) + tabletCallErrorCount = stats.NewCountersWithMultiLabels( + "VttabletCallErrorCount", + "Error count from tablet calls in scatter conns", + []string{"Operation", "Keyspace", "ShardName", "DbType"}) +) + // NewScatterConn creates a new ScatterConn. func NewScatterConn(statsName string, txConn *TxConn, gw *TabletGateway) *ScatterConn { // this only works with TabletGateway + if statsName == "VttabletCall" { + return &ScatterConn{ + timings: vttabletTimings, + tabletCallErrorCount: tabletCallErrorCount, + txConn: txConn, + gateway: gw, + } + } + tabletCallErrorCountStatsName := "" if statsName != "" { tabletCallErrorCountStatsName = statsName + "ErrorCount" @@ -91,6 +111,7 @@ func NewScatterConn(statsName string, txConn *TxConn, gw *TabletGateway) *Scatte txConn: txConn, gateway: gw, } + } func (stc *ScatterConn) startAction(name string, target *querypb.Target) (time.Time, []string) { diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index 7d28c0e9697..b6ba241ec3c 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -216,6 +216,23 @@ var ( []string{"Operation", "Keyspace", "DbType"}) ) +func ClearMetrics() { + vschemaCounters.ResetAll() + errorCounts.ResetAll() + warnings.ResetAll() + vstreamSkewDelayCount.Reset() + vindexUnknownParams.Reset() + timings.Reset() + rowsReturned.ResetAll() + rowsAffected.ResetAll() + queriesProcessed.ResetAll() + queriesRouted.ResetAll() + queriesProcessedByTable.ResetAll() + queriesRoutedByTable.ResetAll() + vttabletTimings.Reset() + tabletCallErrorCount.ResetAll() +} + // VTGate is the rpc interface to vtgate. Only one instance // can be created. It implements vtgateservice.VTGateService // VTGate exposes multiple generations of interfaces. @@ -377,6 +394,7 @@ func Init( }) vtgateInst.registerDebugHealthHandler() vtgateInst.registerDebugEnvHandler() + vtgateInst.registerClearMetrics() initAPI(gw.hc) return vtgateInst @@ -441,6 +459,14 @@ func (vtg *VTGate) registerDebugHealthHandler() { }) } +func (vtg *VTGate) registerClearMetrics() { + servenv.HTTPHandleFunc("/clear/metrics", func(w http.ResponseWriter, r *http.Request) { + ClearMetrics() + log.Infof("vtgate metrics have been cleared.") + w.Write([]byte("vtgate metrics have been cleared.")) + }) +} + // IsHealthy returns nil if server is healthy. // Otherwise, it returns an error indicating the reason. func (vtg *VTGate) IsHealthy() error {