Fluent Bit 中的 OpenTelemetry Proto C 接口库:fluent-otel-proto 构建与 C 文件再生成实战指南
2026/9/16 15:53:40 网站建设 项目流程

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 只给出两条操作线:

  1. 把它构建为静态库;
  2. .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-api

README 给出的预期输出:

- opentelemetry proto 'common' : found - opentelemetry proto 'resource': found - opentelemetry proto 'trace' : found - opentelemetry proto 'logs' : found - opentelemetry proto 'metrics' : found - opentelemetry proto 'profiles': found

2.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.protoYes
FLUENT_PROTO_RESOURCE包含resource.protoYes
FLUENT_PROTO_TRACE包含trace.prototrace_service.protoYes
FLUENT_PROTO_LOGS包含logs.protologs_service.protoYes
FLUENT_PROTO_METRICS包含metrics.protometrics_service.protoYes
FLUENT_PROTO_PROFILES包含 profiles 相关 proto 文件Yes
FLUENT_PROTO_EXAMPLES是否编译示例程序Yes
FLUENT_PROTO_TOOLS是否生成 toolsNo

其中FLUENT_PROTO_EXAMPLES控制examples/子目录是否加入构建(test-api即受它保护),FLUENT_PROTO_TOOLS则预留了tools/子目录入口。主仓库在引入该子项目时显式将FLUENT_PROTO_METRICSFLUENT_PROTO_PROFILES置为 ON(见根 CMakeLists.txt),保证 Fluent Bit 的 OTLP 相关功能始终可用。

四、再生成 C 文件(升级 .proto 数据模型的完整流程)

当 OpenTelemetry 官方数据模型更新、需要刷新仓库中的.pb-c.c/.pb-c.h时,需要按下述流程操作。以下内容完整继承 README 的操作步骤,并结合 CMake 实现补充了关键细节。

4.1 依赖准备:三个外部仓库

再生成依赖三个仓库(README 原文列出):

  1. fluent 的 protobuf-c 分支:它是官方 protobuf-c 的一个分支(fork),合入了上游 PR #781 对 proto3optional特性(显式可选字段)的支持。README 明确指出:该特性是 OpenTelemetry Metrics 数据模型所需的,因此不能直接使用官方原版;
  2. open-telemetry/opentelemetry-proto:提供.proto源文件;
  3. 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-proto

4.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 的再生成分支,有助于理解产物如何落位:

  1. 拼出基础命令protoc-c --c_out=${PROJECT_SOURCE_DIR}/proto_c/ --proto_path=${OTEL_PROTO_DIR}/,对每个启用的域执行execute_process(),例如 trace 域会依次处理trace.protocollector/trace/v1/trace_service.proto;生成的.pb-c.c/.pb-c.h直接写入本项目的proto_c/opentelemetry/proto/...目录,保持与.proto文件一致的相对路径;
  2. 注入构建宏:每个成功处理的域都会调用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
  3. 生成 info 头文件configure_file()依据include/fluent-otel-proto/下的fluent-otel-info.h.in模板生成 fluent-otel-info.h,把本次构建启用的宏固化到头文件里,供下游头文件(如fluent-otel.h首行的 include)消费;
  4. 拷贝 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_REGENERATEPROTOBUF_C_SOURCE_DIROTEL_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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询