Vector 数据转换实战:用 VRL 与 Lua 对可观测性数据进行结构化、塑形与转换
【免费下载链接】vectorA high-performance observability data pipeline.项目地址: https://gitcode.com/GitHub_Trending/vect/vector
本指南基于 Vector 官方入门系列中的《Structuring, Shaping, and Transforming Data》,面向已掌握 Vector 基础概念与基础管道搭建的读者,完整演示如何使用remap变换与 Vector Remap Language(VRL)对 Syslog 等可观测性数据进行解析、字段增删、类型转换与条件逻辑处理,并介绍 VRL 无法覆盖场景下的lua运行时变换及其取舍。读完本文,你将能够独立编写一段可在vector.yaml中直接运行的数据转换拓扑,并理解其背后的编译期检查与运行时行为。
前置要求
在开始之前,本指南假设你已经具备以下基础:
- 理解 Vector 基本概念(事件、组件、拓扑);
- 理解如何搭建一条基础管道(source → transform → sink)。
Vector 的变换机制与为何首选 VRL
Vector 提供了多种变换(transform)组件,用于在数据流经 topology(管道模型) 的过程中修改可观测性数据。在众多变换中,你大概率最常使用的是remap变换——它使用一种专为数据转换设计的语言Vector Remap Language(VRL)来定义事件转换逻辑。
从源码结构看,remap是 Vector 生态的核心变换之一,其配置结构体RemapConfig直接内建了 VRL 程序编译与缓存逻辑(src/transforms/remap.rs#L51-L164),并维护了一个基于 enrichment 表与 schema 定义的编译缓存,避免对相同程序重复编译。VRL 之所以应作为转换数据的首选,有以下几个关键理由:
- 丰富的可观测性专属函数:VRL 提供了大量直接映射到可观测性场景的函数,例如解析 Syslog 的
parse_syslog、解析 JSON 的parse_json、时间戳转换的to_unix_timestamp、生成 UUID 的uuid_v4等; - 为 Vector 日志与指标量身定制:VRL 专为 Vector 日志和指标设计,没有多余功能,其数据模型与 Vector 内部数据模型直接对应,性能与原生 Rust 相当。仓库中的 remap 基准测试与 lua 基准测试 正是对这种性能诉求的工程验证;
- 编译期检查:Vector 内置的 VRL 编译器会在启动时执行多项编译期检查,确保 VRL 代码健全——无死代码、无未处理错误、无类型不匹配。
在 VRL 无法满足你的场景时,Vector 还提供 Lua 运行时变换,它比 VRL 更灵活,但也伴随下文列出的、应当始终牢记的缺点。
使用 VRL 转换数据:一个完整拓扑示例
让我们直接进入一个使用 VRL 修改数据的例子。我们将创建一个由三个组件构成的简单拓扑:
- 一个
demo_logs源,以每秒 10 条的速率产生随机 Syslog(RFC 5424)格式消息; - 一个
remap变换,使用 VRL 将传入的 Syslog 行解析为命名字段(severity、timestamp等); - 一个
consolesink,将拓扑输出打印到 stdout,方便在命令行直接查看结果。
下面的配置即定义了该拓扑:
sources: logs: type: demo_logs format: syslog interval: 0.1 transforms: modify: type: remap inputs: - logs source: | # Parse Syslog input. The "!" means that the script should abort on error. . = parse_syslog!(.message) sinks: out: type: console inputs: - modify encoding: codec: json说明:虽然这里使用 YAML 编写配置,Vector 同样支持 TOML 与 JSON 格式。
从源码看,demo_logs源的配置项与上述用法完全对应:interval控制每批输出的间隔秒数(默认 1 秒,设为0.0可去掉延迟尽可能快地输出),format支持shuffle、apache_common、apache_error、syslog(RFC 5424)、bsd_syslog(RFC 3164)与json等多种随机格式,count默认输出无限行(src/sources/demo_logs.rs#L32-L77)。
使用该拓扑启动 Vector:
vector --config /etc/vector/vector.yaml你应该会在 stdout 看到类似下面的输出行(此处为便于阅读做了格式化):
{ "appname": "authsvc", "facility": "daemon", "hostname": "acmecorp.biz", "message": "#hugops to everyone who has to deal with this", "msgid": "ID486", "procid": 5265, "severity": "notice", "timestamp": "2021-01-19T18:16:40.027Z" }到目前为止,我们只是让 Vector解析了 Syslog 数据,还没有真正修改这些数据。接下来更新remap变换的source脚本,做一些临时性的转换:
transforms: modify: type: remap inputs: - logs source: | . = parse_syslog!(.message) # Convert the timestamp to a Unix timestamp, aborting on error .timestamp = to_unix_timestamp!(.timestamp) # Remove the "facility" and "procid" fields del(.facility) del(.procid) # Replace the "msgid" field with a unique ID .msgid = uuid_v4() # If the log message contains the phrase "Great Scott!", set the new field # "critical" to true, otherwise set it to false. If the "contains" function # errors, log the error (instead of aborting the script, as above). if (is_critical = contains(.message, "Great Scott!"); is_critical) { log("It contains 'Great Scott!'", level: "info") } .critical = is_critical关于这段脚本,有几点值得注意:
- 所有 VRL 函数抛出的错误都必须被处理。例如,如果我们忽略
parse_syslog函数可能抛出的错误,VRL 编译器会给出非常具体的警告,Vector 将无法启动。这正是 VRL 编译期检查的体现; - VRL 具备完整的语言构造:变量、
if语句、注释以及日志输出(log); .充当事件数据的"容器":单独的.指向事件根对象,你可以使用路径(path)如.foo、.foo[0]、.foo.bar、.foo.bar[0]等引用子字段、数组索引等。VRL 的路径语法在remap实现中由ValuePath等类型支撑(src/transforms/remap.rs#L25-L27)。
注意:VRL 函数在不同执行上下文中的行为可能不同。例如,当编译器能检测到
.message的类型是字符串时,上面的contains函数在 Vector/Remap 进程内是 infallible(不会出错)的。同样的代码在 VRL Playground、VRL CLI 中运行,或在schema.log_namespace设为true时,行为可能不同。
重启 Vector 后,你应该看到类似下面的日志行(同样为便于阅读做了重新格式化):
{ "appname": "authsvc", "hostname": "acmecorp.biz", "message": "Great Scott! We're never gonna reach 88 mph with the flux capacitor in its current state!", "msgid": "4e4437b6-13e8-43b3-b51e-c37bd46de490", "severity": "notice", "timestamp": 1611080200, "critical": true }至此,我们已经成功创建了一个会转换流经它的每个事件的 Vector 拓扑:Syslog 原始文本被解析为结构化字段,timestamp被转换为 Unix 时间戳,facility与procid被删除,msgid被替换为 UUID,并基于消息内容新增了critical布尔字段。
remap 变换的更多配置能力
除了source内联脚本,remap变换还支持把 VRL 程序放在外部文件中:file(单个文件路径,相对路径以当前工作目录为根)与files(多个文件路径),三者至少指定其一(src/transforms/remap.rs#L58-L85)。此外还有几个与错误处理密切相关的配置项:
drop_on_error:默认false。当 VRL 程序处理事件出错时,默认会把原始未修改事件继续下发;设为true后则直接丢弃出错事件;drop_on_abort:默认true。控制 VRL 程序中手动调用abort中止时,是下发原始未修改事件还是丢弃;reroute_dropped:默认false。开启后,被drop_on_error或drop_on_abort丢弃的事件会被转发到名为dropped的特殊输出,便于进一步分析、调试或重试;metric_tag_values:控制指标标签值如何暴露(single/full/auto),auto模式下单值标签暴露为字符串、多值标签暴露为数组;timezone:为不包含显式时区的时间戳转换指定时区,覆盖全局timezone选项(src/transforms/remap.rs#L101-L110)。
这些配置让remap不仅能"成功时转换数据",还能精确定义"出错时数据流向何处"。
深入探索 VRL
如果你想进一步了解 VRL,推荐阅读以下内容:
- VRL 函数完整列表——涵盖
parse_syslog、to_unix_timestamp、uuid_v4、contains、del、log、abort等全部内置函数; - VRL 示例——仓库内置的 VRL 测试用例与示例;
- VRL 表达式——详细描述 VRL 语法与类型系统的实现。
仓库中 VRL 标准库的本地实现与 web-playground 也是阅读源码、理解函数执行上下文差异(如schema.log_namespace对类型推断的影响)的绝佳入口。
Lua 运行时变换
如果 VRL 无法覆盖你的用例——这种情况应当很少发生——Vector 还提供了lua运行时变换,你可以用它代替 VRL。它允许你运行直接内嵌在 Vector 配置中的 Lua 代码。
从源码结构看,lua变换存在两个 API 版本:v1 已标记为 deprecated,将在未来版本中移除;v2 采用基于生命周期钩子的编程模型,通过hooks.init、hooks.process、hooks.shutdown三个钩子函数管理变换的初始化、事件处理与收尾,并支持source(初始化 Lua 代码,可引入外部依赖与定义钩子函数)与search_dirs(自定义依赖搜索路径)等配置(src/transforms/lua/mod.rs#L59-L72、src/transforms/lua/v2/mod.rs#L72-L80)。v2 还通过LuaMetricTagValues控制指标标签暴露方式(single/full)。
lua变换提供了最大的灵活性,因为你可以直接在 Vector 内部使用一门完整的编程语言。但我们建议只在确实必要时使用它,原因如下:
lua变换很容易让你写出缓慢、易出错且难以阅读的脚本;- 它要求你在使用 Vector 之外,额外引入一套编码/测试/调试工作流——如果你的用例没有其他办法满足,这一成本是值得的,但如非必要最好避免;
- 与 VRL 相比,它会带来性能开销。仓库中的 lua 基准测试 也从工程角度印证了这一点。
因此,实践中的推荐路径是:优先用 VRL 描述转换逻辑,仅在 VRL 确实无法表达(例如需要复杂外部库或非结构化算法)时才求助于 Lua。
小结
本文围绕 Vector 的核心变换组件remap与lua,完整走通了一条"解析 → 塑形 → 转换"的数据管道:
- 用
demo_logs源模拟 Syslog 数据,用remap变换配合 VRL 的parse_syslog、to_unix_timestamp、del、uuid_v4、contains、log等函数完成字段级转换,并通过consolesink 验证结果; - 理解了 VRL 的编译期错误检查、
.事件容器与路径语法,以及执行上下文(Vector 进程、VRL CLI、Playground、schema.log_namespace)对函数行为的影响; - 掌握了
remap在错误处理(drop_on_error、drop_on_abort、reroute_dropped)与外部程序文件(file/files)方面的扩展能力; - 了解了
lua运行时变换的 v1/v2 演进、钩子式编程模型及其在灵活性与性能、可维护性之间的权衡。
相关源码与配置均可在本仓库中继续深入研读:remap 变换实现、demo_logs 源实现、lua 变换实现、VRL 函数与测试 以及 VRL 基准测试。
【免费下载链接】vectorA high-performance observability data pipeline.项目地址: https://gitcode.com/GitHub_Trending/vect/vector
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考