From 0649f5f184191cad5c12b22ff89dd9a7d4f7fe3a Mon Sep 17 00:00:00 2001 From: Mario Macias Date: Thu, 3 Oct 2024 10:41:31 +0200 Subject: [PATCH] Make EBPF tracer config visible --- pkg/beyla/config.go | 6 ++-- pkg/beyla/config_test.go | 8 ++--- pkg/config/config.go | 3 ++ pkg/config/ebpf_tracer.go | 41 ++++++++++++++++++++++++ pkg/internal/ebpf/common/common.go | 39 ---------------------- pkg/internal/ebpf/common/ringbuf.go | 7 ++-- pkg/internal/ebpf/common/ringbuf_test.go | 7 ++-- pkg/internal/ebpf/gotracer/gotracer.go | 3 +- 8 files changed, 61 insertions(+), 53 deletions(-) create mode 100644 pkg/config/config.go create mode 100644 pkg/config/ebpf_tracer.go diff --git a/pkg/beyla/config.go b/pkg/beyla/config.go index 12255fc98..95bd92610 100644 --- a/pkg/beyla/config.go +++ b/pkg/beyla/config.go @@ -11,12 +11,12 @@ import ( otelconsumer "go.opentelemetry.io/collector/consumer" "gopkg.in/yaml.v3" + "github.com/grafana/beyla/pkg/config" "github.com/grafana/beyla/pkg/export/attributes" "github.com/grafana/beyla/pkg/export/debug" "github.com/grafana/beyla/pkg/export/instrumentations" "github.com/grafana/beyla/pkg/export/otel" "github.com/grafana/beyla/pkg/export/prom" - ebpfcommon "github.com/grafana/beyla/pkg/internal/ebpf/common" "github.com/grafana/beyla/pkg/internal/filter" "github.com/grafana/beyla/pkg/internal/imetrics" "github.com/grafana/beyla/pkg/internal/infraolly/process" @@ -44,7 +44,7 @@ var DefaultConfig = Config{ ChannelBufferLen: 10, LogLevel: "INFO", EnforceSysCaps: false, - EBPF: ebpfcommon.TracerConfig{ + EBPF: config.EPPFTracer{ BatchLength: 100, BatchTimeout: time.Second, BpfBaseDir: "/var/run/beyla", @@ -130,7 +130,7 @@ var DefaultConfig = Config{ } type Config struct { - EBPF ebpfcommon.TracerConfig `yaml:"ebpf"` + EBPF config.EPPFTracer `yaml:"ebpf"` // NetworkFlows configuration for Network Observability feature NetworkFlows NetworkConfig `yaml:"network"` diff --git a/pkg/beyla/config_test.go b/pkg/beyla/config_test.go index 61cd67abd..e8462f325 100644 --- a/pkg/beyla/config_test.go +++ b/pkg/beyla/config_test.go @@ -14,12 +14,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/grafana/beyla/pkg/config" "github.com/grafana/beyla/pkg/export/attributes" "github.com/grafana/beyla/pkg/export/debug" "github.com/grafana/beyla/pkg/export/instrumentations" "github.com/grafana/beyla/pkg/export/otel" "github.com/grafana/beyla/pkg/export/prom" - ebpfcommon "github.com/grafana/beyla/pkg/internal/ebpf/common" "github.com/grafana/beyla/pkg/internal/imetrics" "github.com/grafana/beyla/pkg/internal/infraolly/process" "github.com/grafana/beyla/pkg/internal/netolly/transform/cidr" @@ -110,7 +110,7 @@ network: EnforceSysCaps: false, Printer: false, TracePrinter: "json", - EBPF: ebpfcommon.TracerConfig{ + EBPF: config.EPPFTracer{ BatchLength: 100, BatchTimeout: time.Second, BpfBaseDir: "/var/run/beyla", @@ -412,7 +412,7 @@ time=\S+ level=DEBUG msg=debug arg=debug$`), tracing: true, expectedCfg: Config{ TracePrinter: debug.TracePrinterText, - EBPF: ebpfcommon.TracerConfig{BpfDebug: true}, + EBPF: config.EPPFTracer{BpfDebug: true}, }, }, { name: "debug log with network flows", @@ -426,7 +426,7 @@ time=\S+ level=DEBUG msg=debug arg=debug$`), tracing: true, expectedCfg: Config{ TracePrinter: debug.TracePrinterText, - EBPF: ebpfcommon.TracerConfig{BpfDebug: true}, + EBPF: config.EPPFTracer{BpfDebug: true}, NetworkFlows: NetworkConfig{Enable: true, Print: true}, }, }} { diff --git a/pkg/config/config.go b/pkg/config/config.go new file mode 100644 index 000000000..483f7ea87 --- /dev/null +++ b/pkg/config/config.go @@ -0,0 +1,3 @@ +// Package config contains some configuration options that need to be in a public package +// to let Alloy accessing them +package config diff --git a/pkg/config/ebpf_tracer.go b/pkg/config/ebpf_tracer.go new file mode 100644 index 000000000..f20484f27 --- /dev/null +++ b/pkg/config/ebpf_tracer.go @@ -0,0 +1,41 @@ +package config + +import "time" + +// EPPFTracer configuration for eBPF programs +type EPPFTracer struct { + BpfDebug bool `yaml:"bpf_debug" env:"BEYLA_BPF_DEBUG"` + + // WakeupLen specifies how many messages need to be accumulated in the eBPF ringbuffer + // before sending a wakeup request. + // High values of WakeupLen could add a noticeable metric delay in services with low + // requests/second. + // TODO: see if there is a way to force eBPF to wakeup userspace on timeout + WakeupLen int `yaml:"wakeup_len" env:"BEYLA_BPF_WAKEUP_LEN"` + // BatchLength allows specifying how many traces will be batched at the initial + // stage before being forwarded to the next stage + BatchLength int `yaml:"batch_length" env:"BEYLA_BPF_BATCH_LENGTH"` + // BatchTimeout specifies the timeout to forward the data batch if it didn't + // reach the BatchLength size + BatchTimeout time.Duration `yaml:"batch_timeout" env:"BEYLA_BPF_BATCH_TIMEOUT"` + + // BpfBaseDir specifies the base directory where the BPF pinned maps will be mounted. + // By default, it will be /var/run/beyla + BpfBaseDir string `yaml:"bpf_fs_base_dir" env:"BEYLA_BPF_FS_BASE_DIR"` + + // BpfPath specifies the path in the base directory where the BPF pinned maps will be mounted. + // By default, it will be beyla-. + BpfPath string `yaml:"bpf_fs_path" env:"BEYLA_BPF_FS_PATH"` + + // If enabled, the kprobes based HTTP request tracking will start tracking the request + // headers to process any 'Traceparent' fields. + TrackRequestHeaders bool `yaml:"track_request_headers" env:"BEYLA_BPF_TRACK_REQUEST_HEADERS"` + + HTTPRequestTimeout time.Duration `yaml:"http_request_timeout" env:"BEYLA_BPF_HTTP_REQUEST_TIMEOUT"` + + // Enables Linux Traffic Control probes for context propagation + UseLinuxTC bool `yaml:"enable_traffic_control" env:"BEYLA_BPF_TC"` + + // Optimises for getting requests information immediately when request response is seen + HighRequestVolume bool `yaml:"high_request_volume" env:"BEYLA_BPF_HIGH_REQUEST_VOLUME"` +} diff --git a/pkg/internal/ebpf/common/common.go b/pkg/internal/ebpf/common/common.go index 8248d8203..3060a24cd 100644 --- a/pkg/internal/ebpf/common/common.go +++ b/pkg/internal/ebpf/common/common.go @@ -9,7 +9,6 @@ import ( "net" "os" "strings" - "time" "github.com/cilium/ebpf" "github.com/cilium/ebpf/ringbuf" @@ -43,44 +42,6 @@ var IntegrityModeOverride = false var ActiveNamespaces = make(map[uint32]uint32) -// TracerConfig configuration for eBPF programs -type TracerConfig struct { - BpfDebug bool `yaml:"bpf_debug" env:"BEYLA_BPF_DEBUG"` - - // WakeupLen specifies how many messages need to be accumulated in the eBPF ringbuffer - // before sending a wakeup request. - // High values of WakeupLen could add a noticeable metric delay in services with low - // requests/second. - // TODO: see if there is a way to force eBPF to wakeup userspace on timeout - WakeupLen int `yaml:"wakeup_len" env:"BEYLA_BPF_WAKEUP_LEN"` - // BatchLength allows specifying how many traces will be batched at the initial - // stage before being forwarded to the next stage - BatchLength int `yaml:"batch_length" env:"BEYLA_BPF_BATCH_LENGTH"` - // BatchTimeout specifies the timeout to forward the data batch if it didn't - // reach the BatchLength size - BatchTimeout time.Duration `yaml:"batch_timeout" env:"BEYLA_BPF_BATCH_TIMEOUT"` - - // BpfBaseDir specifies the base directory where the BPF pinned maps will be mounted. - // By default, it will be /var/run/beyla - BpfBaseDir string `yaml:"bpf_fs_base_dir" env:"BEYLA_BPF_FS_BASE_DIR"` - - // BpfPath specifies the path in the base directory where the BPF pinned maps will be mounted. - // By default, it will be beyla-. - BpfPath string `yaml:"bpf_fs_path" env:"BEYLA_BPF_FS_PATH"` - - // If enabled, the kprobes based HTTP request tracking will start tracking the request - // headers to process any 'Traceparent' fields. - TrackRequestHeaders bool `yaml:"track_request_headers" env:"BEYLA_BPF_TRACK_REQUEST_HEADERS"` - - HTTPRequestTimeout time.Duration `yaml:"http_request_timeout" env:"BEYLA_BPF_HTTP_REQUEST_TIMEOUT"` - - // Enables Linux Traffic Control probes for context propagation - UseLinuxTC bool `yaml:"enable_traffic_control" env:"BEYLA_BPF_TC"` - - // Optimises for getting requests information immediately when request response is seen - HighRequestVolume bool `yaml:"high_request_volume" env:"BEYLA_BPF_HIGH_REQUEST_VOLUME"` -} - // Probe holds the information of the instrumentation points of a given function: its start and end offsets and // eBPF programs type Probe struct { diff --git a/pkg/internal/ebpf/common/ringbuf.go b/pkg/internal/ebpf/common/ringbuf.go index 637aaefb4..99831b7bd 100644 --- a/pkg/internal/ebpf/common/ringbuf.go +++ b/pkg/internal/ebpf/common/ringbuf.go @@ -11,6 +11,7 @@ import ( "github.com/cilium/ebpf" "github.com/cilium/ebpf/ringbuf" + "github.com/grafana/beyla/pkg/config" "github.com/grafana/beyla/pkg/internal/imetrics" "github.com/grafana/beyla/pkg/internal/request" ) @@ -29,7 +30,7 @@ var readerFactory = func(rb *ebpf.Map) (ringBufReader, error) { } type ringBufForwarder struct { - cfg *TracerConfig + cfg *config.EPPFTracer logger *slog.Logger ringbuffer *ebpf.Map closers []io.Closer @@ -51,7 +52,7 @@ var singleRbfLock sync.Mutex // internal buffer, and forwards them to an output events channel, previously converted to request.Span // instances. func SharedRingbuf( - cfg *TracerConfig, + cfg *config.EPPFTracer, filter ServiceFilter, ringbuffer *ebpf.Map, metrics imetrics.Reporter, @@ -74,7 +75,7 @@ func SharedRingbuf( } func ForwardRingbuf( - cfg *TracerConfig, + cfg *config.EPPFTracer, ringbuffer *ebpf.Map, filter ServiceFilter, reader func(*ringbuf.Record, ServiceFilter) (request.Span, bool, error), diff --git a/pkg/internal/ebpf/common/ringbuf_test.go b/pkg/internal/ebpf/common/ringbuf_test.go index 634251324..3f1440ac3 100644 --- a/pkg/internal/ebpf/common/ringbuf_test.go +++ b/pkg/internal/ebpf/common/ringbuf_test.go @@ -16,6 +16,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/grafana/beyla/pkg/config" "github.com/grafana/beyla/pkg/internal/imetrics" "github.com/grafana/beyla/pkg/internal/request" "github.com/grafana/beyla/pkg/internal/svc" @@ -33,7 +34,7 @@ func TestForwardRingbuf_CapacityFull(t *testing.T) { fltr := TestPidsFilter{services: map[uint32]svc.ID{}} fltr.AllowPID(1, 1, &svc.ID{Name: "myService"}, PIDTypeGo) go ForwardRingbuf( - &TracerConfig{BatchLength: 10}, + &config.EPPFTracer{BatchLength: 10}, nil, // the source ring buffer can be null &fltr, ReadBPFTraceAsSpan, @@ -85,7 +86,7 @@ func TestForwardRingbuf_Deadline(t *testing.T) { fltr := TestPidsFilter{services: map[uint32]svc.ID{}} fltr.AllowPID(1, 1, &svc.ID{Name: "myService"}, PIDTypeGo) go ForwardRingbuf( - &TracerConfig{BatchLength: 10, BatchTimeout: 20 * time.Millisecond}, + &config.EPPFTracer{BatchLength: 10, BatchTimeout: 20 * time.Millisecond}, nil, // the source ring buffer can be null &fltr, // change fltr to a pointer ReadBPFTraceAsSpan, @@ -125,7 +126,7 @@ func TestForwardRingbuf_Close(t *testing.T) { metrics := &metricsReporter{} closable := closableObject{} go ForwardRingbuf( - &TracerConfig{BatchLength: 10}, + &config.EPPFTracer{BatchLength: 10}, nil, // the source ring buffer can be null (&IdentityPidsFilter{}), ReadBPFTraceAsSpan, diff --git a/pkg/internal/ebpf/gotracer/gotracer.go b/pkg/internal/ebpf/gotracer/gotracer.go index 810e64555..013b1665f 100644 --- a/pkg/internal/ebpf/gotracer/gotracer.go +++ b/pkg/internal/ebpf/gotracer/gotracer.go @@ -23,6 +23,7 @@ import ( "github.com/cilium/ebpf" "github.com/grafana/beyla/pkg/beyla" + "github.com/grafana/beyla/pkg/config" ebpfcommon "github.com/grafana/beyla/pkg/internal/ebpf/common" "github.com/grafana/beyla/pkg/internal/exec" "github.com/grafana/beyla/pkg/internal/goexec" @@ -39,7 +40,7 @@ import ( type Tracer struct { log *slog.Logger pidsFilter ebpfcommon.ServiceFilter - cfg *ebpfcommon.TracerConfig + cfg *config.EPPFTracer metrics imetrics.Reporter bpfObjects bpfObjects closers []io.Closer