使用 Rust 与 WASI 模式扩展 Fluent Bit:wasi_serde_json 示例深度解析

发布时间:2026/9/16 18:17:22

使用 Rust 与 WASI 模式扩展 Fluent Bit:wasi_serde_json 示例深度解析 使用 Rust 与 WASI 模式扩展 Fluent Bitwasi_serde_json 示例深度解析【免费下载链接】fluent-bitFast and Lightweight Logs, Metrics and Traces processor for Linux, BSD, OSX and Windows项目地址: https://gitcode.com/GitHub_Trending/fl/fluent-bit导读examples/wasi_serde_json/是 Fluent Bit 官方提供的 WASIWebAssembly System Interface模式示例演示了如何用 Rust 编写一个 WASM 程序被 Fluent Bit 的exec_wasi输入插件周期性调用将其 stdout 输出解析为结构化日志事件。读完本文你将掌握 WASI 程序的 Rust 构建全流程rustup目标添加、cargo build交叉编译、exec_wasi插件的完整配置方法WASI_Path、Parser、accessible_paths、oneshot等参数以及 Fluent Bit 底层如何基于 wasm-micro-runtimeWAMR实例化并执行 WASM 模块、把输出转换为 MessagePack 日志记录的完整数据通路。示例定位Fluent Bit 的 WASI 模式是什么Fluent Bit 允许用户通过 WASM 扩展数据采集能力。在exec_wasi输入插件出现之前exec插件只能周期执行本地命令行程序而exec_wasi则把执行对象替换为符合 WASI 规范的.wasm二进制模块其入口main()在 Fluent Bit 内嵌的 wasm-micro-runtime见仓库 lib/wasm-micro-runtime-WAMR-2.4.1/中被调用stdout输出被捕获并交给配置的 Parser 解析为结构化记录。这种方式兼具“跨平台可移植”与“沙箱隔离”的特点同一份.wasm文件可以在 Linux、BSD、macOS、Windows 上以一致行为运行。本示例仓库位于 examples/wasi_serde_json/包含三个核心文件文件作用examples/wasi_serde_json/README.md构建与集成验证步骤本文的主体脉络examples/wasi_serde_json/src/main.rsRust WASI 程序源码输出 JSON 并测试文件系统 APIexamples/wasi_serde_json/Cargo.toml依赖声明serde_json与chrono程序源码解读main.rs 在做什么src/main.rs 是一个极简但完整的 WASI 应用它演示了两种能力1. 生成并输出结构化 JSON 到 stdoutuse std::io::prelude::*; use std::fs; use serde_json::json; use chrono::Utc; fn main() { // Note that fractional second must be handled by .%9f not %L like as fluent-bit. let time Utc::now().format(%Y-%m-%dT%H:%M:%S.%9f %z).to_string(); let john json!({ name: John Doe, age: 43, phones: [ 44 1234567, 44 2345678 ], time: format!({}, time), }); println!({}, john.to_string()); ... }注意源码第 11 行的注释时间格式的纳秒部分必须使用%9f而不是 Fluent Bit 解析器中的%L。这直接关系到与 Parser 时间字段的匹配是初学者最容易踩的坑——WASI 侧的 Rustchrono与 Fluent Bit 侧的strptime格式串并不完全等价。2. 验证 WASI 文件系统 API 暴露// Create a file (Testing for exposed wasi API) let mut file fs::File::create(helloworld.txt).expect(Unable to create file); write!(file, Hello world!\n).unwrap();这段代码尝试在当前工作目录创建helloworld.txt。WASI 默认不允许模块随意访问宿主机文件系统必须通过accessible_paths配置显式授权可访问目录详见下文参数表这正是 WASI 沙箱安全模型的体现。serde_json负责 JSON 序列化chrono负责时间格式化两者的版本声明见 Cargo.toml[dependencies] serde_json 1.0 chrono 0.4构建 WASI 模块从 Rust 到 .wasm示例 README 给出的构建流程分三步前提是本机已安装 Rust 工具链README 编写时使用的 rustc 版本为 1.61.0实际构建以你当前工具链为准未安装时可先用rustup准备编译器与工具链。第一步为 Rust 工具链添加 WASI 目标$ rustup target add wasm32-wasip1wasm32-wasip1即 WASI Preview 1 对应的 Rust 编译目标它将标准库中的文件、时间等系统调用重定向到 WASI 的fd_write、path_open等 API这与 main.rs 注释中“This will handle writing to stdout for us using the WASI APIs (e.g fd_write)”相互印证。第二步交叉编译 Release 版本$ cargo build --target wasm32-wasip1 --release第三步确认产物$ ls target/wasm32-wasip1/release/*.wasm target/wasm32-wasip1/release/wasi_serde_json.wasm构建出的wasi_serde_json.wasm就是后续WASI_Path需要指向的文件。需要说明的是示例 README 中rustup的官网地址属于外部站点此处不展开若你的环境通过发行版包管理器安装 Rust也可用rustup target add统一管理交叉编译目标。集成验证parsers.conf 与 fluent-bit.confWASI 集成验证需要两个配置文件README 均给出了完整示例。第一步定义 JSON Parserparsers.conf[PARSER] Name wasi Format json Time_Key time Time_Format %Y-%m-%dT%H:%M:%S.%L %zTime_Key time指示插件从 JSON 记录的time字段提取时间戳Time_Format与 main.rs 中chrono输出的%Y-%m-%dT%H:%M:%S.%9f %z格式对应Fluent Bit 侧用%L表示毫秒/微秒小数部分Rust 侧用%9f表示纳秒两者解析结果一致。Parser 的完整配置项可参考仓库根目录的 conf/parsers.conf 中其他[PARSER]段落。第二步编写 exec_wasi 输入配置fluent-bit.conf[SERVICE] Flush 1 Daemon Off Parsers_File parsers.conf Log_Level info HTTP_Server Off HTTP_Listen 0.0.0.0 HTTP_Port 2020 [INPUT] Name exec_wasi Tag exec.wasi.local WASI_Path /path/to/wasi_ser_json.wasm Parser wasi [OUTPUT] Name stdout Match *注意原文档中WASI_Path写的是wasi_serde_json.wasm的完整路径此处按原意指向构建产物。关键配置语义[SERVICE]中的Parsers_File parsers.conf把第一步定义的 Parser 加载进来HTTP_Server Off关闭监控接口若开启则监听HTTP_Listen/HTTP_Port指定的 0.0.0.0:2020[INPUT]的Name exec_wasi启用 WASI 输入插件WASI_Path指向.wasm文件Parser wasi指定用哪个 Parser 解析 WASM 的 stdout 输出[OUTPUT]使用stdout输出插件把解析后的记录打印到终端Match *匹配所有标签这里对应exec.wasi.local。启动 Fluent Bit 后WASI 程序会按interval_sec默认 1 秒周期执行终端应持续打印包含name、age、phones、time字段的 JSON 日志。exec_wasi 插件参数全解结合源码README 只使用了WASI_Path与Parser两个参数但插件的完整配置面远不止于此。从 plugins/in_exec_wasi/in_exec_wasi.c 的config_map定义可以看到全部可配置项及其默认值参数类型默认值说明WASI_Pathstring无必填要执行的 WASM 程序路径缺失时插件报错no input command was givenaccessible_paths逗号分隔列表.当前工作目录允许 WASM 程序访问的路径列表对应 main.rs 中创建helloworld.txt所需授权Parserstring无用于解析 WASM stdout 输出的 Parser 名称未配置时按原始文本以wasi_stdout为键记录interval_secint1采集周期秒见头文件DEFAULT_INTERVAL_SECinterval_nsecint0采集周期纳秒补充见头文件DEFAULT_INTERVAL_NSECbuf_sizesize4096读取 stdout 的缓冲区大小见头文件DEFAULT_BUF_SIZEoneshotboolfalse只执行一次置位后强制interval_sec -1改为事件驱动wasm_heap_sizesize8192WASM 运行时堆大小KB见头文件DEFAULT_WASM_HEAP_SIZEwasm_stack_sizesize8192WASM 运行时栈大小KB见头文件DEFAULT_WASM_STACK_SIZE默认值常量集中在 plugins/in_exec_wasi/in_exec_wasi.h。参数之间的联动逻辑值得注意见 in_exec_wasi.c当interval_sec与interval_nsec都 ≤ 0 时插件会用默认值覆盖当oneshot为真时两个 interval 被强制设为 -1插件改用事件收集器pipe 触发执行一次cb_prerun中向管理管道写入哑元值 0xc003 以“踢”起执行见 in_exec_wasi.c只有用户显式设置的wasm_heap_size/wasm_stack_size大于运行时默认值时才会生效见 in_exec_wasi.c。插件通过FLB_PLUGIN(in_exec_wasi ...)注册并链接flb-wasm-static与vmlib-static即 WAMR 虚拟机详见 plugins/in_exec_wasi/CMakeLists.txt在 plugins/CMakeLists.txt 中以REGISTER_IN_PLUGIN(in_exec_wasi)纳入 Fluent Bit 输入插件体系。底层数据通路从 WASI stdout 到日志事件理解示例“能跑起来”的背后是 in_exec_wasi.c 中in_exec_wasi_collect回调完成的一连串动作创建临时文件接管 stdoutFILE *stdoutp tmpfile()创建一个匿名临时文件把其文件描述符写入 WASM 配置的stdoutfd第 54、82 行WASI 模块中println!的输出即被重定向到这里实例化并调用 WASI mainflb_wasm_instantiate()基于wasi_path与accessible_dir_list加载模块随后flb_wasm_call_wasi_main()执行入口函数第 84-97 行若找不到 main 则报错WASI main function is not found逐行解析 stdoutrewind(stdoutp)后按行fgets读取第 100-102 行去掉行尾换行符若配置了 Parser则调用flb_parser_do()把每行文本解析为 msgpack 数据第 109 行解析失败时打印parser returned an error并跳过编码为日志事件并分发使用flb_log_event_encoder把解析结果或未配置 Parser 时的原始文本键名为wasi_stdout与时间戳编码为 Fluent Bit 标准日志事件通过flb_input_log_append()交给路由与输出第 116-153 行销毁实例执行结束后flb_wasm_destroy()释放模块关闭临时文件第 202-206 行。未配置Parser时的行为同样值得注意第 156-200 行每行输出会以固定键名wasi_stdout附带原始文本直接入库此时所有字段都是非结构化的。这正是示例中特意定义 JSON Parser 的原因——只有结构化的 JSON 输出才能被stdout插件以key: value形式完整呈现。延伸其他语言的 WASI 构建与更多参考WASI 并不局限于 Rust。仓库测试目录 tests/runtime/wasm/go/ 中的 Makefile 展示了用 TinyGo 以-targetwasi构建 WASI 模块的方式tinygo build -wasm-abigeneric -targetwasi -o $.wasm $.go这说明只要目标平台是 WASI Preview 1无论 Rust 还是 Go 生成的.wasm都可以被exec_wasi插件加载执行。如果你想在自己的项目里复刻本示例直接复用 examples/wasi_serde_json/ 的Cargo.toml与main.rs按上文三步构建再把fluent-bit.conf中的WASI_Path换成你的产物路径即可。若需要对 WASI 程序暴露宿主机目录务必配置accessible_paths否则文件系统类 API 调用会因权限不足而失败。小结本文以 examples/wasi_serde_json/README.md 为骨架完整还原了从 Rust 源码、wasm32-wasip1交叉编译、.wasm产物到exec_wasi插件集成验证的全过程并结合 plugins/in_exec_wasi/ 源码剖析了插件全部配置参数与 stdout→Parser→日志事件的三段式数据通路。掌握这套流程后你便可以用任意支持 WASI 的语言为 Fluent Bit 编写可移植、可沙箱化运行的自定义数据采集逻辑。【免费下载链接】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),仅供参考
延伸阅读

