From 7b4377ad9d8a7205416df8d6217ef2b010f89481 Mon Sep 17 00:00:00 2001 From: Taras Madan Date: Wed, 22 Jan 2025 16:07:17 +0100 Subject: vendor: delete --- vendor/github.com/jjti/go-spancheck/.gitignore | 19 - vendor/github.com/jjti/go-spancheck/.golangci.yml | 103 ----- .../github.com/jjti/go-spancheck/CONTRIBUTING.md | 51 --- vendor/github.com/jjti/go-spancheck/LICENSE | 21 - vendor/github.com/jjti/go-spancheck/Makefile | 27 -- vendor/github.com/jjti/go-spancheck/README.md | 268 ------------ vendor/github.com/jjti/go-spancheck/config.go | 223 ---------- vendor/github.com/jjti/go-spancheck/doc.go | 37 -- vendor/github.com/jjti/go-spancheck/go.work | 8 - vendor/github.com/jjti/go-spancheck/go.work.sum | 4 - vendor/github.com/jjti/go-spancheck/spancheck.go | 466 --------------------- 11 files changed, 1227 deletions(-) delete mode 100644 vendor/github.com/jjti/go-spancheck/.gitignore delete mode 100644 vendor/github.com/jjti/go-spancheck/.golangci.yml delete mode 100644 vendor/github.com/jjti/go-spancheck/CONTRIBUTING.md delete mode 100644 vendor/github.com/jjti/go-spancheck/LICENSE delete mode 100644 vendor/github.com/jjti/go-spancheck/Makefile delete mode 100644 vendor/github.com/jjti/go-spancheck/README.md delete mode 100644 vendor/github.com/jjti/go-spancheck/config.go delete mode 100644 vendor/github.com/jjti/go-spancheck/doc.go delete mode 100644 vendor/github.com/jjti/go-spancheck/go.work delete mode 100644 vendor/github.com/jjti/go-spancheck/go.work.sum delete mode 100644 vendor/github.com/jjti/go-spancheck/spancheck.go (limited to 'vendor/github.com/jjti') diff --git a/vendor/github.com/jjti/go-spancheck/.gitignore b/vendor/github.com/jjti/go-spancheck/.gitignore deleted file mode 100644 index 1f83be414..000000000 --- a/vendor/github.com/jjti/go-spancheck/.gitignore +++ /dev/null @@ -1,19 +0,0 @@ -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ -src/ diff --git a/vendor/github.com/jjti/go-spancheck/.golangci.yml b/vendor/github.com/jjti/go-spancheck/.golangci.yml deleted file mode 100644 index 15d8513d6..000000000 --- a/vendor/github.com/jjti/go-spancheck/.golangci.yml +++ /dev/null @@ -1,103 +0,0 @@ -## A good ref for this: https://gist.github.com/maratori/47a4d00457a92aa426dbd48a18776322 - -run: - timeout: 5m - tests: true -linters: - enable: - - asasalint # checks for pass []any as any in variadic func(...any) - - asciicheck # checks that your code does not contain non-ASCII identifiers - - bidichk # checks for dangerous unicode character sequences - - bodyclose - - containedctx - - decorder # checks declaration order and count of types, constants, variables and functions - - dogsled - - dupword # checks for duplicate words in the source code - - durationcheck # checks for two durations multiplied together - - errcheck - - errname - - errorlint - - exhaustive # checks exhaustiveness of enum switch statements - - exportloopref # checks for pointers to enclosing loop variables - - gci - - gochecknoinits # checks that no init functions are present in Go code - - gocritic - - gomnd - - gosimple - - govet - - importas # enforces consistent import aliases - - ineffassign - - loggercheck - - makezero # finds slice declarations with non-zero initial length - - mirror - - misspell - - musttag # enforces field tags in (un)marshaled structs - - nakedret - - nestif # reports deeply nested if statements - - nilerr # finds the code that returns nil even if it checks that the error is not nil - - noctx # finds sending http request without context.Context - - nolintlint # reports ill-formed or insufficient nolint directives - - predeclared # finds code that shadows one of Go's predeclared identifiers - - promlinter - - reassign # checks that package variables are not reassigned - - revive # fast, configurable, extensible, flexible, and beautiful linter for Go, drop-in replacement of golint - - staticcheck - - stylecheck - - tenv - - thelper # detects golang test helpers without t.Helper() call and checks the consistency of test helpers - - unconvert # removes unnecessary type conversions - - unparam # reports unused function parameters - - unused - - usestdlibvars # detects the possibility to use variables/constants from the Go standard library - - wastedassign # finds wasted assignment statements - - whitespace # detects leading and trailing whitespace -linters-settings: - gci: - skip-generated: true - custom-order: true - sections: - - standard # Standard section: captures all standard packages. - - default # Default section: contains all imports that could not be matched to another section type. - - prefix(github.com/jjti) - exhaustive: - # Program elements to check for exhaustiveness. - # Default: [ switch ] - check: - - switch - - map - gocritic: - settings: - captLocal: - # Whether to restrict checker to params only. - # Default: true - paramsOnly: false - underef: - # Whether to skip (*x).method() calls where x is a pointer receiver. - # Default: true - skipRecvDeref: false - govet: - enable-all: true - disable: - - fieldalignment # too strict - - shadow # bunch of false positive, doesn't realize when we return from a func - misspell: - locale: US - nakedret: - max-func-lines: 0 - nestif: - # Minimal complexity of if statements to report. - # Default: 5 - min-complexity: 4 - nolintlint: - # Enable to require an explanation of nonzero length after each nolint directive. - # Default: false - require-explanation: true - stylecheck: - checks: ["all"] -issues: - include: - - EXC0001 # Error return value of x is not checked - - EXC0013 # package comment should be of the form "(.+)... - - EXC0014 # comment on exported (.+) should be of the form "(.+)..." - exclude: - - ifElseChain diff --git a/vendor/github.com/jjti/go-spancheck/CONTRIBUTING.md b/vendor/github.com/jjti/go-spancheck/CONTRIBUTING.md deleted file mode 100644 index 32932fae1..000000000 --- a/vendor/github.com/jjti/go-spancheck/CONTRIBUTING.md +++ /dev/null @@ -1,51 +0,0 @@ -# Contributing guideline - -Contributions are welcome + appreciated. - -## Open Requests - -These are a couple contributions I would especially appreciate: - -1. Add check for SetAttributes: https://github.com/jjti/go-spancheck/issues/1 -1. Add SuggestedFix(es): https://github.com/jjti/go-spancheck/issues/2 - -## Steps - -### 1. Create an Issue - -If one does not exist already, open a bug report or feature request in [https://github.com/jjti/go-spancheck/issues](https://github.com/jjti/go-spancheck/issues). - -### 2. Add a test case - -Test cases are in `/testdata`. - -If fixing a bug, you can add it to `testdata/enableall/enable_all.go` (for example): - -```go -func _() { - ctx, span := otel.Tracer("foo").Start(context.Background(), "bar") // want "span.End is not called on all paths, possible memory leak" - print(ctx.Done(), span.IsRecording()) -} // want "return can be reached without calling span.End" -``` - -If adding a new feature with a new combination of flags, create a new module within `testdata`: - -1. Create a new module, eg `testdata/setattributes` -1. Copy/paste go.mod/sum into the new module directory and update the module definition, eg `module github.com/jjti/go-spancheck/testdata/setattributes` -1. Add the module to the workspace in [go.work](./go.work) -1. Add the module's directory to the `testvendor` Make target in [Makefile](./Makefile) - -### 3. Run tests - -```bash -make test -``` - -### 4. Open a PR - -Eg of a GitHub snippet for PRs: - -```bash -alias gpr='gh pr view --web 2>/dev/null || gh pr create --web --fill' -gpr -``` diff --git a/vendor/github.com/jjti/go-spancheck/LICENSE b/vendor/github.com/jjti/go-spancheck/LICENSE deleted file mode 100644 index 552ddf2dc..000000000 --- a/vendor/github.com/jjti/go-spancheck/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Joshua Timmons - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/jjti/go-spancheck/Makefile b/vendor/github.com/jjti/go-spancheck/Makefile deleted file mode 100644 index 8e9d07be3..000000000 --- a/vendor/github.com/jjti/go-spancheck/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -.PHONY: fmt -fmt: - golangci-lint run --fix --config ./.golangci.yml - -.PHONY: test -test: testvendor - go test -v ./... - -# note: I'm copying https://github.com/ghostiam/protogetter/blob/main/testdata/Makefile -# -# x/tools/go/analysis/analysistest does not support go modules. To work around this issue -# we need to vendor any external modules to `./src`. -# -# Follow https://github.com/golang/go/issues/37054 for more details. -.PHONY: testvendor -testvendor: - rm -rf testdata/base/src - cd testdata/base && GOWORK=off go mod vendor - cp -r testdata/base/vendor testdata/base/src - cp -r testdata/base/vendor testdata/disableerrorchecks/src - cp -r testdata/base/vendor testdata/enableall/src - rm -rf testdata/base/vendor - -.PHONY: install -install: - go install ./cmd/spancheck - @echo "Installed in $(shell which spancheck)" \ No newline at end of file diff --git a/vendor/github.com/jjti/go-spancheck/README.md b/vendor/github.com/jjti/go-spancheck/README.md deleted file mode 100644 index 393663ba7..000000000 --- a/vendor/github.com/jjti/go-spancheck/README.md +++ /dev/null @@ -1,268 +0,0 @@ -# go-spancheck - -![Latest release](https://img.shields.io/github/v/release/jjti/go-spancheck) -[![ci](https://github.com/jjti/go-spancheck/actions/workflows/ci.yaml/badge.svg)](https://github.com/jjti/go-spancheck/actions/workflows/ci.yaml) -[![Go Report Card](https://goreportcard.com/badge/github.com/jjti/go-spancheck)](https://goreportcard.com/report/github.com/jjti/go-spancheck) -[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE) - -Checks usage of: - -- [OpenTelemetry spans](https://opentelemetry.io/docs/instrumentation/go/manual/) from [go.opentelemetry.io/otel/trace](go.opentelemetry.io/otel/trace) -- [OpenCensus spans](https://opencensus.io/quickstart/go/tracing/) from [go.opencensus.io/trace](https://pkg.go.dev/go.opencensus.io/trace#Span) - -## Example - -```bash -spancheck -checks 'end,set-status,record-error' ./... -``` - -```go -func _() error { - // span.End is not called on all paths, possible memory leak - // span.SetStatus is not called on all paths - // span.RecordError is not called on all paths - _, span := otel.Tracer("foo").Start(context.Background(), "bar") - - if true { - // return can be reached without calling span.End - // return can be reached without calling span.SetStatus - // return can be reached without calling span.RecordError - return errors.New("err") - } - - return nil // return can be reached without calling span.End -} -``` - -## Configuration - -### golangci-lint - -Docs on configuring the linter are also available at [https://golangci-lint.run/usage/linters/#spancheck](https://golangci-lint.run/usage/linters/#spancheck): - -```yaml -linters: - enable: - - spancheck - -linters-settings: - spancheck: - # Checks to enable. - # Options include: - # - `end`: check that `span.End()` is called - # - `record-error`: check that `span.RecordError(err)` is called when an error is returned - # - `set-status`: check that `span.SetStatus(codes.Error, msg)` is called when an error is returned - # Default: ["end"] - checks: - - end - - record-error - - set-status - # A list of regexes for function signatures that silence `record-error` and `set-status` reports - # if found in the call path to a returned error. - # https://github.com/jjti/go-spancheck#ignore-check-signatures - # Default: [] - ignore-check-signatures: - - "telemetry.RecordError" - # A list of regexes for additional function signatures that create spans. This is useful if you have a utility - # method to create spans. Each entry should be of the form :, where `telemetry-type` - # can be `opentelemetry` or `opencensus`. - # https://github.com/jjti/go-spancheck#extra-start-span-signatures - # Default: [] - extra-start-span-signatures: - - "github.com/user/repo/telemetry/trace.Start:opentelemetry" -``` - -### CLI - -To install the linter as a CLI: - -```bash -go install github.com/jjti/go-spancheck/cmd/spancheck@latest -spancheck ./... -``` - -Only the `span.End()` check is enabled by default. The others can be enabled with `-checks 'end,set-status,record-error'`. - -```txt -$ spancheck -h -... -Flags: - -checks string - comma-separated list of checks to enable (options: end, set-status, record-error) (default "end") - -extra-start-span-signatures string - comma-separated list of regex:telemetry-type for function signatures that indicate the start of a span - -ignore-check-signatures string - comma-separated list of regex for function signatures that disable checks on errors -``` - -### Ignore Check Signatures - -The `span.SetStatus()` and `span.RecordError()` checks warn when there is: - -1. a path to return statement -1. that returns an error -1. without a call (to `SetStatus` or `RecordError`, respectively) - -But it's convenient to call `SetStatus` and `RecordError` from utility methods [[1](https://andydote.co.uk/2023/09/19/tracing-is-better/#step-2-wrap-the-errors)]. To support that, the `ignore-*-check-signatures` settings will suppress warnings if the configured function is present in the path. - -For example, by default, the code below would have warnings as shown: - -```go -func task(ctx context.Context) error { - ctx, span := otel.Tracer("foo").Start(ctx, "bar") // span.SetStatus is not called on all paths - defer span.End() - - if err := subTask(ctx); err != nil { - return recordErr(span, err) // return can be reached without calling span.SetStatus - } - - return nil -} - -func recordErr(span trace.Span, err error) error { - span.SetStatus(codes.Error, err.Error()) - span.RecordError(err) - return err -} -``` - -The warnings are can be ignored by setting `-ignore-check-signatures` flag to `recordErr`: - -```bash -spancheck -checks 'end,set-status,record-error' -ignore-check-signatures 'recordErr' ./... -``` - -### Extra Start Span Signatures - -By default, Span creation will be tracked from calls to [(go.opentelemetry.io/otel/trace.Tracer).Start](https://github.com/open-telemetry/opentelemetry-go/blob/98b32a6c3a87fbee5d34c063b9096f416b250897/trace/trace.go#L523), [go.opencensus.io/trace.StartSpan](https://pkg.go.dev/go.opencensus.io/trace#StartSpan), or [go.opencensus.io/trace.StartSpanWithRemoteParent](https://github.com/census-instrumentation/opencensus-go/blob/v0.24.0/trace/trace_api.go#L66). - -You can use the `-extra-start-span-signatures` flag to list additional Span creation functions. For all such functions: - -1. their Spans will be linted (for all enable checks) -1. checks will be disabled (i.e. there is no linting of Spans within the creation functions) - -You must pass a comma-separated list of regex patterns and the telemetry library corresponding to the returned Span. Each entry should be of the form `:`, where `telemetry-type` can be `opentelemetry` or `opencensus`. For example, if you have created a function named `StartTrace` in a `telemetry` package, using the `go.opentelemetry.io/otel` library, you can include this function for analysis like so: - -```bash -spancheck -extra-start-span-signatures 'github.com/user/repo/telemetry/StartTrace:opentelemetry' ./... -``` - -## Problem Statement - -Tracing is a celebrated [[1](https://andydote.co.uk/2023/09/19/tracing-is-better/),[2](https://charity.wtf/2022/08/15/live-your-best-life-with-structured-events/)] and well marketed [[3](https://docs.datadoghq.com/tracing/),[4](https://www.honeycomb.io/distributed-tracing)] pillar of observability. But self-instrumented tracing requires a lot of easy-to-forget boilerplate: - -```go -import ( - "go.opentelemetry.io/otel" - "go.opentelemetry.io/otel/codes" -) - -func task(ctx context.Context) error { - ctx, span := otel.Tracer("foo").Start(ctx, "bar") - defer span.End() // call `.End()` - - if err := subTask(ctx); err != nil { - span.SetStatus(codes.Error, err.Error()) // call SetStatus(codes.Error, msg) to set status:error - span.RecordError(err) // call RecordError(err) to record an error event - return err - } - - return nil -} -``` - -For spans to be _really_ useful, developers need to: - -1. call `span.End()` always -1. call `span.SetStatus(codes.Error, msg)` on error -1. call `span.RecordError(err)` on error -1. call `span.SetAttributes()` liberally - -- OpenTelemetry: [Creating spans](https://opentelemetry.io/docs/instrumentation/go/manual/#creating-spans) -- Uptrace: [OpenTelemetry Go Tracing API](https://uptrace.dev/opentelemetry/go-tracing.html#quickstart) - -This linter helps developers with steps 1-3. - -## Checks - -This linter supports three checks, each documented below. Only the check for `span.End()` is enabled by default. See [Configuration](#configuration) for instructions on enabling the others. - -### `span.End()` - -Enabled by default. - -Not calling `End` can cause memory leaks and prevents spans from being closed. - -> Any Span that is created MUST also be ended. This is the responsibility of the user. Implementations of this API may leak memory or other resources if Spans are not ended. - -[source: trace.go](https://github.com/open-telemetry/opentelemetry-go/blob/98b32a6c3a87fbee5d34c063b9096f416b250897/trace/trace.go#L523) - -```go -func task(ctx context.Context) error { - otel.Tracer("app").Start(ctx, "foo") // span is unassigned, probable memory leak - _, span := otel.Tracer().Start(ctx, "foo") // span.End is not called on all paths, possible memory leak - return nil // return can be reached without calling span.End -} -``` - -### `span.SetStatus(codes.Error, "msg")` - -Disabled by default. Enable with `-checks 'set-status'`. - -Developers should call `SetStatus` on spans. The status attribute is an important, first-class attribute: - -1. observability platforms and APMs differentiate "success" vs "failure" using [span's status codes](https://docs.datadoghq.com/tracing/metrics/). -1. telemetry collector agents, like the [Open Telemetry Collector's Tail Sampling Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/tailsamplingprocessor/README.md#:~:text=Sampling%20Processor.-,status_code,-%3A%20Sample%20based%20upon), are configurable to sample `Error` spans at a higher rate than `OK` spans. -1. observability platforms, like [DataDog, have trace retention filters that use spans' status](https://docs.datadoghq.com/tracing/trace_pipeline/trace_retention/). In other words, `status:error` spans often receive special treatment with the assumption they are more useful for debugging. And forgetting to set the status can lead to spans, with useful debugging information, being dropped. - -```go -func _() error { - _, span := otel.Tracer("foo").Start(context.Background(), "bar") // span.SetStatus is not called on all paths - defer span.End() - - if err := subTask(); err != nil { - span.RecordError(err) - return errors.New(err) // return can be reached without calling span.SetStatus - } - - return nil -} -``` - -OpenTelemetry docs: [Set span status](https://opentelemetry.io/docs/instrumentation/go/manual/#set-span-status). - -### `span.RecordError(err)` - -Disabled by default. Enable with `-checks 'record-error'`. - -Calling `RecordError` creates a new exception-type [event (structured log message)](https://opentelemetry.io/docs/concepts/signals/traces/#span-events) on the span. This is recommended to capture the error's stack trace. - -```go -func _() error { - _, span := otel.Tracer("foo").Start(context.Background(), "bar") // span.RecordError is not called on all paths - defer span.End() - - if err := subTask(); err != nil { - span.SetStatus(codes.Error, err.Error()) - return errors.New(err) // return can be reached without calling span.RecordError - } - - return nil -} -``` - -OpenTelemetry docs: [Record errors](https://opentelemetry.io/docs/instrumentation/go/manual/#record-errors). - -Note: this check is not applied to [OpenCensus spans](https://pkg.go.dev/go.opencensus.io/trace#SpanInterface) because they have no `RecordError` method. - -## Attribution - -This linter is the product of liberal copying of: - -- [github.com/golang/tools/go/analysis/passes/lostcancel](https://github.com/golang/tools/tree/master/go/analysis/passes/lostcancel) (half the linter) -- [github.com/tomarrell/wrapcheck](https://github.com/tomarrell/wrapcheck) (error type checking and config) -- [github.com/Antonboom/testifylint](https://github.com/Antonboom/testifylint) (README) -- [github.com/ghostiam/protogetter](https://github.com/ghostiam/protogetter/blob/main/testdata/Makefile) (test setup) - -And the contributions of: -- [@trixnz](https://github.com/trixnz) who [added support for custom span start functions](https://github.com/jjti/go-spancheck/pull/16) diff --git a/vendor/github.com/jjti/go-spancheck/config.go b/vendor/github.com/jjti/go-spancheck/config.go deleted file mode 100644 index ed02a1ad9..000000000 --- a/vendor/github.com/jjti/go-spancheck/config.go +++ /dev/null @@ -1,223 +0,0 @@ -package spancheck - -import ( - "flag" - "fmt" - "log" - "regexp" - "strings" -) - -// Check is a type of check that can be enabled or disabled. -type Check int - -const ( - // EndCheck if enabled, checks that span.End() is called after span creation and before the function returns. - EndCheck Check = iota - - // SetStatusCheck if enabled, checks that `span.SetStatus(codes.Error, msg)` is called when returning an error. - SetStatusCheck - - // RecordErrorCheck if enabled, checks that span.RecordError(err) is called when returning an error. - RecordErrorCheck -) - -var ( - startSpanSignatureCols = 2 - defaultStartSpanSignatures = []string{ - // https://github.com/open-telemetry/opentelemetry-go/blob/98b32a6c3a87fbee5d34c063b9096f416b250897/trace/trace.go#L523 - `\(go.opentelemetry.io/otel/trace.Tracer\).Start:opentelemetry`, - // https://pkg.go.dev/go.opencensus.io/trace#StartSpan - `go.opencensus.io/trace.StartSpan:opencensus`, - // https://github.com/census-instrumentation/opencensus-go/blob/v0.24.0/trace/trace_api.go#L66 - `go.opencensus.io/trace.StartSpanWithRemoteParent:opencensus`, - } -) - -func (c Check) String() string { - switch c { - case EndCheck: - return "end" - case SetStatusCheck: - return "set-status" - case RecordErrorCheck: - return "record-error" - default: - return "" - } -} - -// Checks is a list of all checks by name. -var Checks = map[string]Check{ - EndCheck.String(): EndCheck, - SetStatusCheck.String(): SetStatusCheck, - RecordErrorCheck.String(): RecordErrorCheck, -} - -type spanStartMatcher struct { - signature *regexp.Regexp - spanType spanType -} - -// Config is a configuration for the spancheck analyzer. -type Config struct { - fs flag.FlagSet - - // EnabledChecks is a list of checks to enable by name. - EnabledChecks []string - - // IgnoreChecksSignaturesSlice is a slice of strings that are turned into - // the IgnoreSetStatusCheckSignatures regex. - IgnoreChecksSignaturesSlice []string - - StartSpanMatchersSlice []string - - endCheckEnabled bool - setStatusEnabled bool - recordErrorEnabled bool - - // ignoreChecksSignatures is a regex that, if matched, disables the - // SetStatus and RecordError checks on error. - ignoreChecksSignatures *regexp.Regexp - - startSpanMatchers []spanStartMatcher - startSpanMatchersCustomRegex *regexp.Regexp -} - -// NewDefaultConfig returns a new Config with default values. -func NewDefaultConfig() *Config { - return &Config{ - EnabledChecks: []string{EndCheck.String()}, - StartSpanMatchersSlice: defaultStartSpanSignatures, - } -} - -// finalize parses checks and signatures from the public string slices of Config. -func (c *Config) finalize() { - c.parseSignatures() - - checks := parseChecks(c.EnabledChecks) - c.endCheckEnabled = contains(checks, EndCheck) - c.setStatusEnabled = contains(checks, SetStatusCheck) - c.recordErrorEnabled = contains(checks, RecordErrorCheck) -} - -// parseSignatures sets the Ignore*CheckSignatures regex from the string slices. -func (c *Config) parseSignatures() { - c.parseIgnoreSignatures() - c.parseStartSpanSignatures() -} - -func (c *Config) parseIgnoreSignatures() { - if c.ignoreChecksSignatures == nil && len(c.IgnoreChecksSignaturesSlice) > 0 { - if len(c.IgnoreChecksSignaturesSlice) == 1 && c.IgnoreChecksSignaturesSlice[0] == "" { - return - } - - c.ignoreChecksSignatures = createRegex(c.IgnoreChecksSignaturesSlice) - } -} - -func (c *Config) parseStartSpanSignatures() { - if c.startSpanMatchers != nil { - return - } - - customMatchers := []string{} - for i, sig := range c.StartSpanMatchersSlice { - parts := strings.Split(sig, ":") - - // Make sure we have both a signature and a telemetry type - if len(parts) != startSpanSignatureCols { - log.Default().Printf("[WARN] invalid start span signature \"%s\". expected regex:telemetry-type\n", sig) - - continue - } - - sig, sigType := parts[0], parts[1] - if len(sig) < 1 { - log.Default().Print("[WARN] invalid start span signature, empty pattern") - - continue - } - - spanType, ok := SpanTypes[sigType] - if !ok { - validSpanTypes := make([]string, 0, len(SpanTypes)) - for k := range SpanTypes { - validSpanTypes = append(validSpanTypes, k) - } - - log.Default(). - Printf("[WARN] invalid start span type \"%s\". expected one of %s\n", sigType, strings.Join(validSpanTypes, ", ")) - - continue - } - - regex, err := regexp.Compile(sig) - if err != nil { - log.Default().Printf("[WARN] failed to compile regex from signature %s: %v\n", sig, err) - - continue - } - - c.startSpanMatchers = append(c.startSpanMatchers, spanStartMatcher{ - signature: regex, - spanType: spanType, - }) - - if i >= len(defaultStartSpanSignatures) { - customMatchers = append(customMatchers, sig) - } - } - - c.startSpanMatchersCustomRegex = createRegex(customMatchers) -} - -func parseChecks(checksSlice []string) []Check { - if len(checksSlice) == 0 { - return nil - } - - checks := []Check{} - for _, check := range checksSlice { - checkName := strings.TrimSpace(check) - if checkName == "" { - continue - } - - check, ok := Checks[checkName] - if !ok { - continue - } - - checks = append(checks, check) - } - - return checks -} - -func createRegex(sigs []string) *regexp.Regexp { - if len(sigs) == 0 { - return nil - } - - regex := fmt.Sprintf("(%s)", strings.Join(sigs, "|")) - regexCompiled, err := regexp.Compile(regex) - if err != nil { - log.Default().Print("[WARN] failed to compile regex from signature flag", "regex", regex, "err", err) - return nil - } - - return regexCompiled -} - -func contains(s []Check, e Check) bool { - for _, a := range s { - if a == e { - return true - } - } - - return false -} diff --git a/vendor/github.com/jjti/go-spancheck/doc.go b/vendor/github.com/jjti/go-spancheck/doc.go deleted file mode 100644 index f9dec043f..000000000 --- a/vendor/github.com/jjti/go-spancheck/doc.go +++ /dev/null @@ -1,37 +0,0 @@ -// Package spancheck defines a linter that checks for mistakes with OTEL trace spans. -// -// # Analyzer spancheck -// -// spancheck: check for mistakes with OpenTelemetry trace spans. -// -// Common mistakes with OTEL trace spans include forgetting to call End: -// -// func(ctx context.Context) { -// ctx, span := otel.Tracer("app").Start(ctx, "span") -// // defer span.End() should be here -// -// // do stuff -// } -// -// Forgetting to set an Error status: -// -// ctx, span := otel.Tracer("app").Start(ctx, "span") -// defer span.End() -// -// if err := task(); err != nil { -// // span.SetStatus(codes.Error, err.Error()) should be here -// span.RecordError(err) -// return fmt.Errorf("failed to run task: %w", err) -// } -// -// Forgetting to record the Error: -// -// ctx, span := otel.Tracer("app").Start(ctx, "span") -// defer span.End() -// -// if err := task(); err != nil { -// span.SetStatus(codes.Error, err.Error()) -// // span.RecordError(err) should be here -// return fmt.Errorf("failed to run task: %w", err) -// } -package spancheck diff --git a/vendor/github.com/jjti/go-spancheck/go.work b/vendor/github.com/jjti/go-spancheck/go.work deleted file mode 100644 index 7d0a87b9e..000000000 --- a/vendor/github.com/jjti/go-spancheck/go.work +++ /dev/null @@ -1,8 +0,0 @@ -go 1.20 - -use ( - . - ./testdata/base - ./testdata/disableerrorchecks - ./testdata/enableall -) diff --git a/vendor/github.com/jjti/go-spancheck/go.work.sum b/vendor/github.com/jjti/go-spancheck/go.work.sum deleted file mode 100644 index 04eadf2c5..000000000 --- a/vendor/github.com/jjti/go-spancheck/go.work.sum +++ /dev/null @@ -1,4 +0,0 @@ -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= diff --git a/vendor/github.com/jjti/go-spancheck/spancheck.go b/vendor/github.com/jjti/go-spancheck/spancheck.go deleted file mode 100644 index 8fc7945c6..000000000 --- a/vendor/github.com/jjti/go-spancheck/spancheck.go +++ /dev/null @@ -1,466 +0,0 @@ -package spancheck - -import ( - "go/ast" - "go/types" - "regexp" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/ctrlflow" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - "golang.org/x/tools/go/cfg" -) - -const stackLen = 32 - -// spanType differentiates span types. -type spanType int - -const ( - spanUnset spanType = iota // not a span - spanOpenTelemetry // from go.opentelemetry.io/otel - spanOpenCensus // from go.opencensus.io/trace -) - -// SpanTypes is a list of all span types by name. -var SpanTypes = map[string]spanType{ - "opentelemetry": spanOpenTelemetry, - "opencensus": spanOpenCensus, -} - -// this approach stolen from errcheck -// https://github.com/kisielk/errcheck/blob/7f94c385d0116ccc421fbb4709e4a484d98325ee/errcheck/errcheck.go#L22 -var errorType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) - -// NewAnalyzerWithConfig returns a new analyzer configured with the Config passed in. -// Its config can be set for testing. -func NewAnalyzerWithConfig(config *Config) *analysis.Analyzer { - return newAnalyzer(config) -} - -func newAnalyzer(config *Config) *analysis.Analyzer { - config.finalize() - - return &analysis.Analyzer{ - Name: "spancheck", - Doc: "Checks for mistakes with OpenTelemetry/Census spans.", - Flags: config.fs, - Run: run(config), - Requires: []*analysis.Analyzer{ - ctrlflow.Analyzer, - inspect.Analyzer, - }, - } -} - -func run(config *Config) func(*analysis.Pass) (interface{}, error) { - return func(pass *analysis.Pass) (interface{}, error) { - inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - - nodeFilter := []ast.Node{ - (*ast.FuncLit)(nil), // f := func() {} - (*ast.FuncDecl)(nil), // func foo() {} - } - inspect.Preorder(nodeFilter, func(n ast.Node) { - runFunc(pass, n, config) - }) - - return nil, nil - } -} - -type spanVar struct { - stmt ast.Node - id *ast.Ident - vr *types.Var - spanType spanType -} - -// runFunc checks if the node is a function, has a span, and the span never has SetStatus set. -func runFunc(pass *analysis.Pass, node ast.Node, config *Config) { - // copying https://cs.opensource.google/go/x/tools/+/master:go/analysis/passes/lostcancel/lostcancel.go - - // Find scope of function node - var funcScope *types.Scope - switch v := node.(type) { - case *ast.FuncLit: - funcScope = pass.TypesInfo.Scopes[v.Type] - case *ast.FuncDecl: - funcScope = pass.TypesInfo.Scopes[v.Type] - fnSig := pass.TypesInfo.ObjectOf(v.Name).String() - - // Skip checking spans in this function if it's a custom starter/creator. - if config.startSpanMatchersCustomRegex != nil && config.startSpanMatchersCustomRegex.MatchString(fnSig) { - return - } - } - - // Maps each span variable to its defining ValueSpec/AssignStmt. - spanVars := make(map[*ast.Ident]spanVar) - - // Find the set of span vars to analyze. - stack := make([]ast.Node, 0, stackLen) - ast.Inspect(node, func(n ast.Node) bool { - switch n.(type) { - case *ast.FuncLit: - if len(stack) > 0 { - return false // don't stray into nested functions - } - case nil: - stack = stack[:len(stack)-1] // pop - return true - } - stack = append(stack, n) // push - - // Look for [{AssignStmt,ValueSpec} CallExpr SelectorExpr]: - // - // ctx, span := otel.Tracer("app").Start(...) - // ctx, span = otel.Tracer("app").Start(...) - // var ctx, span = otel.Tracer("app").Start(...) - sType, isStart := isSpanStart(pass.TypesInfo, n, config.startSpanMatchers) - if !isStart { - return true - } - - if !isCall(stack[len(stack)-2]) { - return true - } - - stmt := stack[len(stack)-3] - id := getID(stmt) - if id == nil { - pass.ReportRangef(n, "span is unassigned, probable memory leak") - return true - } - - if id.Name == "_" { - pass.ReportRangef(id, "span is unassigned, probable memory leak") - } else if v, ok := pass.TypesInfo.Uses[id].(*types.Var); ok { - // If the span variable is defined outside function scope, - // do not analyze it. - if funcScope.Contains(v.Pos()) { - spanVars[id] = spanVar{ - vr: v, - stmt: stmt, - id: id, - spanType: sType, - } - } - } else if v, ok := pass.TypesInfo.Defs[id].(*types.Var); ok { - spanVars[id] = spanVar{ - vr: v, - stmt: stmt, - id: id, - spanType: sType, - } - } - - return true - }) - - if len(spanVars) == 0 { - return // no need to inspect CFG - } - - // Obtain the CFG. - cfgs := pass.ResultOf[ctrlflow.Analyzer].(*ctrlflow.CFGs) - var g *cfg.CFG - var sig *types.Signature - switch node := node.(type) { - case *ast.FuncDecl: - sig, _ = pass.TypesInfo.Defs[node.Name].Type().(*types.Signature) - g = cfgs.FuncDecl(node) - case *ast.FuncLit: - sig, _ = pass.TypesInfo.Types[node.Type].Type.(*types.Signature) - g = cfgs.FuncLit(node) - } - if sig == nil { - return // missing type information - } - - // Check for missing calls. - for _, sv := range spanVars { - if config.endCheckEnabled { - // Check if there's no End to the span. - if ret := getMissingSpanCalls(pass, g, sv, "End", func(_ *analysis.Pass, ret *ast.ReturnStmt) *ast.ReturnStmt { return ret }, nil, config.startSpanMatchers); ret != nil { - pass.ReportRangef(sv.stmt, "%s.End is not called on all paths, possible memory leak", sv.vr.Name()) - pass.ReportRangef(ret, "return can be reached without calling %s.End", sv.vr.Name()) - } - } - - if config.setStatusEnabled { - // Check if there's no SetStatus to the span setting an error. - if ret := getMissingSpanCalls(pass, g, sv, "SetStatus", getErrorReturn, config.ignoreChecksSignatures, config.startSpanMatchers); ret != nil { - pass.ReportRangef(sv.stmt, "%s.SetStatus is not called on all paths", sv.vr.Name()) - pass.ReportRangef(ret, "return can be reached without calling %s.SetStatus", sv.vr.Name()) - } - } - - if config.recordErrorEnabled && sv.spanType == spanOpenTelemetry { // RecordError only exists in OpenTelemetry - // Check if there's no RecordError to the span setting an error. - if ret := getMissingSpanCalls(pass, g, sv, "RecordError", getErrorReturn, config.ignoreChecksSignatures, config.startSpanMatchers); ret != nil { - pass.ReportRangef(sv.stmt, "%s.RecordError is not called on all paths", sv.vr.Name()) - pass.ReportRangef(ret, "return can be reached without calling %s.RecordError", sv.vr.Name()) - } - } - } -} - -// isSpanStart reports whether n is tracer.Start() -func isSpanStart(info *types.Info, n ast.Node, startSpanMatchers []spanStartMatcher) (spanType, bool) { - sel, ok := n.(*ast.SelectorExpr) - if !ok { - return spanUnset, false - } - - fnSig := info.ObjectOf(sel.Sel).String() - - // Check if the function is a span start function - for _, matcher := range startSpanMatchers { - if matcher.signature.MatchString(fnSig) { - return matcher.spanType, true - } - } - - return 0, false -} - -func isCall(n ast.Node) bool { - _, ok := n.(*ast.CallExpr) - return ok -} - -func getID(node ast.Node) *ast.Ident { - switch stmt := node.(type) { - case *ast.ValueSpec: - if len(stmt.Names) > 1 { - return stmt.Names[1] - } else if len(stmt.Names) == 1 { - return stmt.Names[0] - } - case *ast.AssignStmt: - if len(stmt.Lhs) > 1 { - id, _ := stmt.Lhs[1].(*ast.Ident) - return id - } else if len(stmt.Lhs) == 1 { - id, _ := stmt.Lhs[0].(*ast.Ident) - return id - } - } - return nil -} - -// getMissingSpanCalls finds a path through the CFG, from stmt (which defines -// the 'span' variable v) to a return statement, that doesn't call the passed selector on the span. -func getMissingSpanCalls( - pass *analysis.Pass, - g *cfg.CFG, - sv spanVar, - selName string, - checkErr func(pass *analysis.Pass, ret *ast.ReturnStmt) *ast.ReturnStmt, - ignoreCheckSig *regexp.Regexp, - spanStartMatchers []spanStartMatcher, -) *ast.ReturnStmt { - // blockUses computes "uses" for each block, caching the result. - memo := make(map[*cfg.Block]bool) - blockUses := func(pass *analysis.Pass, b *cfg.Block) bool { - res, ok := memo[b] - if !ok { - res = usesCall(pass, b.Nodes, sv, selName, ignoreCheckSig, spanStartMatchers, 0) - memo[b] = res - } - return res - } - - // Find the var's defining block in the CFG, - // plus the rest of the statements of that block. - var defBlock *cfg.Block - var rest []ast.Node -outer: - for _, b := range g.Blocks { - for i, n := range b.Nodes { - if n == sv.stmt { - defBlock = b - rest = b.Nodes[i+1:] - break outer - } - } - } - - // Is the call "used" in the remainder of its defining block? - if usesCall(pass, rest, sv, selName, ignoreCheckSig, spanStartMatchers, 0) { - return nil - } - - // Does the defining block return without making the call? - if ret := defBlock.Return(); ret != nil { - return checkErr(pass, ret) - } - - // Search the CFG depth-first for a path, from defblock to a - // return block, in which v is never "used". - seen := make(map[*cfg.Block]bool) - var search func(blocks []*cfg.Block) *ast.ReturnStmt - search = func(blocks []*cfg.Block) *ast.ReturnStmt { - for _, b := range blocks { - if seen[b] { - continue - } - seen[b] = true - - // Prune the search if the block uses v. - if blockUses(pass, b) { - continue - } - - // Found path to return statement? - if ret := getErrorReturn(pass, b.Return()); ret != nil { - return ret // found - } - - // Recur - if ret := getErrorReturn(pass, search(b.Succs)); ret != nil { - return ret - } - } - return nil - } - - return search(defBlock.Succs) -} - -// usesCall reports whether stmts contain a use of the selName call on variable v. -func usesCall( - pass *analysis.Pass, - stmts []ast.Node, - sv spanVar, - selName string, - ignoreCheckSig *regexp.Regexp, - startSpanMatchers []spanStartMatcher, - depth int, -) bool { - if depth > 1 { // for perf reasons, do not dive too deep thru func literals, just one level deep check. - return false - } - - found, reAssigned := false, false - for _, subStmt := range stmts { - stack := []ast.Node{} - ast.Inspect(subStmt, func(n ast.Node) bool { - switch n := n.(type) { - case *ast.FuncLit: - if len(stack) > 0 { - cfgs := pass.ResultOf[ctrlflow.Analyzer].(*ctrlflow.CFGs) - g := cfgs.FuncLit(n) - if g != nil && len(g.Blocks) > 0 { - return usesCall(pass, g.Blocks[0].Nodes, sv, selName, ignoreCheckSig, startSpanMatchers, depth+1) - } - - return false - } - case *ast.CallExpr: - if ident, ok := n.Fun.(*ast.Ident); ok { - fnSig := pass.TypesInfo.ObjectOf(ident).String() - if ignoreCheckSig != nil && ignoreCheckSig.MatchString(fnSig) { - found = true - return false - } - } - case nil: - if len(stack) > 0 { - stack = stack[:len(stack)-1] // pop - return true - } - return false - } - stack = append(stack, n) // push - - // Check whether the span was assigned over top of its old value. - _, isStart := isSpanStart(pass.TypesInfo, n, startSpanMatchers) - if isStart { - if id := getID(stack[len(stack)-3]); id != nil && id.Obj.Decl == sv.id.Obj.Decl { - reAssigned = true - return false - } - } - - if n, ok := n.(*ast.SelectorExpr); ok { - // Selector (End, SetStatus, RecordError) hit. - if n.Sel.Name == selName { - id, ok := n.X.(*ast.Ident) - found = ok && id.Obj != nil && id.Obj.Decl == sv.id.Obj.Decl - } - - // Check if an ignore signature matches. - fnSig := pass.TypesInfo.ObjectOf(n.Sel).String() - if ignoreCheckSig != nil && ignoreCheckSig.MatchString(fnSig) { - found = true - } - } - - return !found - }) - } - - return found && !reAssigned -} - -func getErrorReturn(pass *analysis.Pass, ret *ast.ReturnStmt) *ast.ReturnStmt { - if ret == nil { - return nil - } - - for _, r := range ret.Results { - if isErrorType(pass.TypesInfo.TypeOf(r)) { - return ret - } - - if r, ok := r.(*ast.CallExpr); ok { - for _, err := range errorsByArg(pass, r) { - if err { - return ret - } - } - } - } - - return nil -} - -// errorsByArg returns a slice s such that -// len(s) == number of return types of call -// s[i] == true iff return type at position i from left is an error type -// -// copied from https://github.com/kisielk/errcheck/blob/master/errcheck/errcheck.go -func errorsByArg(pass *analysis.Pass, call *ast.CallExpr) []bool { - switch t := pass.TypesInfo.Types[call].Type.(type) { - case *types.Named: - // Single return - return []bool{isErrorType(t)} - case *types.Pointer: - // Single return via pointer - return []bool{isErrorType(t)} - case *types.Tuple: - // Multiple returns - s := make([]bool, t.Len()) - for i := 0; i < t.Len(); i++ { - switch et := t.At(i).Type().(type) { - case *types.Named: - // Single return - s[i] = isErrorType(et) - case *types.Pointer: - // Single return via pointer - s[i] = isErrorType(et) - default: - s[i] = false - } - } - return s - } - return []bool{false} -} - -func isErrorType(t types.Type) bool { - return types.Implements(t, errorType) -} -- cgit mrf-deployment