Skip to content

Commit 58cc2d5

Browse files
niedbalskiedsiper
authored andcommitted
in_ebpf: initial version of the plugin (experimental)
This is a proposal to implement a ebpf trace ingestor plugin to allow sending traces from in kernel functions and userland through uprobes. This initial implementation has 3 traces implemented: bind (tcp), malloc (uprobe) and signals (kernel trace). Events types are known and defined in the fluent-bit codebase and those has to be implemented by the ebpf program to follow when submitted into the ring buffer. Signed-off-by: Jorge Niedbalski <[email protected]>
1 parent 601969d commit 58cc2d5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+381884
-5
lines changed

.github/workflows/unit-tests.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
- name: Setup environment
5757
run: |
5858
sudo apt-get update
59-
sudo apt-get install -y gcc-7 g++-7 clang-6.0 libsystemd-dev gcovr libyaml-dev
59+
sudo apt-get install -y gcc-7 g++-7 clang-6.0 libsystemd-dev gcovr libyaml-dev libbpf-dev linux-tools-common
6060
sudo ln -s /usr/bin/llvm-symbolizer-6.0 /usr/bin/llvm-symbolizer || true
6161
6262
- uses: actions/checkout@v4
@@ -142,7 +142,7 @@ jobs:
142142
- name: Setup environment
143143
run: |
144144
sudo apt-get update
145-
sudo apt-get install -y gcc-9 g++-9 clang-12 cmake flex bison libsystemd-dev gcovr libyaml-dev
145+
sudo apt-get install -y gcc-9 g++-9 clang-12 cmake flex bison libsystemd-dev gcovr libyaml-dev libbpf-dev linux-tools-common
146146
sudo ln -s /usr/bin/llvm-symbolizer-12 /usr/bin/llvm-symbolizer || true
147147
148148
- name: Build and test with actuated runners
@@ -195,7 +195,7 @@ jobs:
195195
--volume "/etc/machine-id:/etc/machine-id"
196196
install: |
197197
apt-get update
198-
apt-get install -y gcc-7 g++-7 clang-6.0 libyaml-dev cmake flex bison libssl-dev #libsystemd-dev
198+
apt-get install -y gcc-7 g++-7 clang-6.0 libyaml-dev cmake flex bison libssl-dev libbpf-dev linux-tools-common#libsystemd-dev
199199
ln -s /usr/bin/llvm-symbolizer-6.0 /usr/bin/llvm-symbolizer || true
200200
201201
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 90

.gitignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ workflow/
2828
*.key
2929
*.log
3030
*.tar.gz
31-
31+
*.o
3232
# clangd files
3333
.cache/
3434
compile_commands.json
@@ -40,4 +40,4 @@ workflow/
4040
# examples
4141
examples/wasi_serde_json/target/
4242
# WASM test data
43-
tests/runtime/wasm/go/*.wasm
43+
tests/runtime/wasm/go/*.wasm

CMakeLists.txt

+30
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,36 @@ else()
10671067
set(FLB_ARROW OFF)
10681068
endif()
10691069

1070+
# EBPF Support
1071+
# ============
1072+
if (FLB_IN_EBPF)
1073+
find_package(PkgConfig)
1074+
1075+
# Check for libbpf with pkg-config
1076+
pkg_check_modules(LIBBPF libbpf>=0.5.0)
1077+
1078+
if (LIBBPF_FOUND)
1079+
message(STATUS "libbpf found: ${LIBBPF_LIBRARIES}")
1080+
include_directories(${LIBBPF_INCLUDE_DIRS})
1081+
list(APPEND EXTRA_LIBS ${LIBBPF_LIBRARIES})
1082+
else()
1083+
# Manually find the library if pkg-config fails
1084+
find_library(LIBBPF_LIBRARY NAMES bpf REQUIRED)
1085+
if (LIBBPF_LIBRARY)
1086+
message(STATUS "Found libbpf: ${LIBBPF_LIBRARY}")
1087+
list(APPEND EXTRA_LIBS ${LIBBPF_LIBRARY})
1088+
else()
1089+
if (FLB_SYSTEM_LINUX)
1090+
message(FATAL_ERROR "libbpf is required on Linux. Please install libbpf or ensure it is in your library path.")
1091+
else()
1092+
message(STATUS "libbpf is not found. Disabling eBPF support.")
1093+
set(FLB_IN_EBPF OFF)
1094+
endif()
1095+
endif()
1096+
endif()
1097+
1098+
endif()
1099+
10701100
# Pthread Local Storage
10711101
# =====================
10721102
# By default we expect the compiler already support thread local storage

cmake/plugins_options.cmake

+1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ DEFINE_OPTION(FLB_IN_WINLOG "Enable Windows Log input plugin"
6262
DEFINE_OPTION(FLB_IN_WINDOWS_EXPORTER_METRICS "Enable windows exporter metrics input plugin" ON)
6363
DEFINE_OPTION(FLB_IN_WINEVTLOG "Enable Windows EvtLog input plugin" OFF)
6464
DEFINE_OPTION(FLB_IN_WINSTAT "Enable Windows Stat input plugin" OFF)
65+
DEFINE_OPTION(FLB_IN_EBPF "Enable Linux eBPF input plugin" OFF)
6566

6667
# Processors
6768
# ==========

cmake/windows-setup.cmake

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ if(FLB_WINDOWS_DEFAULTS)
5353
set(FLB_IN_STORAGE_BACKLOG Yes)
5454
set(FLB_IN_EMITTER Yes)
5555
set(FLB_IN_PODMAN_METRICS No)
56+
set(FLB_IN_EBPF No)
5657
set(FLB_IN_ELASTICSEARCH Yes)
5758
set(FLB_IN_SPLUNK Yes)
5859
set(FLB_IN_PROMETHEUS_REMOTE_WRITE Yes)

plugins/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
209209
REGISTER_IN_PLUGIN("in_docker_events")
210210
REGISTER_IN_PLUGIN("in_podman_metrics")
211211
REGISTER_IN_PLUGIN("in_process_exporter_metrics")
212+
REGISTER_IN_PLUGIN("in_ebpf")
212213
endif()
213214

214215
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")

plugins/in_ebpf/CMakeLists.txt

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
cmake_minimum_required(VERSION 3.0)
2+
3+
# Define source files for the main plugin
4+
file(GLOB_RECURSE src
5+
"in_ebpf.c"
6+
"traces/**/handler.c"
7+
)
8+
9+
# Determine architecture and set flags accordingly
10+
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
11+
set(ARCH_FLAG "-D__TARGET_ARCH_x86_64")
12+
set(VMLINUX_PATH "${CMAKE_SOURCE_DIR}/plugins/in_ebpf/traces/includes/external/gadget/amd64")
13+
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "arm64")
14+
set(ARCH_FLAG "-D__TARGET_ARCH_arm64")
15+
set(VMLINUX_PATH "${CMAKE_SOURCE_DIR}/plugins/in_ebpf/traces/includes/external/gadget/arm64")
16+
else()
17+
message(FATAL_ERROR "Unsupported architecture: ${CMAKE_SYSTEM_PROCESSOR}")
18+
endif()
19+
20+
# Include directories for external headers, common headers, and generated skeletons
21+
include_directories(
22+
${CMAKE_SOURCE_DIR}/plugins/in_ebpf/traces/includes/external
23+
${CMAKE_SOURCE_DIR}/plugins/in_ebpf/traces/includes
24+
)
25+
26+
# Create an interface library for gadget includes
27+
add_library(gadget INTERFACE)
28+
target_include_directories(gadget INTERFACE ${CMAKE_SOURCE_DIR}/plugins/in_ebpf/traces/includes/external/gadget)
29+
30+
# Find all bpf.c files in the traces directory
31+
file(GLOB_RECURSE TRACE_C_FILES ${CMAKE_SOURCE_DIR}/plugins/in_ebpf/traces/*/bpf.c)
32+
33+
# Create a list to hold all the object files and skeleton headers that will be generated
34+
set(TRACE_OBJ_FILES "")
35+
set(TRACE_SKEL_HEADERS "")
36+
37+
# Iterate over each trace bpf.c file to generate corresponding .o and .skel.h files
38+
foreach(TRACE_C_FILE ${TRACE_C_FILES})
39+
# Get the filename and parent directory name (for uniqueness)
40+
get_filename_component(TRACE_FILE_NAME ${TRACE_C_FILE} NAME_WE)
41+
get_filename_component(TRACE_PARENT_DIR ${TRACE_C_FILE} DIRECTORY)
42+
get_filename_component(TRACE_PARENT_DIR_NAME ${TRACE_PARENT_DIR} NAME)
43+
44+
# Ensure the output filenames maintain the original "trace_" prefix
45+
set(TRACE_BASE_NAME "trace_${TRACE_PARENT_DIR_NAME}")
46+
47+
# Set unique names by including the parent directory name in the output paths
48+
set(TRACE_OBJ_FILE ${CMAKE_BINARY_DIR}/plugins/in_ebpf/traces/includes/generated/${TRACE_BASE_NAME}.o)
49+
set(TRACE_SKEL_HEADER ${CMAKE_BINARY_DIR}/plugins/in_ebpf/traces/includes/generated/${TRACE_BASE_NAME}.skel.h)
50+
51+
# Compile each bpf.c file to its corresponding .o file
52+
add_custom_command(
53+
OUTPUT ${TRACE_OBJ_FILE}
54+
COMMAND clang
55+
-target bpf
56+
${ARCH_FLAG} # Use architecture-specific flag
57+
-O2 # Optional: Optimization level
58+
-g # Optional: Debug info
59+
-I${CMAKE_SOURCE_DIR}/plugins/in_ebpf/traces/includes/external
60+
-I${CMAKE_SOURCE_DIR}/plugins/in_ebpf/traces/includes
61+
-I${VMLINUX_PATH} # Include the correct vmlinux.h based on architecture
62+
-c ${TRACE_C_FILE}
63+
-o ${TRACE_OBJ_FILE}
64+
DEPENDS ${TRACE_C_FILE}
65+
)
66+
67+
# Generate skeleton header for each compiled BPF object file
68+
add_custom_command(
69+
OUTPUT ${TRACE_SKEL_HEADER}
70+
COMMAND bpftool gen skeleton ${TRACE_OBJ_FILE} > ${TRACE_SKEL_HEADER}
71+
DEPENDS ${TRACE_OBJ_FILE}
72+
COMMENT "Generating skeleton ${TRACE_SKEL_HEADER} from ${TRACE_OBJ_FILE}"
73+
)
74+
75+
# Add generated object and skeleton files to their respective lists
76+
list(APPEND TRACE_OBJ_FILES ${TRACE_OBJ_FILE})
77+
list(APPEND TRACE_SKEL_HEADERS ${TRACE_SKEL_HEADER})
78+
endforeach()
79+
80+
# Create a custom target specifically for generating eBPF skeletons
81+
add_custom_target(generate_skeletons DEPENDS ${TRACE_SKEL_HEADERS})
82+
83+
# Create a custom target to compile all eBPF programs (all trace bpf.c files)
84+
add_custom_target(compile_ebpf ALL DEPENDS ${TRACE_OBJ_FILES} ${TRACE_SKEL_HEADERS})
85+
86+
# Ensure that the custom target depends on the gadget interface library (for include paths)
87+
add_dependencies(compile_ebpf gadget)
88+
89+
# Include generated skeleton headers in the main plugin
90+
include_directories(${CMAKE_BINARY_DIR}/plugins/in_ebpf/traces/includes/generated)
91+
92+
# Declare the Fluent Bit plugin (using the default compiler for the main plugin)
93+
FLB_PLUGIN(in_ebpf "${src}" "")
94+
95+
# Link necessary libraries
96+
target_link_libraries(flb-plugin-in_ebpf gadget -lbpf -lelf -lz)

0 commit comments

Comments
 (0)