更多相关文章

2026/9/16 18:17:22

TAPTAP评论文本挖掘:从爬虫到情感分析的完整方案

简介:这是一个面向计算机相关专业学生与文本挖掘初学者的完整项目资源,聚焦TAPTAP游戏评论的文本挖掘全流程,覆盖APP爬虫、数据清洗、pyecharts可视化与情感分析四大核心环节。项目来源于作者大三期末大作业,经导师指导获得99分高…

2026/9/16 18:17:22

去耦电容到底该多近?从物理本质到布局落地的完整指南

1. 引言:从一个被问住的“常识”说起做硬件设计这些年,我面试过不少工程师,也带过不少新人。每次问到去耦电容,几乎人人都能背出那句口诀:“电容要靠近引脚放,越近越好。”但你追问一句:“那到底…

2026/9/16 19:17:31

postMessage跨域通信实战:父页面与iframe安全双向通信指南

1. 先搞明白:跨域到底卡在哪了1.1 浏览器的同源策略是道门如果你是个前端,早晚会撞上这么一个需求:页面里嵌了iframe,里面的页面可能是你自己的子应用,也可能是第三方服务,结果两边要互传数据、同步状态、触…

2026/9/16 19:17:31

Uniapp跨端开发中Vite构建格式冲突解决方案

