From e11bc16837ac4e58afdfedf379acb442aedbb806 Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Thu, 14 Sep 2023 07:33:30 -0700 Subject: [PATCH] Remove deprecated support for github.com/gorilla/mux (#303) * Remove deprecated support for github.com/gorilla/mux * Add change to changelog --- .github/dependabot.yml | 126 ++++++++++ .github/workflows/kind.yml | 2 +- CHANGELOG.md | 4 + Makefile | 3 +- .../github.com/gorilla/mux/bpf/probe.bpf.c | 92 ------- .../github.com/gorilla/mux/bpf_bpfel_arm64.go | 146 ----------- .../github.com/gorilla/mux/bpf_bpfel_x86.go | 146 ----------- .../bpf/github.com/gorilla/mux/probe.go | 238 ------------------ .../bpf/github.com/gorilla/mux/probe_test.go | 68 ----- internal/pkg/instrumentors/manager.go | 2 - internal/test/e2e/gorillamux/Dockerfile | 4 - internal/test/e2e/gorillamux/go.mod | 6 - internal/test/e2e/gorillamux/go.sum | 2 - internal/test/e2e/gorillamux/main.go | 56 ----- internal/test/e2e/gorillamux/traces.json | 117 --------- internal/test/e2e/gorillamux/verify.bats | 40 --- versions.yaml | 1 - 17 files changed, 132 insertions(+), 921 deletions(-) delete mode 100644 internal/pkg/instrumentors/bpf/github.com/gorilla/mux/bpf/probe.bpf.c delete mode 100644 internal/pkg/instrumentors/bpf/github.com/gorilla/mux/bpf_bpfel_arm64.go delete mode 100644 internal/pkg/instrumentors/bpf/github.com/gorilla/mux/bpf_bpfel_x86.go delete mode 100644 internal/pkg/instrumentors/bpf/github.com/gorilla/mux/probe.go delete mode 100644 internal/pkg/instrumentors/bpf/github.com/gorilla/mux/probe_test.go delete mode 100644 internal/test/e2e/gorillamux/Dockerfile delete mode 100644 internal/test/e2e/gorillamux/go.mod delete mode 100644 internal/test/e2e/gorillamux/go.sum delete mode 100644 internal/test/e2e/gorillamux/main.go delete mode 100644 internal/test/e2e/gorillamux/traces.json delete mode 100644 internal/test/e2e/gorillamux/verify.bats diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 5c5b986bd..0a269668b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -19,6 +19,51 @@ updates: schedule: interval: weekly day: sunday + - package-ecosystem: docker + directory: /examples/httpPlusdb + labels: + - dependencies + - docker + - Skip Changelog + schedule: + interval: weekly + day: sunday + - package-ecosystem: docker + directory: /examples/rolldice + labels: + - dependencies + - docker + - Skip Changelog + schedule: + interval: weekly + day: sunday + - package-ecosystem: docker + directory: /internal/test/e2e/databasesql + labels: + - dependencies + - docker + - Skip Changelog + schedule: + interval: weekly + day: sunday + - package-ecosystem: docker + directory: /internal/test/e2e/gin + labels: + - dependencies + - docker + - Skip Changelog + schedule: + interval: weekly + day: sunday + - package-ecosystem: docker + directory: /internal/test/e2e/nethttp + labels: + - dependencies + - docker + - Skip Changelog + schedule: + interval: weekly + day: sunday - package-ecosystem: docker directory: /offsets-tracker labels: @@ -28,6 +73,24 @@ updates: schedule: interval: weekly day: sunday + - package-ecosystem: docker + directory: /test/e2e/databasesql + labels: + - dependencies + - docker + - Skip Changelog + schedule: + interval: weekly + day: sunday + - package-ecosystem: docker + directory: /test/e2e/gin + labels: + - dependencies + - docker + - Skip Changelog + schedule: + interval: weekly + day: sunday - package-ecosystem: docker directory: /test/e2e/gorillamux labels: @@ -55,6 +118,51 @@ updates: schedule: interval: weekly day: sunday + - package-ecosystem: gomod + directory: /examples/httpPlusdb + labels: + - dependencies + - go + - Skip Changelog + schedule: + interval: weekly + day: sunday + - package-ecosystem: gomod + directory: /examples/rolldice + labels: + - dependencies + - go + - Skip Changelog + schedule: + interval: weekly + day: sunday + - package-ecosystem: gomod + directory: /internal/test/e2e/databasesql + labels: + - dependencies + - go + - Skip Changelog + schedule: + interval: weekly + day: sunday + - package-ecosystem: gomod + directory: /internal/test/e2e/gin + labels: + - dependencies + - go + - Skip Changelog + schedule: + interval: weekly + day: sunday + - package-ecosystem: gomod + directory: /internal/test/e2e/nethttp + labels: + - dependencies + - go + - Skip Changelog + schedule: + interval: weekly + day: sunday - package-ecosystem: gomod directory: /internal/tools labels: @@ -73,6 +181,24 @@ updates: schedule: interval: weekly day: sunday + - package-ecosystem: gomod + directory: /test/e2e/databasesql + labels: + - dependencies + - go + - Skip Changelog + schedule: + interval: weekly + day: sunday + - package-ecosystem: gomod + directory: /test/e2e/gin + labels: + - dependencies + - go + - Skip Changelog + schedule: + interval: weekly + day: sunday - package-ecosystem: gomod directory: /test/e2e/gorillamux labels: diff --git a/.github/workflows/kind.yml b/.github/workflows/kind.yml index 2383e8d18..19f79ab15 100644 --- a/.github/workflows/kind.yml +++ b/.github/workflows/kind.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: k8s-version: ["v1.26.0"] - library: ["gorillamux", "nethttp", "gin", "databasesql"] + library: ["nethttp", "gin", "databasesql"] runs-on: ubuntu-latest steps: - name: Checkout Repo diff --git a/CHANGELOG.md b/CHANGELOG.md index cb7082621..7b9018998 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ OpenTelemetry Go Automatic Instrumentation adheres to [Semantic Versioning](http ## [Unreleased] +### Removed + +- The deprecated instrumentation support for `github.com/gorilla/mux` is removed. ([#303](https://github.com/open-telemetry/opentelemetry-go-instrumentation/pull/303)) + ## [v0.3.0-alpha] - 2023-09-12 ### Added diff --git a/Makefile b/Makefile index 3f0386cf3..07e53429e 100644 --- a/Makefile +++ b/Makefile @@ -133,9 +133,8 @@ license-header-check: exit 1; \ fi -.PHONY: fixture-nethttp fixture-gorillamux fixture-gin fixture-databasesql +.PHONY: fixture-nethttp fixture-gin fixture-databasesql fixture-nethttp: fixtures/nethttp -fixture-gorillamux: fixtures/gorillamux fixture-gin: fixtures/gin fixture-databasesql: fixtures/databasesql fixtures/%: LIBRARY=$* diff --git a/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/bpf/probe.bpf.c b/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/bpf/probe.bpf.c deleted file mode 100644 index cc3eb479f..000000000 --- a/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/bpf/probe.bpf.c +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "arguments.h" -#include "span_context.h" -#include "go_context.h" -#include "uprobe.h" - -char __license[] SEC("license") = "Dual MIT/GPL"; - -#define PATH_MAX_LEN 100 -#define METHOD_MAX_LEN 7 -#define MAX_CONCURRENT 50 - -struct http_request_t { - BASE_SPAN_PROPERTIES - char method[METHOD_MAX_LEN]; - char path[PATH_MAX_LEN]; -}; - -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __type(key, void *); - __type(value, struct http_request_t); - __uint(max_entries, MAX_CONCURRENT); -} http_events SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); -} events SEC(".maps"); - -// Injected in init -volatile const u64 method_ptr_pos; -volatile const u64 url_ptr_pos; -volatile const u64 path_ptr_pos; -volatile const u64 ctx_ptr_pos; - -// This instrumentation attaches uprobe to the following function: -// func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) -SEC("uprobe/GorillaMux_ServeHTTP") -int uprobe_GorillaMux_ServeHTTP(struct pt_regs *ctx) { - u64 request_pos = 4; - struct http_request_t httpReq = {}; - httpReq.start_time = bpf_ktime_get_ns(); - - // Get request struct - void *req_ptr = get_argument(ctx, request_pos); - - // Get method from request - void *method_ptr = 0; - bpf_probe_read(&method_ptr, sizeof(method_ptr), (void *)(req_ptr + method_ptr_pos)); - u64 method_len = 0; - bpf_probe_read(&method_len, sizeof(method_len), (void *)(req_ptr + (method_ptr_pos + 8))); - u64 method_size = sizeof(httpReq.method); - method_size = method_size < method_len ? method_size : method_len; - bpf_probe_read(&httpReq.method, method_size, method_ptr); - - // get path from Request.URL - void *url_ptr = 0; - bpf_probe_read(&url_ptr, sizeof(url_ptr), (void *)(req_ptr + url_ptr_pos)); - void *path_ptr = 0; - bpf_probe_read(&path_ptr, sizeof(path_ptr), (void *)(url_ptr + path_ptr_pos)); - u64 path_len = 0; - bpf_probe_read(&path_len, sizeof(path_len), (void *)(url_ptr + (path_ptr_pos + 8))); - u64 path_size = sizeof(httpReq.path); - path_size = path_size < path_len ? path_size : path_len; - bpf_probe_read(&httpReq.path, path_size, path_ptr); - - // Get key - void *req_ctx_ptr = 0; - bpf_probe_read(&req_ctx_ptr, sizeof(req_ctx_ptr), (void *)(req_ptr + ctx_ptr_pos)); - void *key = get_consistent_key(ctx, (void *)(req_ptr + ctx_ptr_pos)); - - // Write event - httpReq.sc = generate_span_context(); - bpf_map_update_elem(&http_events, &key, &httpReq, 0); - start_tracking_span(req_ctx_ptr, &httpReq.sc); - return 0; -} - -UPROBE_RETURN(GorillaMux_ServeHTTP, struct http_request_t, 4, ctx_ptr_pos, http_events, events) \ No newline at end of file diff --git a/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/bpf_bpfel_arm64.go b/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/bpf_bpfel_arm64.go deleted file mode 100644 index cfc195ab5..000000000 --- a/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/bpf_bpfel_arm64.go +++ /dev/null @@ -1,146 +0,0 @@ -// Code generated by bpf2go; DO NOT EDIT. -//go:build arm64 - -package mux - -import ( - "bytes" - _ "embed" - "fmt" - "io" - - "github.com/cilium/ebpf" -) - -type bpfHttpRequestT struct { - StartTime uint64 - EndTime uint64 - Sc bpfSpanContext - Psc bpfSpanContext - Method [7]int8 - Path [100]int8 - _ [5]byte -} - -type bpfSpanContext struct { - TraceID [16]uint8 - SpanID [8]uint8 -} - -// loadBpf returns the embedded CollectionSpec for bpf. -func loadBpf() (*ebpf.CollectionSpec, error) { - reader := bytes.NewReader(_BpfBytes) - spec, err := ebpf.LoadCollectionSpecFromReader(reader) - if err != nil { - return nil, fmt.Errorf("can't load bpf: %w", err) - } - - return spec, err -} - -// loadBpfObjects loads bpf and converts it into a struct. -// -// The following types are suitable as obj argument: -// -// *bpfObjects -// *bpfPrograms -// *bpfMaps -// -// See ebpf.CollectionSpec.LoadAndAssign documentation for details. -func loadBpfObjects(obj interface{}, opts *ebpf.CollectionOptions) error { - spec, err := loadBpf() - if err != nil { - return err - } - - return spec.LoadAndAssign(obj, opts) -} - -// bpfSpecs contains maps and programs before they are loaded into the kernel. -// -// It can be passed ebpf.CollectionSpec.Assign. -type bpfSpecs struct { - bpfProgramSpecs - bpfMapSpecs -} - -// bpfSpecs contains programs before they are loaded into the kernel. -// -// It can be passed ebpf.CollectionSpec.Assign. -type bpfProgramSpecs struct { - UprobeGorillaMuxServeHTTP *ebpf.ProgramSpec `ebpf:"uprobe_GorillaMux_ServeHTTP"` - UprobeGorillaMuxServeHTTP_Returns *ebpf.ProgramSpec `ebpf:"uprobe_GorillaMux_ServeHTTP_Returns"` -} - -// bpfMapSpecs contains maps before they are loaded into the kernel. -// -// It can be passed ebpf.CollectionSpec.Assign. -type bpfMapSpecs struct { - Events *ebpf.MapSpec `ebpf:"events"` - HttpEvents *ebpf.MapSpec `ebpf:"http_events"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` - TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` -} - -// bpfObjects contains all objects after they have been loaded into the kernel. -// -// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. -type bpfObjects struct { - bpfPrograms - bpfMaps -} - -func (o *bpfObjects) Close() error { - return _BpfClose( - &o.bpfPrograms, - &o.bpfMaps, - ) -} - -// bpfMaps contains all maps after they have been loaded into the kernel. -// -// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. -type bpfMaps struct { - Events *ebpf.Map `ebpf:"events"` - HttpEvents *ebpf.Map `ebpf:"http_events"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` - TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` -} - -func (m *bpfMaps) Close() error { - return _BpfClose( - m.Events, - m.HttpEvents, - m.TrackedSpans, - m.TrackedSpansBySc, - ) -} - -// bpfPrograms contains all programs after they have been loaded into the kernel. -// -// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. -type bpfPrograms struct { - UprobeGorillaMuxServeHTTP *ebpf.Program `ebpf:"uprobe_GorillaMux_ServeHTTP"` - UprobeGorillaMuxServeHTTP_Returns *ebpf.Program `ebpf:"uprobe_GorillaMux_ServeHTTP_Returns"` -} - -func (p *bpfPrograms) Close() error { - return _BpfClose( - p.UprobeGorillaMuxServeHTTP, - p.UprobeGorillaMuxServeHTTP_Returns, - ) -} - -func _BpfClose(closers ...io.Closer) error { - for _, closer := range closers { - if err := closer.Close(); err != nil { - return err - } - } - return nil -} - -// Do not access this directly. -// -//go:embed bpf_bpfel_arm64.o -var _BpfBytes []byte diff --git a/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/bpf_bpfel_x86.go b/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/bpf_bpfel_x86.go deleted file mode 100644 index c43f1c91e..000000000 --- a/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/bpf_bpfel_x86.go +++ /dev/null @@ -1,146 +0,0 @@ -// Code generated by bpf2go; DO NOT EDIT. -//go:build 386 || amd64 - -package mux - -import ( - "bytes" - _ "embed" - "fmt" - "io" - - "github.com/cilium/ebpf" -) - -type bpfHttpRequestT struct { - StartTime uint64 - EndTime uint64 - Sc bpfSpanContext - Psc bpfSpanContext - Method [7]int8 - Path [100]int8 - _ [5]byte -} - -type bpfSpanContext struct { - TraceID [16]uint8 - SpanID [8]uint8 -} - -// loadBpf returns the embedded CollectionSpec for bpf. -func loadBpf() (*ebpf.CollectionSpec, error) { - reader := bytes.NewReader(_BpfBytes) - spec, err := ebpf.LoadCollectionSpecFromReader(reader) - if err != nil { - return nil, fmt.Errorf("can't load bpf: %w", err) - } - - return spec, err -} - -// loadBpfObjects loads bpf and converts it into a struct. -// -// The following types are suitable as obj argument: -// -// *bpfObjects -// *bpfPrograms -// *bpfMaps -// -// See ebpf.CollectionSpec.LoadAndAssign documentation for details. -func loadBpfObjects(obj interface{}, opts *ebpf.CollectionOptions) error { - spec, err := loadBpf() - if err != nil { - return err - } - - return spec.LoadAndAssign(obj, opts) -} - -// bpfSpecs contains maps and programs before they are loaded into the kernel. -// -// It can be passed ebpf.CollectionSpec.Assign. -type bpfSpecs struct { - bpfProgramSpecs - bpfMapSpecs -} - -// bpfSpecs contains programs before they are loaded into the kernel. -// -// It can be passed ebpf.CollectionSpec.Assign. -type bpfProgramSpecs struct { - UprobeGorillaMuxServeHTTP *ebpf.ProgramSpec `ebpf:"uprobe_GorillaMux_ServeHTTP"` - UprobeGorillaMuxServeHTTP_Returns *ebpf.ProgramSpec `ebpf:"uprobe_GorillaMux_ServeHTTP_Returns"` -} - -// bpfMapSpecs contains maps before they are loaded into the kernel. -// -// It can be passed ebpf.CollectionSpec.Assign. -type bpfMapSpecs struct { - Events *ebpf.MapSpec `ebpf:"events"` - HttpEvents *ebpf.MapSpec `ebpf:"http_events"` - TrackedSpans *ebpf.MapSpec `ebpf:"tracked_spans"` - TrackedSpansBySc *ebpf.MapSpec `ebpf:"tracked_spans_by_sc"` -} - -// bpfObjects contains all objects after they have been loaded into the kernel. -// -// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. -type bpfObjects struct { - bpfPrograms - bpfMaps -} - -func (o *bpfObjects) Close() error { - return _BpfClose( - &o.bpfPrograms, - &o.bpfMaps, - ) -} - -// bpfMaps contains all maps after they have been loaded into the kernel. -// -// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. -type bpfMaps struct { - Events *ebpf.Map `ebpf:"events"` - HttpEvents *ebpf.Map `ebpf:"http_events"` - TrackedSpans *ebpf.Map `ebpf:"tracked_spans"` - TrackedSpansBySc *ebpf.Map `ebpf:"tracked_spans_by_sc"` -} - -func (m *bpfMaps) Close() error { - return _BpfClose( - m.Events, - m.HttpEvents, - m.TrackedSpans, - m.TrackedSpansBySc, - ) -} - -// bpfPrograms contains all programs after they have been loaded into the kernel. -// -// It can be passed to loadBpfObjects or ebpf.CollectionSpec.LoadAndAssign. -type bpfPrograms struct { - UprobeGorillaMuxServeHTTP *ebpf.Program `ebpf:"uprobe_GorillaMux_ServeHTTP"` - UprobeGorillaMuxServeHTTP_Returns *ebpf.Program `ebpf:"uprobe_GorillaMux_ServeHTTP_Returns"` -} - -func (p *bpfPrograms) Close() error { - return _BpfClose( - p.UprobeGorillaMuxServeHTTP, - p.UprobeGorillaMuxServeHTTP_Returns, - ) -} - -func _BpfClose(closers ...io.Closer) error { - for _, closer := range closers { - if err := closer.Close(); err != nil { - return err - } - } - return nil -} - -// Do not access this directly. -// -//go:embed bpf_bpfel_x86.o -var _BpfBytes []byte diff --git a/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/probe.go b/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/probe.go deleted file mode 100644 index 9bea9c450..000000000 --- a/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/probe.go +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package mux provides an instrumentation probe for the github.com/gorilla/mux -// package. -// -// Deprecated: This package will be removed in the next release. -package mux - -import ( - "bytes" - "encoding/binary" - "errors" - "os" - - "go.opentelemetry.io/auto/internal/pkg/instrumentors/bpffs" - - "github.com/cilium/ebpf" - "github.com/cilium/ebpf/link" - "github.com/cilium/ebpf/perf" - "golang.org/x/sys/unix" - - "go.opentelemetry.io/auto/internal/pkg/inject" - "go.opentelemetry.io/auto/internal/pkg/instrumentors/context" - "go.opentelemetry.io/auto/internal/pkg/instrumentors/events" - "go.opentelemetry.io/auto/internal/pkg/instrumentors/utils" - "go.opentelemetry.io/auto/internal/pkg/log" - "go.opentelemetry.io/otel/attribute" - semconv "go.opentelemetry.io/otel/semconv/v1.18.0" - "go.opentelemetry.io/otel/trace" -) - -//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -target amd64,arm64 -cc clang -cflags $CFLAGS bpf ./bpf/probe.bpf.c - -const instrumentedPkg = "github.com/gorilla/mux" - -// Event represents an event in the gorilla/mux server during an HTTP -// request-response. -type Event struct { - context.BaseSpanProperties - Method [7]byte - Path [100]byte -} - -// Instrumentor is the gorilla/mux instrumentor. -type Instrumentor struct { - bpfObjects *bpfObjects - uprobes []link.Link - returnProbs []link.Link - eventsReader *perf.Reader -} - -// New returns a new [Instrumentor]. -func New() *Instrumentor { - return &Instrumentor{} -} - -// LibraryName returns the gorilla/mux package import path. -func (g *Instrumentor) LibraryName() string { - return instrumentedPkg -} - -// FuncNames returns the function names from "github.com/gorilla/mux" that are -// instrumented. -func (g *Instrumentor) FuncNames() []string { - return []string{"github.com/gorilla/mux.(*Router).ServeHTTP"} -} - -// Load loads all instrumentation offsets. -func (g *Instrumentor) Load(ctx *context.InstrumentorContext) error { - spec, err := ctx.Injector.Inject(loadBpf, "go", ctx.TargetDetails.GoVersion.Original(), []*inject.StructField{ - { - VarName: "method_ptr_pos", - StructName: "net/http.Request", - Field: "Method", - }, - { - VarName: "url_ptr_pos", - StructName: "net/http.Request", - Field: "URL", - }, - { - VarName: "ctx_ptr_pos", - StructName: "net/http.Request", - Field: "ctx", - }, - { - VarName: "path_ptr_pos", - StructName: "net/url.URL", - Field: "Path", - }, - }, nil, false) - - if err != nil { - return err - } - - g.bpfObjects = &bpfObjects{} - err = utils.LoadEBPFObjects(spec, g.bpfObjects, &ebpf.CollectionOptions{ - Maps: ebpf.MapOptions{ - PinPath: bpffs.PathForTargetApplication(ctx.TargetDetails), - }, - }) - if err != nil { - return err - } - - for _, funcName := range g.FuncNames() { - g.registerProbes(ctx, funcName) - } - rd, err := perf.NewReader(g.bpfObjects.Events, os.Getpagesize()) - if err != nil { - return err - } - g.eventsReader = rd - - return nil -} - -func (g *Instrumentor) registerProbes(ctx *context.InstrumentorContext, funcName string) { - logger := log.Logger.WithName("gorilla/mux-instrumentor").WithValues("function", funcName) - offset, err := ctx.TargetDetails.GetFunctionOffset(funcName) - if err != nil { - logger.Error(err, "could not find function start offset. Skipping") - return - } - retOffsets, err := ctx.TargetDetails.GetFunctionReturns(funcName) - if err != nil { - logger.Error(err, "could not find function end offset. Skipping") - return - } - - up, err := ctx.Executable.Uprobe("", g.bpfObjects.UprobeGorillaMuxServeHTTP, &link.UprobeOptions{ - Address: offset, - }) - if err != nil { - logger.Error(err, "could not insert start uprobe. Skipping") - return - } - - g.uprobes = append(g.uprobes, up) - - for _, ret := range retOffsets { - retProbe, err := ctx.Executable.Uprobe("", g.bpfObjects.UprobeGorillaMuxServeHTTP_Returns, &link.UprobeOptions{ - Address: ret, - }) - if err != nil { - logger.Error(err, "could not insert return uprobe. Skipping") - return - } - g.returnProbs = append(g.returnProbs, retProbe) - } -} - -// Run runs the events processing loop. -func (g *Instrumentor) Run(eventsChan chan<- *events.Event) { - logger := log.Logger.WithName("gorilla/mux-instrumentor") - var event Event - for { - record, err := g.eventsReader.Read() - if err != nil { - if errors.Is(err, perf.ErrClosed) { - return - } - logger.Error(err, "error reading from perf reader") - continue - } - - if record.LostSamples != 0 { - logger.V(0).Info("perf event ring buffer full", "dropped", record.LostSamples) - continue - } - - if err := binary.Read(bytes.NewBuffer(record.RawSample), binary.LittleEndian, &event); err != nil { - logger.Error(err, "error parsing perf event") - continue - } - - eventsChan <- g.convertEvent(&event) - } -} - -func (g *Instrumentor) convertEvent(e *Event) *events.Event { - method := unix.ByteSliceToString(e.Method[:]) - path := unix.ByteSliceToString(e.Path[:]) - - sc := trace.NewSpanContext(trace.SpanContextConfig{ - TraceID: e.SpanContext.TraceID, - SpanID: e.SpanContext.SpanID, - TraceFlags: trace.FlagsSampled, - }) - - return &events.Event{ - Library: g.LibraryName(), - // Do not include the high-cardinality path here (there is no - // templatized path manifest to reference). - Name: method, - Kind: trace.SpanKindServer, - StartTime: int64(e.StartTime), - EndTime: int64(e.EndTime), - SpanContext: &sc, - Attributes: []attribute.KeyValue{ - semconv.HTTPMethodKey.String(method), - semconv.HTTPTargetKey.String(path), - }, - } -} - -// Close stops the Instrumentor. -func (g *Instrumentor) Close() { - log.Logger.V(0).Info("closing gorilla/mux instrumentor") - if g.eventsReader != nil { - g.eventsReader.Close() - } - - for _, r := range g.uprobes { - r.Close() - } - - for _, r := range g.returnProbs { - r.Close() - } - - if g.bpfObjects != nil { - g.bpfObjects.Close() - } -} diff --git a/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/probe_test.go b/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/probe_test.go deleted file mode 100644 index 43facbab2..000000000 --- a/internal/pkg/instrumentors/bpf/github.com/gorilla/mux/probe_test.go +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package mux - -import ( - "testing" - "time" - - "github.com/stretchr/testify/assert" - - "go.opentelemetry.io/auto/internal/pkg/instrumentors/context" - "go.opentelemetry.io/auto/internal/pkg/instrumentors/events" - "go.opentelemetry.io/otel/attribute" - semconv "go.opentelemetry.io/otel/semconv/v1.7.0" - "go.opentelemetry.io/otel/trace" -) - -func TestInstrumentorConvertEvent(t *testing.T) { - start := time.Now() - end := start.Add(1 * time.Second) - - traceID := trace.TraceID{1} - spanID := trace.SpanID{1} - - i := New() - got := i.convertEvent(&Event{ - BaseSpanProperties: context.BaseSpanProperties{ - StartTime: uint64(start.UnixNano()), - EndTime: uint64(end.UnixNano()), - SpanContext: context.EBPFSpanContext{TraceID: traceID, SpanID: spanID}, - }, - // "GET" - Method: [7]byte{0x47, 0x45, 0x54}, - // "/foo/bar" - Path: [100]byte{0x2f, 0x66, 0x6f, 0x6f, 0x2f, 0x62, 0x61, 0x72}, - }) - - sc := trace.NewSpanContext(trace.SpanContextConfig{ - TraceID: traceID, - SpanID: spanID, - TraceFlags: trace.FlagsSampled, - }) - want := &events.Event{ - Library: instrumentedPkg, - Name: "GET", - Kind: trace.SpanKindServer, - StartTime: int64(start.UnixNano()), - EndTime: int64(end.UnixNano()), - SpanContext: &sc, - Attributes: []attribute.KeyValue{ - semconv.HTTPMethodKey.String("GET"), - semconv.HTTPTargetKey.String("/foo/bar"), - }, - } - assert.Equal(t, want, got) -} diff --git a/internal/pkg/instrumentors/manager.go b/internal/pkg/instrumentors/manager.go index c478aa614..dd9522d9f 100644 --- a/internal/pkg/instrumentors/manager.go +++ b/internal/pkg/instrumentors/manager.go @@ -20,7 +20,6 @@ import ( "go.opentelemetry.io/auto/internal/pkg/instrumentors/allocator" dbSql "go.opentelemetry.io/auto/internal/pkg/instrumentors/bpf/database/sql" "go.opentelemetry.io/auto/internal/pkg/instrumentors/bpf/github.com/gin-gonic/gin" - gorillaMux "go.opentelemetry.io/auto/internal/pkg/instrumentors/bpf/github.com/gorilla/mux" // nolint:staticcheck // TODO: remove in #263 "go.opentelemetry.io/auto/internal/pkg/instrumentors/bpf/google.golang.org/grpc" grpcServer "go.opentelemetry.io/auto/internal/pkg/instrumentors/bpf/google.golang.org/grpc/server" httpClient "go.opentelemetry.io/auto/internal/pkg/instrumentors/bpf/net/http/client" @@ -116,7 +115,6 @@ func registerInstrumentors(m *Manager) error { grpcServer.New(), httpServer.New(), httpClient.New(), - gorillaMux.New(), gin.New(), dbSql.New(), } diff --git a/internal/test/e2e/gorillamux/Dockerfile b/internal/test/e2e/gorillamux/Dockerfile deleted file mode 100644 index 646ec7a43..000000000 --- a/internal/test/e2e/gorillamux/Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -FROM golang:1.20 -WORKDIR /sample-app -COPY . . -RUN go build -o main diff --git a/internal/test/e2e/gorillamux/go.mod b/internal/test/e2e/gorillamux/go.mod deleted file mode 100644 index a3f1c02b9..000000000 --- a/internal/test/e2e/gorillamux/go.mod +++ /dev/null @@ -1,6 +0,0 @@ -// Deprecated: This module will be removed in the next release. -module go.opentelemetry.io/auto/internal/test/e2e/gorillamux - -go 1.20 - -require github.com/gorilla/mux v1.8.0 diff --git a/internal/test/e2e/gorillamux/go.sum b/internal/test/e2e/gorillamux/go.sum deleted file mode 100644 index 535028803..000000000 --- a/internal/test/e2e/gorillamux/go.sum +++ /dev/null @@ -1,2 +0,0 @@ -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= diff --git a/internal/test/e2e/gorillamux/main.go b/internal/test/e2e/gorillamux/main.go deleted file mode 100644 index 403e0cabf..000000000 --- a/internal/test/e2e/gorillamux/main.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright The OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import ( - "fmt" - "io" - "log" - "net/http" - "time" - - "github.com/gorilla/mux" -) - -func main() { - r := mux.NewRouter() - - r.HandleFunc("/users/{user}", func(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - user := vars["user"] - fmt.Fprintf(w, "Hello user %s\n", user) - }) - go func() { - _ = http.ListenAndServe(":8080", r) - }() - - // give time for auto-instrumentation to start up - time.Sleep(5 * time.Second) - - resp, err := http.Get("http://localhost:8080/users/foo") - if err != nil { - log.Fatal(err) - } - body, err := io.ReadAll(resp.Body) - if err != nil { - log.Fatal(err) - } - - log.Printf("Body: %s\n", string(body)) - _ = resp.Body.Close() - - // give time for auto-instrumentation to report signal - time.Sleep(5 * time.Second) -} diff --git a/internal/test/e2e/gorillamux/traces.json b/internal/test/e2e/gorillamux/traces.json deleted file mode 100644 index 8307fe3bd..000000000 --- a/internal/test/e2e/gorillamux/traces.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "resourceSpans": [ - { - "resource": { - "attributes": [ - { - "key": "service.name", - "value": { - "stringValue": "sample-app" - } - }, - { - "key": "telemetry.auto.version", - "value": { - "stringValue": "v0.3.0-alpha" - } - }, - { - "key": "telemetry.sdk.language", - "value": { - "stringValue": "go" - } - } - ] - }, - "scopeSpans": [ - { - "scope": { - "name": "github.com/gorilla/mux" - }, - "spans": [ - { - "attributes": [ - { - "key": "http.method", - "value": { - "stringValue": "GET" - } - }, - { - "key": "http.target", - "value": { - "stringValue": "/users/foo" - } - } - ], - "kind": 2, - "name": "GET", - "parentSpanId": "", - "spanId": "xxxxx", - "status": {}, - "traceId": "xxxxx" - } - ] - }, - { - "scope": { - "name": "net/http" - }, - "spans": [ - { - "attributes": [ - { - "key": "http.method", - "value": { - "stringValue": "GET" - } - }, - { - "key": "http.target", - "value": { - "stringValue": "/users/foo" - } - } - ], - "kind": 2, - "name": "GET", - "parentSpanId": "xxxxx", - "spanId": "xxxxx", - "status": {}, - "traceId": "xxxxx" - } - ] - }, - { - "scope": { - "name": "net/http/client" - }, - "spans": [ - { - "attributes": [ - { - "key": "http.method", - "value": { - "stringValue": "GET" - } - }, - { - "key": "http.target", - "value": { - "stringValue": "/users/foo" - } - } - ], - "kind": 3, - "name": "/users/foo", - "parentSpanId": "", - "spanId": "xxxxx", - "status": {}, - "traceId": "xxxxx" - } - ] - } - ] - } - ] -} diff --git a/internal/test/e2e/gorillamux/verify.bats b/internal/test/e2e/gorillamux/verify.bats deleted file mode 100644 index 9b0624218..000000000 --- a/internal/test/e2e/gorillamux/verify.bats +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bats - -load ../../test_helpers/utilities - -LIBRARY_NAME="github.com/gorilla/mux" - -@test "go-auto :: includes service.name in resource attributes" { - result=$(resource_attributes_received | jq "select(.key == \"service.name\").value.stringValue") - assert_equal "$result" '"sample-app"' -} - -@test "${LIBRARY_NAME} :: emits a span name '{http.method}' (per semconv)" { - result=$(span_names_for ${LIBRARY_NAME}) - assert_equal "$result" '"GET"' -} - -@test "${LIBRARY_NAME} :: includes http.method attribute" { - result=$(span_attributes_for ${LIBRARY_NAME} | jq "select(.key == \"http.method\").value.stringValue") - assert_equal "$result" '"GET"' -} - -@test "${LIBRARY_NAME} :: includes http.target attribute" { - result=$(span_attributes_for ${LIBRARY_NAME} | jq "select(.key == \"http.target\").value.stringValue") - assert_equal "$result" '"/users/foo"' -} - -@test "${LIBRARY_NAME} :: trace ID present and valid in all spans" { - trace_id=$(spans_from_scope_named ${LIBRARY_NAME} | jq ".traceId") - assert_regex "$trace_id" ${MATCH_A_TRACE_ID} -} - -@test "${LIBRARY_NAME} :: span ID present and valid in all spans" { - span_id=$(spans_from_scope_named ${LIBRARY_NAME} | jq ".spanId") - assert_regex "$span_id" ${MATCH_A_SPAN_ID} -} - -@test "${LIBRARY_NAME} :: expected (redacted) trace output" { - redact_json - assert_equal "$(git --no-pager diff ${BATS_TEST_DIRNAME}/traces.json)" "" -} diff --git a/versions.yaml b/versions.yaml index 6d61f8a09..8492e15aa 100644 --- a/versions.yaml +++ b/versions.yaml @@ -20,7 +20,6 @@ module-sets: - go.opentelemetry.io/auto/examples/rolldice - go.opentelemetry.io/auto/offsets-tracker - go.opentelemetry.io/auto/test/e2e/gin - - go.opentelemetry.io/auto/test/e2e/gorillamux - go.opentelemetry.io/auto/test/e2e/nethttp excluded-modules: - github.com/hashicorp/go-version