Skip to content

How to Add a New Probe

Relevant source files

The following files were used as context for generating this wiki page:

This guide provides a step-by-step technical walkthrough for developers looking to extend eCapture by adding a new probe. eCapture utilizes a standardized "Probe Framework" that decouples the eBPF kernel logic from the userspace control plane, allowing for consistent lifecycle management and event processing.

1. Overview of the Probe Architecture

Adding a new probe involves implementing several interfaces and registering the new module with the central factory. The data flow starts in the kernel with an eBPF program, travels through a perf/ring buffer, is decoded in userspace, and finally dispatched to the output pipeline.

Probe Component Relationship

The following diagram illustrates how the different code entities interact during the lifecycle of a probe.

Entity Interaction Diagram

Sources: internal/domain/configuration.go:1-50, internal/factory/factory.go:1-100, internal/probe/base/base_probe.go:1-50


2. Step-by-Step Implementation

Step 1: Define the Configuration

Create a new directory internal/probe/<name>/ and implement the Configuration interface. Most probes should embed config.BaseConfig to inherit common flags like PID and UID filtering.

  • File: internal/probe/<name>/config.go
  • Action: Implement Check(), GetBPFFileName(), and SetPayloadTruncSize().

Example (based on Bash): cli/cmd/bash.go:24-38

Step 2: Implement the Probe Logic

The Probe struct must implement the domain.Probe interface. It is highly recommended to embed *base.BaseProbe to handle the boilerplate of event reading and lifecycle management.

Step 3: Write the eBPF Kernel Program

The C program resides in kern/. It defines the maps and the probes (uprobes, kprobes, etc.).

Step 4: Define the Event Decoder

Userspace needs to know how to parse the raw bytes from the kernel.

  • File: internal/probe/<name>/event.go
  • Action: Create a struct that matches the C struct event exactly. Implement Decode() and String() methods. kern/bash_kern.c:17-24 (C side) vs userspace decoding.

Step 5: Bytecode Embedding

eCapture embeds bytecode into the Go binary using go-bindata.

  1. Add your C file to the Makefile build targets.
  2. Run make to compile the C code into .o files in ebpfassets/bytecode/.
  3. The assets package will automatically include the new files. internal/probe/gotls/gotls_probe.go:116-119

Step 6: Registration and CLI

  1. Register in Factory: Add your probe type to internal/factory/factory.go.
  2. Add CLI Command: Create cli/cmd/<name>.go. Define a Cobra command that initializes your config and calls runProbe(). cli/cmd/bash.go:27-55

3. Comparison: Bash vs. MySQL Probes

Different probes use different hook strategies. Understanding these helps in choosing the right approach for a new probe.

FeatureBash ProbeMySQL Probe
Hook Typeuretprobe on readlineuprobe & uretprobe on dispatch_command
Data SourceReturn value (string pointer)Function parameters (command + packet)
State TrackingSimple event outputUses BPF_MAP_TYPE_HASH to link entry/exit
C Codekern/bash_kern.c:42-64kern/mysqld_kern.c:43-91
Go Configcli/cmd/bash.go:35-40cli/cmd/mysqld.go:39-46

4. Developer Checklist

Before submitting a Pull Request for a new probe, ensure the following are complete:

  • [ ] Kernel Code: C program in kern/ uses ecapture.h and implements filtering.
  • [ ] Userspace Probe: Implements Initialize, Start, Stop, and Close.
  • [ ] Event Decoding: Struct alignment matches C struct (watch for padding).
  • [ ] Factory: Probe registered in internal/factory/.
  • [ ] CLI: New subcommand added in cli/cmd/ with appropriate flags.
  • [ ] Documentation: Added to the README.md and docs/ folder.
  • [ ] Tests: Unit tests for configuration and decoding logic.

Data Path Visualization

Sources: internal/probe/base/base_probe.go:100-150, internal/probe/gotls/gotls_probe.go:142-150, kern/bash_kern.c:49-61

How to Add a New Probe has loaded