Fluent Bit 中的 OpenTelemetry Proto C 接口库:fluent-otel-proto 构建与 C 文件再生成实战指南
【免费下载链接】fluent-bitFast and Lightweight Logs, Metrics and Traces processor for Linux, BSD, OSX and Windows项目地址: https://gitcode.com/GitHub_Trending/fl/fluent-bit
fluent-otel-proto是 Fluent Bit 仓库内负责将 OpenTelemetry 官方.proto数据模型转换为 C 语言接口(protobuf-c 生成代码)的静态库项目,它是 Fluent Bit 处理 Logs、Metrics、Traces 与 Profiles 时对接 OTLP 协议的基础设施。读完本文,你将掌握两套完整操作:一是将该子项目独立构建为静态库并验证六大 proto 域的可用状态,二是在需要升级 OpenTelemetry 数据模型时,从零再生成全部 C 接口的完整流程(包括依赖准备、CMake 变量与构建开关)。
一、fluent-otel-proto 是什么:C 语言版的 OTel 数据模型
按 项目 README 的官方描述,本项目构建一个静态库(fluent-otel-proto),提供 OpenTelemetry proto 文件数据模型的 C 接口,并附带若干辅助工具函数。与常规“先取 .proto 再生成”的项目不同,仓库源码中已经内置了全部 .proto 文件对应的 C 版本生成代码,因此 README 只给出两条操作线:
- 把它构建为静态库;
- 从
.proto文件重新再生成 C 接口。
1.1 目录结构速览
从目录结构看,整个项目分成四个职责清晰的区域:
| 路径 | 职责 |
|---|---|
| include/fluent-otel-proto/ | 对外公开头文件:fluent-otel.h、fluent-otel_found.h、fluent-otel-info.h |
| proto_c/ | 已生成的 C 代码:opentelemetry/proto/**下 22 个.pb-c.c/.pb-c.h文件,以及内嵌的protobuf-c运行时(protobuf-c.c/.h) |
| src/ | 库本体源码与静态库构建脚本 |
| examples/ | 示例程序test-api,用于验证 proto 域是否编译进库 |
| cmake/macros.cmake | 定义构建期宏FLUENT_OTEL_DEFINITION |
proto_c/opentelemetry/proto/下的生成文件覆盖了六个数据域,与 README 中测试输出所列的域一一对应:
- common(
proto/common/v1/common.pb-c.*) - resource(
proto/resource/v1/resource.pb-c.*) - trace(
proto/trace/v1/trace.pb-c.*与proto/collector/trace/v1/trace_service.pb-c.*) - logs(
proto/logs/v1/logs.pb-c.*与proto/collector/logs/v1/logs_service.pb-c.*) - metrics(
proto/metrics/v1/metrics.pb-c.*与proto/collector/metrics/v1/metrics_service.pb-c.*) - profiles(
proto/profiles/v1development/profiles.pb-c.*、pprofextended.pb-c.*与proto/collector/profiles/v1development/profiles_service.pb-c.*)
1.2 它在 Fluent Bit 中的位置
在主仓库中,fluent-otel-proto并不是孤立存在的。根 CMakeLists.txt 中有一段注释明确将其定位为 bundled 库之一(“this act as a helper for CFL, Ctraces, CMetrics, CProfiles and fluent-otel-proto”),并把它加入CMAKE_REQUIRED_INCLUDES以支撑各子项目的check_c_source_compiles()检测,随后以add_subdirectory(... EXCLUDE_FROM_ALL)方式引入:
# fluent-otel-proto FLB_OPTION(FLUENT_PROTO_METRICS ON) FLB_OPTION(FLUENT_PROTO_PROFILES ON) add_subdirectory(${FLB_PATH_LIB_FLUENT_OTEL} EXCLUDE_FROM_ALL)它的直接消费者包括:
- cmetrics:lib/cmetrics/src/CMakeLists.txt 中
cmetrics-static链接fluent-otel-proto; - ctraces / cprofiles:lib/ctraces/CMakeLists.txt、lib/cprofiles/CMakeLists.txt 同样链接该库;
- OTLP 导出实现:src/opentelemetry/flb_opentelemetry_logs.c 与 src/opentelemetry/flb_opentelemetry_otlp_proto.c 均
#include <fluent-otel-proto/fluent-otel.h>,直接消费生成的 protobuf-c 结构体。
此外,子项目还通过fluent-otel_found.h做“存在性探测”:fluent-otel_found.h 定义了一个static inline int fluent_otel_found()哑函数,父项目(如 lib/cmetrics/CMakeLists.txt、lib/ctraces/CMakeLists.txt)可用check_c_source_compiles()尝试 include 该头文件,以此判断环境中是否存在 fluent-otel-proto 头文件。
二、构建静态库(常规使用路径)
README 给出的标准流程:克隆仓库、进入build目录、运行 CMake。仓库内子项目对应路径为 lib/fluent-otel-proto/:
cd lib/fluent-otel-proto mkdir -p build && cd build cmake ../ make构建完成后默认附带一个示例测试程序(由 examples/CMakeLists.txt 编译,链接fluent-otel-proto静态库):
examples/test-apiREADME 给出的预期输出:
- opentelemetry proto 'common' : found - opentelemetry proto 'resource': found - opentelemetry proto 'trace' : found - opentelemetry proto 'logs' : found - opentelemetry proto 'metrics' : found - opentelemetry proto 'profiles': found2.1 输出背后的实现:fluent_otel_info()
这个输出并非凭空打印。examples/test-api.c 的main()只调用一个函数fluent_otel_info(),其实现在 src/fluent-otel.c 中:对每个数据域做一次编译期宏判断——
printf("- opentelemetry proto 'common' : "); #ifdef FLUENT_OTEL_HAVE_COMMON printf("%10s", "found\n"); #else printf("%10s", "not found (enable it with -DFLUENT_PROTO_COMMON)\n"); #endif也就是说,found/not found完全由 CMake 是否注入FLUENT_OTEL_HAVE_*编译宏决定,而宏的注入点在再生成流程中(见第四节 cmake/macros.cmake 的FLUENT_OTEL_DEFINITION宏)。对于未走再生成流程的常规构建,各.pb-c.c是否编入静态库则由 src/CMakeLists.txt 按选项逐一控制:
if (FLUENT_PROTO_TRACE) set(src ${src} ${OTEL_C_FILES}/proto/trace/v1/trace.pb-c.c) set(src ${src} ${OTEL_C_FILES}/proto/collector/trace/v1/trace_service.pb-c.c) endif() ... add_library(fluent-otel-proto STATIC ${src})基础源文件(fluent-otel.c+ 内嵌的proto_c/protobuf-c/protobuf-c.c)始终参与编译,六个数据域的生成代码则按开关拼入。
2.2 对外头文件的条件包含机制
fluent-otel.h 展示了“按需包含”的设计:每个生成头文件都被#ifdef宏包裹,只有对应数据域被启用时才暴露——
#ifdef FLUENT_OTEL_HAVE_COMMON #include <opentelemetry/proto/common/v1/common.pb-c.h> #endif #ifdef FLUENT_OTEL_HAVE_TRACE #include <opentelemetry/proto/trace/v1/trace.pb-c.h> #include <opentelemetry/proto/collector/trace/v1/trace_service.pb-c.h> #endif这使得同一个消费方(如 cmetrics 只关心 metrics 域、ctraces 只关心 trace 域)可以只编译自己需要的子集,减小最终二进制体积。
三、CMake 构建选项全集
README 提到的六个数据域开关,在 lib/fluent-otel-proto/CMakeLists.txt 中有精确的默认值定义,另有两个 README 未展开的补充选项:
| 选项 | 含义 | 默认值(源码) |
|---|---|---|
FLUENT_PROTO_REGENERATE | 启用 C 源文件再生成 | No |
FLUENT_PROTO_COMMON | 包含common.proto | Yes |
FLUENT_PROTO_RESOURCE | 包含resource.proto | Yes |
FLUENT_PROTO_TRACE | 包含trace.proto与trace_service.proto | Yes |
FLUENT_PROTO_LOGS | 包含logs.proto与logs_service.proto | Yes |
FLUENT_PROTO_METRICS | 包含metrics.proto与metrics_service.proto | Yes |
FLUENT_PROTO_PROFILES | 包含 profiles 相关 proto 文件 | Yes |
FLUENT_PROTO_EXAMPLES | 是否编译示例程序 | Yes |
FLUENT_PROTO_TOOLS | 是否生成 tools | No |
其中FLUENT_PROTO_EXAMPLES控制examples/子目录是否加入构建(test-api即受它保护),FLUENT_PROTO_TOOLS则预留了tools/子目录入口。主仓库在引入该子项目时显式将FLUENT_PROTO_METRICS与FLUENT_PROTO_PROFILES置为 ON(见根 CMakeLists.txt),保证 Fluent Bit 的 OTLP 相关功能始终可用。
四、再生成 C 文件(升级 .proto 数据模型的完整流程)
当 OpenTelemetry 官方数据模型更新、需要刷新仓库中的.pb-c.c/.pb-c.h时,需要按下述流程操作。以下内容完整继承 README 的操作步骤,并结合 CMake 实现补充了关键细节。
4.1 依赖准备:三个外部仓库
再生成依赖三个仓库(README 原文列出):
- fluent 的 protobuf-c 分支:它是官方 protobuf-c 的一个分支(fork),合入了上游 PR #781 对 proto3
optional特性(显式可选字段)的支持。README 明确指出:该特性是 OpenTelemetry Metrics 数据模型所需的,因此不能直接使用官方原版; - open-telemetry/opentelemetry-proto:提供
.proto源文件; - fluent/fluent-otel-proto:本项目(即仓库内
lib/fluent-otel-proto/)。
步骤 0:手动编译 protobuf(v5.26.1)
fluent 分支的 protobuf-c 需要较新版本的 protobuf,而发行版自带版本过旧,必须手工编译安装(README 原步骤):
cd /tmp git clone --depth 1 --branch v5.26.1 protobuf-src # protocolbuffers/protobuf 仓库 cd protobuf-src git submodule update --init --recursive mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release \ -Dprotobuf_BUILD_TESTS=OFF \ -DCMAKE_INSTALL_PREFIX=/usr/local make sudo make install sudo ldconfig步骤 1:安装 protobuf-c
git clone protobuf-c # fluent 的 protobuf-c 分支仓库 cd protobuf-c ./autogen.sh ./configure PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig:/usr/local/lib/pkgconfig --prefix=/opt/protobuf-c make sudo make install注意--prefix=/opt/protobuf-c:这个安装前缀不是随意写的,它是 CMake 中生成器可执行文件路径的硬编码前提——CMakeLists.txt 中写死了set(PROTOC_BIN "/opt/protobuf-c/bin/protoc-c")。
步骤 2、3:克隆 opentelemetry-proto 与本项目
git clone opentelemetry-proto # open-telemetry 官方 proto 仓库 git clone fluent-otel-proto4.2 CMake 变量与再生成机制
开启再生成时,CMake 会强制要求两个路径变量(CMakeLists.txt 中带有FATAL_ERROR检查,缺失任一变量都会直接报错终止配置):
| 变量名 | 说明 |
|---|---|
FLUENT_PROTO_REGENERATE | 启用 C 源文件再生成,默认关闭 |
PROTOBUF_C_SOURCE_DIR | 步骤 1 下载的 protobuf-c 的源码目录绝对路径。注意:是源码路径,不是二进制安装路径 |
OTEL_PROTO_DIR | 步骤 2 下载的 opentelemetry-proto 的源码目录绝对路径 |
此外,上一节表格中的六个数据域开关(FLUENT_PROTO_COMMON/FLUENT_PROTO_RESOURCE/FLUENT_PROTO_TRACE/FLUENT_PROTO_LOGS/FLUENT_PROTO_METRICS/FLUENT_PROTO_PROFILES)在再生成流程中控制哪些 .proto 文件被处理,默认为 On。
4.3 再生成时 CMake 实际做了什么
读懂 CMakeLists.txt 的再生成分支,有助于理解产物如何落位:
- 拼出基础命令:
protoc-c --c_out=${PROJECT_SOURCE_DIR}/proto_c/ --proto_path=${OTEL_PROTO_DIR}/,对每个启用的域执行execute_process(),例如 trace 域会依次处理trace.proto与collector/trace/v1/trace_service.proto;生成的.pb-c.c/.pb-c.h直接写入本项目的proto_c/opentelemetry/proto/...目录,保持与.proto文件一致的相对路径; - 注入构建宏:每个成功处理的域都会调用
FLUENT_OTEL_DEFINITION(FLUENT_OTEL_HAVE_XXX),该宏(cmake/macros.cmake)做三件事——add_definitions(-DFLUENT_OTEL_HAVE_XXX)注入编译宏、把#define文本累加进FLUENT_OTEL_BUILD_FLAGS、把宏名累加进FLUENT_OTEL_INFO_FLAGS; - 生成 info 头文件:
configure_file()依据include/fluent-otel-proto/下的fluent-otel-info.h.in模板生成 fluent-otel-info.h,把本次构建启用的宏固化到头文件里,供下游头文件(如fluent-otel.h首行的 include)消费; - 拷贝 protobuf-c 运行时:用
configure_file(... COPYONLY)把PROTOBUF_C_SOURCE_DIR/protobuf-c/protobuf-c.c/.h原样复制到proto_c/protobuf-c/,这也是该子目录内这两个文件存在的来源——它们属于随代码分发的内嵌运行时,而非系统依赖。
4.4 README 的再生成示例命令
按 README 的步骤 5,进入项目源码的build目录后运行:
cd fluent-otel-proto/build/ cmake -DFLUENT_PROTO_REGENERATE=ON \ -DPROTOBUF_C_SOURCE_DIR=/tmp/protobuf-c \ -DOTEL_PROTO_DIR=/tmp/opentelemetry-proto \ ../随后执行make完成构建。对照上面的实现可以印证:/tmp/protobuf-c与/tmp/opentelemetry-proto必须是两个仓库的源码检出目录;protoc-c则要求已按步骤 1 安装到/opt/protobuf-c前缀下。
五、小结
fluent-otel-proto用一套“生成代码随仓库分发 + CMake 开关按域裁剪”的模式,把 OpenTelemetry 六大数据域的 proto 模型以纯 C 静态库的形式提供给 Fluent Bit 主程序与 cmetrics/ctraces/cprofiles 等组件:常规构建只需cmake ../ && make并用examples/test-api校验各域状态(输出逻辑见 src/fluent-otel.c);升级数据模型则需准备 protobuf v5.26.1、fluent 分支的 protobuf-c(提供 proto3optional支持,Metrics 模型所必需)与 opentelemetry-proto 三个依赖,通过FLUENT_PROTO_REGENERATE、PROTOBUF_C_SOURCE_DIR、OTEL_PROTO_DIR三个变量触发再生成。所有开关的默认值与行为均可在 lib/fluent-otel-proto/CMakeLists.txt、src/CMakeLists.txt 与 cmake/macros.cmake 中逐一对照验证。
【免费下载链接】fluent-bitFast and Lightweight Logs, Metrics and Traces processor for Linux, BSD, OSX and Windows项目地址: https://gitcode.com/GitHub_Trending/fl/fluent-bit
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考