1. 问题现象与背景解析最近在Uniapp项目开发中遇到一个典型的编译环境差异问题:H5端运行完全正常,但打包App时控制台突然抛出Invalid value "iife" for option "output.format" - UMD and IIFE output formats错误。这个报错直接导致…

2026/9/16 19:17:31

a标签的href与target属性详解:从基础写法到安全实践

1. 先从最容易翻车的细节说起&#xff1a;href的正确写法新手写HTML链接&#xff0c;第一行代码十有八九是<a href"https://example.com">点我</a>。但我在帮人排查代码的时候&#xff0c;见过最多的错误不是忘了写闭合标签&#xff0c;也不是引号用成了…

2026/9/16 19:17:31

Matlab批量解码μ-law PCM音频:从RAR解压到WAV全流程

简介&#xff1a;一份面向数字信号处理与通信原理学习者、用于PCM量化误差分析的MATLAB代码包。压缩包共3个文件&#xff0c;包含2个m脚本和1个txt说明文本&#xff0c;整体仅1KB&#xff1b;核心代码通过生成500个标准正态分布随机数模拟时间点上的采样信号&#xff0c;分别对…

2026/9/16 19:12:27

51单片机电机转速表设计:从信号链路到源码实现

简介&#xff1a;51单片机电机转速表设计源码项目&#xff0c;面向单片机入门及嵌入式系统学习者&#xff0c;演示如何实时采集电机转速信号并通过显示屏呈现。项目以51单片机为核心&#xff0c;涵盖转速脉冲检测、定时器/计数器统计、中断服务处理以及AD0832模数转换等关键环节…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述&#xff1a;一台黑屏的拯救者Y7000&#xff0c;到底卡在哪一步&#xff1f; 联想拯救者Y7000系列笔记本&#xff0c;从2018年第一代搭载i5-8300H开始&#xff0c;到后来的i7-9750H、i7-10750H、i5-11400H&#xff0c;再到2023年款的R7-7840HS&#xff0c;它始终是学…

2026/9/16 0:04:09

PHP源码部署实战:从环境配置到运行情侣游戏全攻略

简介&#xff1a;这是一套面向情侣互动场景的PHP完整源码&#xff0c;集成情侣飞行棋、真心话大冒险、情趣骰子等玩法&#xff0c;并内置完整分销制度&#xff0c;可自定义多种返佣比例&#xff0c;源码完全开源无加密&#xff0c;支持微信无感自动授权登录与第三方授权&#x…

2026/9/15 14:22:53

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行&#xff0c;Type-C接口算是典型的“看着简单&#xff0c;做起来全坑”的东西。光引脚就24个&#xff0c;高低速信号、电源、控制线全部塞在一个小小的连接器里&#xff0c;如果PCB布局不做规划&#xff0c;打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/15 21:31:11

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/15 11:42:23

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码