diff --git a/.golangci.yml b/.golangci.yml index a05cb1afc16..aad04a8ce0c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -51,8 +51,7 @@ linters: - errname # Suggests to use `%w` for error-wrapping. - # TODO enable this. Curently fails in about 20 places. - # - errorlint + - errorlint # Checks for pointers to enclosing loop variables. - exportloopref @@ -109,6 +108,17 @@ linters-settings: - G601 gosimple: go: "1.20" + govet: + check-shadowing: false + enable-all: true + disable: + # There is rarely performance differences due to padding, + # the most noticable impact is memory usage. However, + # the main trace data is Protobuf-generated and we ignore + # those files from linting, so this linter is not useful. + - fieldalignment + # Disable shadow + - shadow run: go: "1.20" diff --git a/cmd/anonymizer/app/query/query.go b/cmd/anonymizer/app/query/query.go index 3218c9e4a26..e928ceeb043 100644 --- a/cmd/anonymizer/app/query/query.go +++ b/cmd/anonymizer/app/query/query.go @@ -16,6 +16,7 @@ package query import ( "context" + "errors" "fmt" "io" "time" @@ -76,7 +77,7 @@ func (q *Query) QueryTrace(traceID string) ([]model.Span, error) { } var spans []model.Span - for received, err := stream.Recv(); err != io.EOF; received, err = stream.Recv() { + for received, err := stream.Recv(); !errors.Is(err, io.EOF); received, err = stream.Recv() { if err != nil { return nil, unwrapNotFoundErr(err) } diff --git a/cmd/anonymizer/app/uiconv/extractor.go b/cmd/anonymizer/app/uiconv/extractor.go index 8679766318f..e04230d53a1 100644 --- a/cmd/anonymizer/app/uiconv/extractor.go +++ b/cmd/anonymizer/app/uiconv/extractor.go @@ -16,8 +16,8 @@ package uiconv import ( "encoding/json" + "errors" "fmt" - "io" "os" "go.uber.org/zap" @@ -25,23 +25,23 @@ import ( uimodel "github.com/jaegertracing/jaeger/model/json" ) -// Extractor reads the spans from reader, filters by traceID, and stores as JSON into uiFile. -type Extractor struct { +// extractor reads the spans from reader, filters by traceID, and stores as JSON into uiFile. +type extractor struct { uiFile *os.File traceID string - reader *Reader + reader *spanReader logger *zap.Logger } -// NewExtractor creates Extractor. -func NewExtractor(uiFile string, traceID string, reader *Reader, logger *zap.Logger) (*Extractor, error) { +// newExtractor creates extractor. +func newExtractor(uiFile string, traceID string, reader *spanReader, logger *zap.Logger) (*extractor, error) { f, err := os.OpenFile(uiFile, os.O_CREATE|os.O_WRONLY, os.ModePerm) if err != nil { return nil, fmt.Errorf("cannot create output file: %w", err) } logger.Sugar().Infof("Writing spans to UI file %s", uiFile) - return &Extractor{ + return &extractor{ uiFile: f, traceID: traceID, reader: reader, @@ -50,7 +50,7 @@ func NewExtractor(uiFile string, traceID string, reader *Reader, logger *zap.Log } // Run executes the extraction. -func (e *Extractor) Run() error { +func (e *extractor) Run() error { e.logger.Info("Parsing captured file for trace", zap.String("trace_id", e.traceID)) var ( @@ -63,7 +63,7 @@ func (e *Extractor) Run() error { spans = append(spans, *span) } } - if err != io.EOF { + if !errors.Is(err, errNoMoreSpans) { return fmt.Errorf("failed when scanning the file: %w", err) } trace := uimodel.Trace{ diff --git a/cmd/anonymizer/app/uiconv/extractor_test.go b/cmd/anonymizer/app/uiconv/extractor_test.go index 22a42b26d97..23747509a3e 100644 --- a/cmd/anonymizer/app/uiconv/extractor_test.go +++ b/cmd/anonymizer/app/uiconv/extractor_test.go @@ -30,18 +30,15 @@ type UITrace struct { Data []model.Trace } -func TestExtractor_TraceSuccess(t *testing.T) { +func TestExtractorTraceSuccess(t *testing.T) { inputFile := "fixtures/trace_success.json" outputFile := "fixtures/trace_success_ui_anonymized.json" defer os.Remove(outputFile) - reader, err := NewReader( - inputFile, - zap.NewNop(), - ) + reader, err := newSpanReader(inputFile, zap.NewNop()) require.NoError(t, err) - extractor, err := NewExtractor( + extractor, err := newExtractor( outputFile, "2be38093ead7a083", reader, @@ -62,22 +59,19 @@ func TestExtractor_TraceSuccess(t *testing.T) { } } -func TestExtractor_TraceOutputFileError(t *testing.T) { +func TestExtractorTraceOutputFileError(t *testing.T) { inputFile := "fixtures/trace_success.json" outputFile := "fixtures/trace_success_ui_anonymized.json" defer os.Remove(outputFile) - reader, err := NewReader( - inputFile, - zap.NewNop(), - ) + reader, err := newSpanReader(inputFile, zap.NewNop()) require.NoError(t, err) err = os.Chmod("fixtures", 0o000) require.NoError(t, err) defer os.Chmod("fixtures", 0o755) - _, err = NewExtractor( + _, err = newExtractor( outputFile, "2be38093ead7a083", reader, @@ -86,18 +80,15 @@ func TestExtractor_TraceOutputFileError(t *testing.T) { require.Contains(t, err.Error(), "cannot create output file") } -func TestExtractor_TraceScanError(t *testing.T) { +func TestExtractorTraceScanError(t *testing.T) { inputFile := "fixtures/trace_scan_error.json" outputFile := "fixtures/trace_scan_error_ui_anonymized.json" defer os.Remove(outputFile) - reader, err := NewReader( - inputFile, - zap.NewNop(), - ) + reader, err := newSpanReader(inputFile, zap.NewNop()) require.NoError(t, err) - extractor, err := NewExtractor( + extractor, err := newExtractor( outputFile, "2be38093ead7a083", reader, diff --git a/cmd/anonymizer/app/uiconv/module.go b/cmd/anonymizer/app/uiconv/module.go index bd19620dd0c..76cbd816761 100644 --- a/cmd/anonymizer/app/uiconv/module.go +++ b/cmd/anonymizer/app/uiconv/module.go @@ -28,11 +28,11 @@ type Config struct { // Extract reads anonymized file, finds spans for a given trace, // and writes out that trace in the UI format. func Extract(config Config, logger *zap.Logger) error { - reader, err := NewReader(config.CapturedFile, logger) + reader, err := newSpanReader(config.CapturedFile, logger) if err != nil { return err } - ext, err := NewExtractor(config.UIFile, config.TraceID, reader, logger) + ext, err := newExtractor(config.UIFile, config.TraceID, reader, logger) if err != nil { return err } diff --git a/cmd/anonymizer/app/uiconv/reader.go b/cmd/anonymizer/app/uiconv/reader.go index ee26edb5093..79345ac7928 100644 --- a/cmd/anonymizer/app/uiconv/reader.go +++ b/cmd/anonymizer/app/uiconv/reader.go @@ -18,7 +18,6 @@ import ( "bufio" "encoding/json" "fmt" - "io" "os" "go.uber.org/zap" @@ -26,8 +25,10 @@ import ( uimodel "github.com/jaegertracing/jaeger/model/json" ) -// Reader loads previously captured spans from a file. -type Reader struct { +var errNoMoreSpans = fmt.Errorf("no more spans") + +// spanReader loads previously captured spans from a file. +type spanReader struct { logger *zap.Logger capturedFile *os.File reader *bufio.Reader @@ -35,25 +36,25 @@ type Reader struct { eofReached bool } -// NewReader creates a Reader. -func NewReader(capturedFile string, logger *zap.Logger) (*Reader, error) { +// newSpanReader creates a spanReader. +func newSpanReader(capturedFile string, logger *zap.Logger) (*spanReader, error) { cf, err := os.OpenFile(capturedFile, os.O_RDONLY, os.ModePerm) if err != nil { return nil, fmt.Errorf("cannot open captured file: %w", err) } logger.Sugar().Infof("Reading captured spans from file %s", capturedFile) - return &Reader{ + return &spanReader{ logger: logger, capturedFile: cf, reader: bufio.NewReader(cf), }, nil } -// NextSpan reads the next span from the capture file, or returns io.EOF. -func (r *Reader) NextSpan() (*uimodel.Span, error) { +// NextSpan reads the next span from the capture file, or returns errNoMoreSpans. +func (r *spanReader) NextSpan() (*uimodel.Span, error) { if r.eofReached { - return nil, io.EOF + return nil, errNoMoreSpans } if r.spansRead == 0 { b, err := r.reader.ReadByte() diff --git a/cmd/anonymizer/app/uiconv/reader_test.go b/cmd/anonymizer/app/uiconv/reader_test.go index c9e230c876c..9af2775aebb 100644 --- a/cmd/anonymizer/app/uiconv/reader_test.go +++ b/cmd/anonymizer/app/uiconv/reader_test.go @@ -15,7 +15,6 @@ package uiconv import ( - "io" "testing" "github.com/stretchr/testify/assert" @@ -23,12 +22,9 @@ import ( "go.uber.org/zap" ) -func TestReader_TraceSuccess(t *testing.T) { +func TestReaderTraceSuccess(t *testing.T) { inputFile := "fixtures/trace_success.json" - r, err := NewReader( - inputFile, - zap.NewNop(), - ) + r, err := newSpanReader(inputFile, zap.NewNop()) require.NoError(t, err) s1, err := r.NextSpan() @@ -46,26 +42,20 @@ func TestReader_TraceSuccess(t *testing.T) { assert.Equal(t, true, r.eofReached) _, err = r.NextSpan() - require.Equal(t, io.EOF, err) + require.Equal(t, errNoMoreSpans, err) assert.Equal(t, 1000, r.spansRead) assert.Equal(t, true, r.eofReached) } -func TestReader_TraceNonExistent(t *testing.T) { +func TestReaderTraceNonExistent(t *testing.T) { inputFile := "fixtures/trace_non_existent.json" - _, err := NewReader( - inputFile, - zap.NewNop(), - ) + _, err := newSpanReader(inputFile, zap.NewNop()) require.Contains(t, err.Error(), "cannot open captured file") } -func TestReader_TraceEmpty(t *testing.T) { +func TestReaderTraceEmpty(t *testing.T) { inputFile := "fixtures/trace_empty.json" - r, err := NewReader( - inputFile, - zap.NewNop(), - ) + r, err := newSpanReader(inputFile, zap.NewNop()) require.NoError(t, err) _, err = r.NextSpan() @@ -74,12 +64,9 @@ func TestReader_TraceEmpty(t *testing.T) { assert.Equal(t, true, r.eofReached) } -func TestReader_TraceWrongFormat(t *testing.T) { +func TestReaderTraceWrongFormat(t *testing.T) { inputFile := "fixtures/trace_wrong_format.json" - r, err := NewReader( - inputFile, - zap.NewNop(), - ) + r, err := newSpanReader(inputFile, zap.NewNop()) require.NoError(t, err) _, err = r.NextSpan() @@ -88,12 +75,9 @@ func TestReader_TraceWrongFormat(t *testing.T) { assert.Equal(t, true, r.eofReached) } -func TestReader_TraceInvalidJson(t *testing.T) { +func TestReaderTraceInvalidJson(t *testing.T) { inputFile := "fixtures/trace_invalid_json.json" - r, err := NewReader( - inputFile, - zap.NewNop(), - ) + r, err := newSpanReader(inputFile, zap.NewNop()) require.NoError(t, err) _, err = r.NextSpan() diff --git a/cmd/collector/app/handler/grpc_handler.go b/cmd/collector/app/handler/grpc_handler.go index 4f5b45847a8..347ce5bb77c 100644 --- a/cmd/collector/app/handler/grpc_handler.go +++ b/cmd/collector/app/handler/grpc_handler.go @@ -16,6 +16,7 @@ package handler import ( "context" + "errors" "go.uber.org/zap" "google.golang.org/grpc/codes" @@ -91,7 +92,7 @@ func (c *batchConsumer) consume(ctx context.Context, batch *model.Batch) error { Tenant: tenant, }) if err != nil { - if err == processor.ErrBusy { + if errors.Is(err, processor.ErrBusy) { return status.Errorf(codes.ResourceExhausted, err.Error()) } c.logger.Error("cannot process spans", zap.Error(err)) diff --git a/cmd/es-rollover/app/init/action.go b/cmd/es-rollover/app/init/action.go index 6dcea2f36d4..99134eb61f7 100644 --- a/cmd/es-rollover/app/init/action.go +++ b/cmd/es-rollover/app/init/action.go @@ -16,6 +16,7 @@ package init import ( "encoding/json" + "errors" "fmt" "net/http" "strings" @@ -84,7 +85,8 @@ func (c Action) Do() error { func createIndexIfNotExist(c client.IndexAPI, index string) error { err := c.CreateIndex(index) if err != nil { - if esErr, ok := err.(client.ResponseError); ok { + var esErr client.ResponseError + if errors.As(err, &esErr) { if esErr.StatusCode != http.StatusBadRequest || esErr.Body == nil { return esErr.Err } diff --git a/cmd/internal/flags/admin.go b/cmd/internal/flags/admin.go index e3e7a069fa3..ea4df675a04 100644 --- a/cmd/internal/flags/admin.go +++ b/cmd/internal/flags/admin.go @@ -17,6 +17,7 @@ package flags import ( "context" "crypto/tls" + "errors" "flag" "fmt" "io" @@ -148,10 +149,7 @@ func (s *AdminServer) serveWithListener(l net.Listener) { } else { err = s.server.Serve(l) } - switch err { - case nil, http.ErrServerClosed: - // normal exit, nothing to do - default: + if err != nil && !errors.Is(err, http.ErrServerClosed) { s.logger.Error("failed to serve", zap.Error(err)) s.hc.Set(healthcheck.Broken) } diff --git a/cmd/query/app/flags.go b/cmd/query/app/flags.go index cb23f5a4395..9e8a7ea7169 100644 --- a/cmd/query/app/flags.go +++ b/cmd/query/app/flags.go @@ -17,6 +17,7 @@ package app import ( "bufio" + "errors" "flag" "fmt" "io" @@ -175,7 +176,7 @@ func stringSliceAsHeader(slice []string) (http.Header, error) { tp := textproto.NewReader(reader) header, err := tp.ReadMIMEHeader() - if err != nil && err != io.EOF { + if err != nil && !errors.Is(err, io.EOF) { return nil, fmt.Errorf("failed to parse headers") } diff --git a/cmd/query/app/grpc_handler.go b/cmd/query/app/grpc_handler.go index 84e18506d6b..88e3df670c3 100644 --- a/cmd/query/app/grpc_handler.go +++ b/cmd/query/app/grpc_handler.go @@ -101,7 +101,7 @@ func (g *GRPCHandler) GetTrace(r *api_v2.GetTraceRequest, stream api_v2.QuerySer return errUninitializedTraceID } trace, err := g.queryService.GetTrace(stream.Context(), r.TraceID) - if err == spanstore.ErrTraceNotFound { + if errors.Is(err, spanstore.ErrTraceNotFound) { g.logger.Error(msgTraceNotFound, zap.Error(err)) return status.Errorf(codes.NotFound, "%s: %v", msgTraceNotFound, err) } @@ -121,7 +121,7 @@ func (g *GRPCHandler) ArchiveTrace(ctx context.Context, r *api_v2.ArchiveTraceRe return nil, errUninitializedTraceID } err := g.queryService.ArchiveTrace(ctx, r.TraceID) - if err == spanstore.ErrTraceNotFound { + if errors.Is(err, spanstore.ErrTraceNotFound) { g.logger.Error("trace not found", zap.Error(err)) return nil, status.Errorf(codes.NotFound, "%s: %v", msgTraceNotFound, err) } diff --git a/cmd/query/app/http_handler.go b/cmd/query/app/http_handler.go index d3c10e4344f..90d01a77cd0 100644 --- a/cmd/query/app/http_handler.go +++ b/cmd/query/app/http_handler.go @@ -261,14 +261,14 @@ func (aH *APIHandler) search(w http.ResponseWriter, r *http.Request) { } func (aH *APIHandler) tracesByIDs(ctx context.Context, traceIDs []model.TraceID) ([]*model.Trace, []structuredError, error) { - var errors []structuredError + var traceErrors []structuredError retMe := make([]*model.Trace, 0, len(traceIDs)) for _, traceID := range traceIDs { if trace, err := aH.queryService.GetTrace(ctx, traceID); err != nil { - if err != spanstore.ErrTraceNotFound { + if !errors.Is(err, spanstore.ErrTraceNotFound) { return nil, nil, err } - errors = append(errors, structuredError{ + traceErrors = append(traceErrors, structuredError{ Msg: err.Error(), TraceID: ui.TraceID(traceID.String()), }) @@ -276,7 +276,7 @@ func (aH *APIHandler) tracesByIDs(ctx context.Context, traceIDs []model.TraceID) retMe = append(retMe, trace) } } - return retMe, errors, nil + return retMe, traceErrors, nil } func (aH *APIHandler) dependencies(w http.ResponseWriter, r *http.Request) { @@ -428,7 +428,7 @@ func (aH *APIHandler) getTrace(w http.ResponseWriter, r *http.Request) { return } trace, err := aH.queryService.GetTrace(r.Context(), traceID) - if err == spanstore.ErrTraceNotFound { + if errors.Is(err, spanstore.ErrTraceNotFound) { aH.handleError(w, err, http.StatusNotFound) return } @@ -467,7 +467,7 @@ func (aH *APIHandler) archiveTrace(w http.ResponseWriter, r *http.Request) { // QueryService.ArchiveTrace can now archive this traceID. err := aH.queryService.ArchiveTrace(r.Context(), traceID) - if err == spanstore.ErrTraceNotFound { + if errors.Is(err, spanstore.ErrTraceNotFound) { aH.handleError(w, err, http.StatusNotFound) return } diff --git a/cmd/query/app/querysvc/query_service.go b/cmd/query/app/querysvc/query_service.go index d9b4a758de3..2144928acb2 100644 --- a/cmd/query/app/querysvc/query_service.go +++ b/cmd/query/app/querysvc/query_service.go @@ -72,7 +72,7 @@ func NewQueryService(spanReader spanstore.Reader, dependencyReader dependencysto // GetTrace is the queryService implementation of spanstore.Reader.GetTrace func (qs QueryService) GetTrace(ctx context.Context, traceID model.TraceID) (*model.Trace, error) { trace, err := qs.spanReader.GetTrace(ctx, traceID) - if err == spanstore.ErrTraceNotFound { + if errors.Is(err, spanstore.ErrTraceNotFound) { if qs.options.ArchiveSpanReader == nil { return nil, err } @@ -144,7 +144,7 @@ func (opts *QueryServiceOptions) InitArchiveStorage(storageFactory storage.Facto return false } reader, err := archiveFactory.CreateArchiveSpanReader() - if err == storage.ErrArchiveStorageNotConfigured || err == storage.ErrArchiveStorageNotSupported { + if errors.Is(err, storage.ErrArchiveStorageNotConfigured) || errors.Is(err, storage.ErrArchiveStorageNotSupported) { logger.Info("Archive storage not created", zap.String("reason", err.Error())) return false } @@ -153,7 +153,7 @@ func (opts *QueryServiceOptions) InitArchiveStorage(storageFactory storage.Facto return false } writer, err := archiveFactory.CreateArchiveSpanWriter() - if err == storage.ErrArchiveStorageNotConfigured || err == storage.ErrArchiveStorageNotSupported { + if errors.Is(err, storage.ErrArchiveStorageNotConfigured) || errors.Is(err, storage.ErrArchiveStorageNotSupported) { logger.Info("Archive storage not created", zap.String("reason", err.Error())) return false } diff --git a/cmd/query/app/server.go b/cmd/query/app/server.go index 3a7d0f548cf..42fb886d9e5 100644 --- a/cmd/query/app/server.go +++ b/cmd/query/app/server.go @@ -284,10 +284,7 @@ func (s *Server) Start() error { } else { err = s.httpServer.Serve(s.httpConn) } - switch err { - case nil, http.ErrServerClosed, cmux.ErrListenerClosed, cmux.ErrServerClosed: - // normal exit, nothing to do - default: + if err != nil && !errors.Is(err, http.ErrServerClosed) && !errors.Is(err, cmux.ErrListenerClosed) && !errors.Is(err, cmux.ErrServerClosed) { s.logger.Error("Could not start HTTP server", zap.Error(err)) } diff --git a/model/ids.go b/model/ids.go index 4c21199eaa8..dfdc9070574 100644 --- a/model/ids.go +++ b/model/ids.go @@ -142,7 +142,7 @@ func (t TraceID) MarshalJSON() ([]byte, error) { } // UnmarshalJSON inflates trace id from base64 string, possibly enclosed in quotes. -// User by protobuf JSON serialization. +// Used by protobuf JSON serialization. func (t *TraceID) UnmarshalJSON(data []byte) error { s := string(data) if l := len(s); l > 2 && s[0] == '"' && s[l-1] == '"' { @@ -150,7 +150,7 @@ func (t *TraceID) UnmarshalJSON(data []byte) error { } b, err := base64.StdEncoding.DecodeString(s) if err != nil { - return fmt.Errorf("cannot unmarshal TraceID from string '%s': %v", string(data), err) + return fmt.Errorf("cannot unmarshal TraceID from string '%s': %w", string(data), err) } return t.Unmarshal(b) } @@ -239,7 +239,7 @@ func (s *SpanID) UnmarshalJSON(data []byte) error { } b, err := base64.StdEncoding.DecodeString(str) if err != nil { - return fmt.Errorf("cannot unmarshal SpanID from string '%s': %v", string(data), err) + return fmt.Errorf("cannot unmarshal SpanID from string '%s': %w", string(data), err) } return s.Unmarshal(b) } diff --git a/pkg/es/client/ilm_client.go b/pkg/es/client/ilm_client.go index 5d06328fc23..2a56c859c68 100644 --- a/pkg/es/client/ilm_client.go +++ b/pkg/es/client/ilm_client.go @@ -15,6 +15,7 @@ package client import ( + "errors" "fmt" "net/http" ) @@ -34,7 +35,8 @@ func (i ILMClient) Exists(name string) (bool, error) { method: http.MethodGet, }) - if respError, isResponseErr := err.(ResponseError); isResponseErr { + var respError ResponseError + if errors.As(err, &respError) { if respError.StatusCode == http.StatusNotFound { return false, nil } diff --git a/pkg/es/client/index_client.go b/pkg/es/client/index_client.go index 9fdaa89c308..1c516b99ef1 100644 --- a/pkg/es/client/index_client.go +++ b/pkg/es/client/index_client.go @@ -16,6 +16,7 @@ package client import ( "encoding/json" + "errors" "fmt" "net/http" "strconv" @@ -108,7 +109,8 @@ func (i *IndicesClient) indexDeleteRequest(concatIndices string) error { method: http.MethodDelete, }) if err != nil { - if responseError, isResponseError := err.(ResponseError); isResponseError { + var responseError ResponseError + if errors.As(err, &responseError) { if responseError.StatusCode != http.StatusOK { return responseError.prefixMessage(fmt.Sprintf("failed to delete indices: %s", concatIndices)) } @@ -152,7 +154,8 @@ func (i *IndicesClient) CreateIndex(index string) error { method: http.MethodPut, }) if err != nil { - if responseError, isResponseError := err.(ResponseError); isResponseError { + var responseError ResponseError + if errors.As(err, &responseError) { if responseError.StatusCode != http.StatusOK { return responseError.prefixMessage(fmt.Sprintf("failed to create index: %s", index)) } @@ -166,7 +169,8 @@ func (i *IndicesClient) CreateIndex(index string) error { func (i *IndicesClient) CreateAlias(aliases []Alias) error { err := i.aliasAction("add", aliases) if err != nil { - if responseError, isResponseError := err.(ResponseError); isResponseError { + var responseError ResponseError + if errors.As(err, &responseError) { if responseError.StatusCode != http.StatusOK { return responseError.prefixMessage(fmt.Sprintf("failed to create aliases: %s", i.aliasesString(aliases))) } @@ -180,7 +184,8 @@ func (i *IndicesClient) CreateAlias(aliases []Alias) error { func (i *IndicesClient) DeleteAlias(aliases []Alias) error { err := i.aliasAction("remove", aliases) if err != nil { - if responseError, isResponseError := err.(ResponseError); isResponseError { + var responseError ResponseError + if errors.As(err, &responseError) { if responseError.StatusCode != http.StatusOK { return responseError.prefixMessage(fmt.Sprintf("failed to delete aliases: %s", i.aliasesString(aliases))) } @@ -252,7 +257,8 @@ func (i IndicesClient) CreateTemplate(template, name string) error { body: []byte(template), }) if err != nil { - if responseError, isResponseError := err.(ResponseError); isResponseError { + var responseError ResponseError + if errors.As(err, &responseError) { if responseError.StatusCode != http.StatusOK { return responseError.prefixMessage(fmt.Sprintf("failed to create template: %s", name)) } @@ -280,7 +286,8 @@ func (i IndicesClient) Rollover(rolloverTarget string, conditions map[string]int } _, err := i.request(esReq) if err != nil { - if responseError, isResponseError := err.(ResponseError); isResponseError { + var responseError ResponseError + if errors.As(err, &responseError) { if responseError.StatusCode != http.StatusOK { return responseError.prefixMessage(fmt.Sprintf("failed to create rollover target: %s", rolloverTarget)) } diff --git a/pkg/es/config/config.go b/pkg/es/config/config.go index bee13a8a34e..1549156cff6 100644 --- a/pkg/es/config/config.go +++ b/pkg/es/config/config.go @@ -192,7 +192,7 @@ func NewClient(c *Configuration, logger *zap.Logger, metricsFactory metrics.Fact if c.Version >= 8 { rawClientV8, err = newElasticsearchV8(c, logger) if err != nil { - return nil, fmt.Errorf("error creating v8 client: %v", err) + return nil, fmt.Errorf("error creating v8 client: %w", err) } } diff --git a/plugin/storage/badger/factory.go b/plugin/storage/badger/factory.go index ee0ad29c2e0..f48c163bc5c 100644 --- a/plugin/storage/badger/factory.go +++ b/plugin/storage/badger/factory.go @@ -15,6 +15,7 @@ package badger import ( + "errors" "expvar" "flag" "io" @@ -224,7 +225,7 @@ func (f *Factory) maintenance() { for err == nil { err = f.store.RunValueLogGC(0.5) // 0.5 is selected to rewrite a file if half of it can be discarded } - if err == badger.ErrNoRewrite { + if errors.Is(err, badger.ErrNoRewrite) { f.metrics.LastValueLogCleaned.Update(t.UnixNano()) } else { f.logger.Error("Failed to run ValueLogGC", zap.Error(err)) diff --git a/plugin/storage/badger/samplingstore/storage.go b/plugin/storage/badger/samplingstore/storage.go index f9a982029f2..f287885906b 100644 --- a/plugin/storage/badger/samplingstore/storage.go +++ b/plugin/storage/badger/samplingstore/storage.go @@ -252,7 +252,7 @@ func initalStartTime(timeBytes []byte) (time.Time, error) { buf := bytes.NewReader(timeBytes) if err := binary.Read(buf, binary.BigEndian, &usec); err != nil { - panic(nil) + return time.Time{}, err } t := time.UnixMicro(usec) diff --git a/plugin/storage/cassandra/samplingstore/storage.go b/plugin/storage/cassandra/samplingstore/storage.go index 2ccdc846fa1..4db8308964d 100644 --- a/plugin/storage/cassandra/samplingstore/storage.go +++ b/plugin/storage/cassandra/samplingstore/storage.go @@ -18,6 +18,7 @@ package samplingstore import ( "bytes" "encoding/csv" + "errors" "fmt" "io" "strconv" @@ -247,7 +248,7 @@ func (s *SamplingStore) parseString(str string, numColumns int, appendFunc func( reader := csv.NewReader(strings.NewReader(str)) for { csvFields, err := reader.Read() - if err == io.EOF { + if errors.Is(err, io.EOF) { break } if err != nil { diff --git a/plugin/storage/grpc/shared/grpc_client.go b/plugin/storage/grpc/shared/grpc_client.go index 4d230cec9af..9b24b6c18eb 100644 --- a/plugin/storage/grpc/shared/grpc_client.go +++ b/plugin/storage/grpc/shared/grpc_client.go @@ -16,6 +16,7 @@ package shared import ( "context" + "errors" "fmt" "io" "time" @@ -201,7 +202,7 @@ func (c *grpcClient) FindTraces(ctx context.Context, query *spanstore.TraceQuery var traces []*model.Trace var trace *model.Trace var traceID model.TraceID - for received, err := stream.Recv(); err != io.EOF; received, err = stream.Recv() { + for received, err := stream.Recv(); !errors.Is(err, io.EOF); received, err = stream.Recv() { if err != nil { return nil, fmt.Errorf("stream error: %w", err) } @@ -291,7 +292,7 @@ func (c *grpcClient) Capabilities() (*Capabilities, error) { func readTrace(stream storage_v1.SpanReaderPlugin_GetTraceClient) (*model.Trace, error) { trace := model.Trace{} - for received, err := stream.Recv(); err != io.EOF; received, err = stream.Recv() { + for received, err := stream.Recv(); !errors.Is(err, io.EOF); received, err = stream.Recv() { if err != nil { if s, _ := status.FromError(err); s != nil { if s.Message() == spanstore.ErrTraceNotFound.Error() { diff --git a/plugin/storage/grpc/shared/grpc_handler.go b/plugin/storage/grpc/shared/grpc_handler.go index 32c1434d2ef..98f27a53540 100644 --- a/plugin/storage/grpc/shared/grpc_handler.go +++ b/plugin/storage/grpc/shared/grpc_handler.go @@ -16,6 +16,7 @@ package shared import ( "context" + "errors" "fmt" "io" @@ -112,7 +113,7 @@ func (s *GRPCHandler) WriteSpanStream(stream storage_v1.StreamingSpanWriterPlugi } for { in, err := stream.Recv() - if err == io.EOF { + if errors.Is(err, io.EOF) { break } if err != nil { @@ -150,7 +151,7 @@ func (s *GRPCHandler) Close(ctx context.Context, r *storage_v1.CloseWriterReques // GetTrace takes a traceID and streams a Trace associated with that traceID func (s *GRPCHandler) GetTrace(r *storage_v1.GetTraceRequest, stream storage_v1.SpanReaderPlugin_GetTraceServer) error { trace, err := s.impl.SpanReader().GetTrace(stream.Context(), r.TraceID) - if err == spanstore.ErrTraceNotFound { + if errors.Is(err, spanstore.ErrTraceNotFound) { return status.Errorf(codes.NotFound, spanstore.ErrTraceNotFound.Error()) } if err != nil { @@ -275,7 +276,7 @@ func (s *GRPCHandler) GetArchiveTrace(r *storage_v1.GetTraceRequest, stream stor return status.Error(codes.Unimplemented, "not implemented") } trace, err := reader.GetTrace(stream.Context(), r.TraceID) - if err == spanstore.ErrTraceNotFound { + if errors.Is(err, spanstore.ErrTraceNotFound) { return status.Errorf(codes.NotFound, spanstore.ErrTraceNotFound.Error()) } if err != nil {