diff --git a/pkg/server/telemetry/features.go b/pkg/server/telemetry/features.go index e2d891106bfb..cefdff349502 100644 --- a/pkg/server/telemetry/features.go +++ b/pkg/server/telemetry/features.go @@ -18,6 +18,8 @@ import ( "fmt" "sync/atomic" + "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" + "github.com/cockroachdb/cockroach/pkg/util/log" "github.com/cockroachdb/cockroach/pkg/util/syncutil" ) @@ -123,3 +125,36 @@ func GetAndResetFeatureCounts(quantize bool) map[string]int32 { } return m } + +// RecordError takes an error and increments the corresponding count +// for its error code, and, if it is an unimplemented or internal +// error, the count for that feature or the internal error's shortened +// stack trace. +func RecordError(err error) { + if err == nil { + return + } + + if pgErr, ok := pgerror.GetPGCause(err); ok { + Count("errorcodes." + pgErr.Code) + + if details := pgErr.InternalCommand; details != "" { + var prefix string + switch pgErr.Code { + case pgerror.CodeFeatureNotSupportedError: + prefix = "unimplemented." + case pgerror.CodeInternalError: + prefix = "internalerror." + default: + prefix = "othererror." + pgErr.Code + "." + } + Count(prefix + details) + } + } else { + typ := log.ErrorSource(err) + if typ == "" { + typ = "unknown" + } + Count("othererror." + typ) + } +} diff --git a/pkg/sql/conn_executor.go b/pkg/sql/conn_executor.go index cd98a869beb9..64915ef2795d 100644 --- a/pkg/sql/conn_executor.go +++ b/pkg/sql/conn_executor.go @@ -302,39 +302,6 @@ func (s *Server) Start(ctx context.Context, stopper *stop.Stopper) { s.PeriodicallyClearStmtStats(ctx, stopper) } -// recordError takes an error and increments the corresponding count -// for its error code, and, if it is an unimplemented or internal -// error, the count for that feature or the internal error's shortened -// stack trace. -func (s *Server) recordError(err error) { - if err == nil { - return - } - - if pgErr, ok := pgerror.GetPGCause(err); ok { - telemetry.Count("errorcodes." + pgErr.Code) - - if details := pgErr.InternalCommand; details != "" { - var prefix string - switch pgErr.Code { - case pgerror.CodeFeatureNotSupportedError: - prefix = "unimplemented." - case pgerror.CodeInternalError: - prefix = "internalerror." - default: - prefix = "othererror." + pgErr.Code + "." - } - telemetry.Count(prefix + details) - } - } else { - typ := log.ErrorSource(err) - if typ == "" { - typ = "unknown" - } - telemetry.Count("othererror." + typ) - } -} - // ResetStatementStats resets the executor's collected statement statistics. func (s *Server) ResetStatementStats(ctx context.Context) { s.sqlStats.resetStats(ctx) @@ -1292,12 +1259,12 @@ func (ex *connExecutor) run( ex.sessionEventf(ex.Ctx(), "execution error: %s", pe.errorCause()) } if resErr == nil && ok { - ex.server.recordError(pe.errorCause()) + telemetry.RecordError(pe.errorCause()) // Depending on whether the result has the error already or not, we have // to call either Close or CloseWithErr. res.CloseWithErr(pe.errorCause()) } else { - ex.server.recordError(resErr) + telemetry.RecordError(resErr) res.Close(stateToTxnStatusIndicator(ex.machine.CurState())) } } else { diff --git a/pkg/sql/conn_executor_exec.go b/pkg/sql/conn_executor_exec.go index 8c5b3220907f..08318c114775 100644 --- a/pkg/sql/conn_executor_exec.go +++ b/pkg/sql/conn_executor_exec.go @@ -26,6 +26,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/base" "github.com/cockroachdb/cockroach/pkg/internal/client" "github.com/cockroachdb/cockroach/pkg/roachpb" + "github.com/cockroachdb/cockroach/pkg/server/telemetry" "github.com/cockroachdb/cockroach/pkg/sql/coltypes" "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" @@ -1207,7 +1208,7 @@ func (ex *connExecutor) runShowSyntax( commErr = res.AddRow(ctx, tree.Datums{tree.NewDString(field), tree.NewDString(msg)}) return nil }, - ex.server.recordError, /* reportErr */ + telemetry.RecordError, /* reportErr */ ); err != nil { res.SetError(err) } diff --git a/pkg/sql/pgwire/command_result.go b/pkg/sql/pgwire/command_result.go index 990a928fb4cb..e0474cbb6700 100644 --- a/pkg/sql/pgwire/command_result.go +++ b/pkg/sql/pgwire/command_result.go @@ -18,13 +18,14 @@ import ( "context" "fmt" + "github.com/cockroachdb/cockroach/pkg/server/telemetry" "github.com/cockroachdb/cockroach/pkg/sql" + "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgerror" "github.com/cockroachdb/cockroach/pkg/sql/pgwire/pgwirebase" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" "github.com/cockroachdb/cockroach/pkg/sql/sqlbase" "github.com/lib/pq/oid" - "github.com/pkg/errors" ) type completionMsgType int @@ -124,9 +125,11 @@ func (r *commandResult) Close(t sql.TransactionStatusIndicator) { r.typ == commandComplete && r.stmtType == tree.Rows { - r.err = errors.Errorf("execute row count limits not supported: %d of %d", + r.err = pgerror.UnimplementedWithIssueErrorf(4035, + "execute row count limits not supported: %d of %d", r.limit, r.rowsAffected) - r.conn.bufferErr(convertToErrWithPGCode(r.err)) + telemetry.RecordError(r.err) + r.conn.bufferErr(r.err) } // Send a completion message, specific to the type of result.