diff --git a/CHANGELOG.md b/CHANGELOG.md index 677f6e38f..135b31f86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ OpenTelemetry Go Automatic Instrumentation adheres to [Semantic Versioning](http - Add [gin-gonic/gin](https://github.com/gin-gonic/gin) instrumentation. ([#100](https://github.com/open-telemetry/opentelemetry-go-instrumentation/pull/100)) - Add ARM64 support. ([#82](https://github.com/open-telemetry/opentelemetry-go-instrumentation/pull/82)) +- Add `OTEL_GO_AUTO_SHOW_VERIFIER_LOG` environment variable to control whether + the verifier log is shown. ([#128](https://github.com/open-telemetry/opentelemetry-go-instrumentation/pull/128)) ### Changed diff --git a/pkg/instrumentors/bpf/github.com/gin-gonic/gin/probe.go b/pkg/instrumentors/bpf/github.com/gin-gonic/gin/probe.go index 301a77af3..7c05651b6 100644 --- a/pkg/instrumentors/bpf/github.com/gin-gonic/gin/probe.go +++ b/pkg/instrumentors/bpf/github.com/gin-gonic/gin/probe.go @@ -18,6 +18,7 @@ import ( "bytes" "encoding/binary" "errors" + "os" "go.opentelemetry.io/auto/pkg/instrumentors/bpffs" @@ -30,6 +31,7 @@ import ( "go.opentelemetry.io/auto/pkg/inject" "go.opentelemetry.io/auto/pkg/instrumentors/context" "go.opentelemetry.io/auto/pkg/instrumentors/events" + "go.opentelemetry.io/auto/pkg/instrumentors/utils" "go.opentelemetry.io/auto/pkg/log" "go.opentelemetry.io/otel/attribute" semconv "go.opentelemetry.io/otel/semconv/v1.7.0" @@ -102,7 +104,7 @@ func (h *Instrumentor) Load(ctx *context.InstrumentorContext) error { } h.bpfObjects = &bpfObjects{} - err = spec.LoadAndAssign(h.bpfObjects, &ebpf.CollectionOptions{ + err = utils.LoadEBPFObjects(spec, h.bpfObjects, &ebpf.CollectionOptions{ Maps: ebpf.MapOptions{ PinPath: bpffs.BPFFsPath, }, diff --git a/pkg/instrumentors/bpf/github.com/gorilla/mux/probe.go b/pkg/instrumentors/bpf/github.com/gorilla/mux/probe.go index 249934adc..b14191e11 100644 --- a/pkg/instrumentors/bpf/github.com/gorilla/mux/probe.go +++ b/pkg/instrumentors/bpf/github.com/gorilla/mux/probe.go @@ -30,6 +30,7 @@ import ( "go.opentelemetry.io/auto/pkg/inject" "go.opentelemetry.io/auto/pkg/instrumentors/context" "go.opentelemetry.io/auto/pkg/instrumentors/events" + "go.opentelemetry.io/auto/pkg/instrumentors/utils" "go.opentelemetry.io/auto/pkg/log" "go.opentelemetry.io/otel/attribute" semconv "go.opentelemetry.io/otel/semconv/v1.7.0" @@ -102,7 +103,7 @@ func (g *Instrumentor) Load(ctx *context.InstrumentorContext) error { } g.bpfObjects = &bpfObjects{} - err = spec.LoadAndAssign(g.bpfObjects, &ebpf.CollectionOptions{ + err = utils.LoadEBPFObjects(spec, g.bpfObjects, &ebpf.CollectionOptions{ Maps: ebpf.MapOptions{ PinPath: bpffs.BPFFsPath, }, diff --git a/pkg/instrumentors/bpf/google/golang/org/grpc/probe.go b/pkg/instrumentors/bpf/google/golang/org/grpc/probe.go index fa13540fe..e80e964ab 100644 --- a/pkg/instrumentors/bpf/google/golang/org/grpc/probe.go +++ b/pkg/instrumentors/bpf/google/golang/org/grpc/probe.go @@ -32,6 +32,7 @@ import ( "go.opentelemetry.io/auto/pkg/inject" "go.opentelemetry.io/auto/pkg/instrumentors/context" "go.opentelemetry.io/auto/pkg/instrumentors/events" + "go.opentelemetry.io/auto/pkg/instrumentors/utils" "go.opentelemetry.io/auto/pkg/log" "go.opentelemetry.io/otel/attribute" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" @@ -95,11 +96,12 @@ func (g *Instrumentor) Load(ctx *context.InstrumentorContext) error { } g.bpfObjects = &bpfObjects{} - err = spec.LoadAndAssign(g.bpfObjects, &ebpf.CollectionOptions{ + err = utils.LoadEBPFObjects(spec, g.bpfObjects, &ebpf.CollectionOptions{ Maps: ebpf.MapOptions{ PinPath: bpffs.BPFFsPath, }, }) + if err != nil { return err } diff --git a/pkg/instrumentors/bpf/google/golang/org/grpc/server/probe.go b/pkg/instrumentors/bpf/google/golang/org/grpc/server/probe.go index 78f1491b5..f1c936b79 100644 --- a/pkg/instrumentors/bpf/google/golang/org/grpc/server/probe.go +++ b/pkg/instrumentors/bpf/google/golang/org/grpc/server/probe.go @@ -30,6 +30,7 @@ import ( "go.opentelemetry.io/auto/pkg/inject" "go.opentelemetry.io/auto/pkg/instrumentors/context" "go.opentelemetry.io/auto/pkg/instrumentors/events" + "go.opentelemetry.io/auto/pkg/instrumentors/utils" "go.opentelemetry.io/auto/pkg/log" "go.opentelemetry.io/otel/attribute" semconv "go.opentelemetry.io/otel/semconv/v1.7.0" @@ -113,7 +114,7 @@ func (g *Instrumentor) Load(ctx *context.InstrumentorContext) error { } g.bpfObjects = &bpfObjects{} - err = spec.LoadAndAssign(g.bpfObjects, &ebpf.CollectionOptions{ + err = utils.LoadEBPFObjects(spec, g.bpfObjects, &ebpf.CollectionOptions{ Maps: ebpf.MapOptions{ PinPath: bpffs.BPFFsPath, }, diff --git a/pkg/instrumentors/bpf/net/http/server/probe.go b/pkg/instrumentors/bpf/net/http/server/probe.go index 41d825708..5ae733999 100644 --- a/pkg/instrumentors/bpf/net/http/server/probe.go +++ b/pkg/instrumentors/bpf/net/http/server/probe.go @@ -30,6 +30,7 @@ import ( "go.opentelemetry.io/auto/pkg/inject" "go.opentelemetry.io/auto/pkg/instrumentors/context" "go.opentelemetry.io/auto/pkg/instrumentors/events" + "go.opentelemetry.io/auto/pkg/instrumentors/utils" "go.opentelemetry.io/auto/pkg/log" "go.opentelemetry.io/otel/attribute" semconv "go.opentelemetry.io/otel/semconv/v1.7.0" @@ -101,7 +102,7 @@ func (h *Instrumentor) Load(ctx *context.InstrumentorContext) error { } h.bpfObjects = &bpfObjects{} - err = spec.LoadAndAssign(h.bpfObjects, &ebpf.CollectionOptions{ + err = utils.LoadEBPFObjects(spec, h.bpfObjects, &ebpf.CollectionOptions{ Maps: ebpf.MapOptions{ PinPath: bpffs.BPFFsPath, }, diff --git a/pkg/instrumentors/utils/ebpf.go b/pkg/instrumentors/utils/ebpf.go new file mode 100644 index 000000000..3cad8d98d --- /dev/null +++ b/pkg/instrumentors/utils/ebpf.go @@ -0,0 +1,62 @@ +// 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 utils + +import ( + "errors" + "fmt" + "os" + "strconv" + + "github.com/cilium/ebpf" +) + +const ( + showVerifierLogEnvVar = "OTEL_GO_AUTO_SHOW_VERIFIER_LOG" +) + +// LoadEBPFObjects loads eBPF objects from the given spec into the given interface. +// If the environment variable OTEL_GO_AUTO_SHOW_VERIFIER_LOG is set to true, the verifier log will be printed. +func LoadEBPFObjects(spec *ebpf.CollectionSpec, to interface{}, opts *ebpf.CollectionOptions) error { + // Getting full verifier log is expensive, so we only do it if the user explicitly asks for it. + showVerifierLogs := shouldShowVerifierLogs() + if showVerifierLogs { + opts.Programs.LogSize = ebpf.DefaultVerifierLogSize * 100 + opts.Programs.LogLevel = ebpf.LogLevelInstruction | ebpf.LogLevelBranch | ebpf.LogLevelStats + } + + err := spec.LoadAndAssign(to, opts) + if err != nil && showVerifierLogs { + var ve *ebpf.VerifierError + if errors.As(err, &ve) { + fmt.Printf("Verifier log: %+v\n", ve) + } + } + + return err +} + +// shouldShowVerifierLogs returns if the user has configured verifier logs to be emitted. +func shouldShowVerifierLogs() bool { + val, exists := os.LookupEnv(showVerifierLogEnvVar) + if exists { + boolVal, err := strconv.ParseBool(val) + if err == nil { + return boolVal + } + } + + return false +}