Vector 组件自动校验机制解析:从 RFC 到 `ValidatableComponent` 验证框架

发布时间:2026/9/13 6:07:38
Vector 组件自动校验机制解析:从 RFC 到 `ValidatableComponent` 验证框架 Vector 组件自动校验机制解析从 RFC 到ValidatableComponent验证框架【免费下载链接】vectorA high-performance observability data pipeline.项目地址: https://gitcode.com/GitHub_Trending/vect/vector本文以仓库内 RFC 文档 rfcs/2022-11-04-automatic-component-validation.md 为核心脉络结合 docs/specs/component.md 组件规范与 src/components/validation 下的实际实现源码完整讲解 Vector 如何通过一套自动化的“验证运行器Validation Runner”机制确保每个可被用户使用的组件都被系统化地测试——包括对组件规范的符合性Component Specification adherence以及内部遥测指标数值的正确性。读完本文你将掌握ValidatableComponenttrait、外部资源定义、测试用例 YAML 格式、可插拔 Validator 与 Runner 的整体设计并了解如何在当前仓库中实际运行与扩展这套校验体系。一、为什么需要自动组件校验背景与痛点Vector 团队长期面临一个棘手问题如何确认组件发出的内部遥测既准确又一致。这里的内部遥测主要指与组件相关的指标例如 source 收到的字节数、sink 发送的事件数、错误计数等。用户在构建仪表盘dashboard和告警规则时依赖这些指标在不同组件类型之间保持一致的语义因此其正确性至关重要。RFC 中明确指出现状下的几类痛点手动校验不可靠为某个组件写单元测试可以检查符合性但如果忘记写测试或在修改所有 source 的行为时没有同步更新全部单元测试符合性检查就会迅速与现实脱节。社区贡献者门槛高Vector 核心作者可能已经熟能生巧地知道该发出哪些指标但第一次贡献代码的人几乎不可能凭空知道这些要求除非存在一种机制主动提示他们。人类本身容易犯错检查数据时看错数字、误以为某个指标存在等情形屡见不鲜。RFC 的Context一节列举了大量真实 issue/PR如 #8858 增加组件规范、#9308 增加表面扫描脚本、#9687/#9688 审计 sources/sinks 合规性、#13995 验证component_discarded_events_total与component_errors_total、#14073 验证 route transform 的丢弃指标等这些都是在多位工程师反复检查后仍漏掉的问题恰恰证明了纯人工流程的局限性。范围界定ScopeRFC 明确了本机制的目标边界在范围内对照 Component Specification 校验组件发出的事件与指标校验指标数值的正确性例如向 source 发送 100 字节请求bytes received指标就必须准确增加 100。不在范围内不校验组件所有可能的配置排列组合不校验组件的功能行为如某个 transform 是否真的把所有字符串转成了小写不校验 sources、transforms、sinks 之外的组件类型。二、核心设计可插拔、可自动化的三层抽象RFC 提出的方案并非为每个组件手写散落的单元测试而是构建一个集中的验证运行器。其用户侧体验User Experience非常关键可用即被测试只要组件被编译进某个 Vector 二进制即组件可用它就会自动暴露给测试机制。理想情况下把组件包含进一次构建却不让它被测到这件事应该几乎不可能发生。在隔离拓扑中运行验证运行器会构造一个隔离的 Vector 拓扑来运行被测组件并为它提供所有必要的输入/输出使其构成合法拓扑。通过控制送入拓扑的输入事件、收集输出事件与遥测测试场景比简单单元测试更接近 Vector 在真实客户环境中的运行方式。跑在单元测试里运行器本身作为单元测试运行接收待校验组件列表 每个组件的测试用例输入事件集合与期望结果如成功/失败逐个隔离执行任何失败用例都会导致整个测试失败。本地命令 CI 双重保障为开发者提供本地运行校验测试的命令同时 CI 中也要确保在校验测试跑在接近真实 release的二进制上从而覆盖所有可用组件。2.1ValidatableComponenttrait组件自我声明可被校验RFC 中给出了该 trait 的略缩版本。在当前仓库的实际实现里src/components/validation/mod.rstrait 已演化为如下形式pub trait ValidatableComponent: Send Sync { /// Gets the validation configuration for this component. /// /// The validation configuration compromises the two main requirements for validating a /// component: how to configure the component in a topology, and what external resources, if /// any, it depends on. fn validation_configuration() - ValidationConfiguration; }而ValidationConfiguration承接了 RFC 中关于组件名、组件类型、配置、外部资源的信息pub struct ValidationConfiguration { component_name: static str, component_type: ComponentType, /// There may be only one ComponentTestCaseConfig necessary to execute all test cases, but some cases /// require more advanced configuration in order to hit the code path desired. component_configurations: VecComponentTestCaseConfig, log_namespace: LogNamespace, }其中ComponentType只有三种取值——Source、Transform、Sink并可通过as_str()得到source/transform/sink字符串。ComponentConfiguration是一个大枚举封装了BoxedSource/BoxedTransform/BoxedSink也就是说组件配置是可以真正交给ConfigBuilder使用的对象。RFC 特别讨论了一个重要设计取舍ValidatableComponent能否从已有的SourceConfig等配置 trait 自动派生结论是不能完全自动。原因在于http_serversource 的SourceConfig::resources声明的是它自己需要一个 TCP socket 监听端口而校验运行器关心的是为了驱动这个组件外部需要提供什么资源——对http_server而言是一个真正向它发 HTTP 请求的客户端。外部资源本质上是组件声明资源SourceConfig::resources的逆关系但仅靠取反还缺少大量信息socket 用什么协议/编码组件会触碰的资源如读写的文件又该如何表达因此 RFC 明确ValidatableComponent的实现无法自动由现有配置 trait 驱动但未来可通过对资源声明补充元数据来统一两者。2.2 外部资源定义ExternalResource与方向性RFC 认为外部资源是ValidatableComponent中最重要的部分。它需要回答三个问题资源类型网络 socket、磁盘文件等、数据流动方向、载荷类型。RFC 给出的原型代码如下pub enum ResourceCodec { Encoding(EncodingConfig), EncodingWithFraming(EncodingConfigWithFraming), Decoding(DecodingConfig), DecodingWithFraming(DecodingConfig, decoding::FramingConfig), } pub enum ResourceDirection { Push, Pull } pub enum ResourceDefinition { Http(HttpConfig), Socket(SocketConfig), } pub struct ExternalResource { definition: ResourceDefinition, direction: ResourceDirection, codec: ResourceCodec, }方向Direction的语义在 RFC 中有详细解释。方向是站在外部资源视角描述的数据流动以http_serversource 为例外部资源是向它发请求的 HTTP 客户端客户端必须主动发起 HTTP 请求把数据推给 source所以方向是Push以kafkasource 为例则方向反转source 必须向 broker 拉取下一批消息外部资源是Pullsink 方向正好反过来sink 主动发起数据流时外部资源被推送Push外部资源需要向 sink 索取数据时则是 Pull。载荷Payload / Codec是设计的另一难点需要一种通用方式描述载荷类型无论是原始字节形式如经 TCP socket 发送的字节还是内部事件形式如要传给 transform 的Event。RFC 的方案是复用组件已有的编解码配置类型EncodingConfig、EncodingConfigWithFraming、DecodingConfig并提供开箱即用的编码↔解码互逆转换sink 用编码配置声明载荷后运行器能自动生成一个知道如何解码 sink 所发内容的外部资源。RFC 也坦承现有编解码枚举之间并不完全对等需要通过后续工作补齐每种编码都有对应的解码器、反之亦然这一目标。当前仓库中的实现src/components/validation/resources/mod.rs与此高度吻合pub enum ResourceCodec { /// Component encodes events. Encoding(EncodingConfig), /// Component encodes events, with a specific framer. EncodingWithFraming(EncodingConfigWithFraming), /// Component decodes events. Decoding(DecodingConfig), } pub enum ResourceDirection { Pull, Push } pub enum ResourceDefinition { Http(HttpResourceConfig) } pub struct ExternalResource { pub direction: ResourceDirection, definition: ResourceDefinition, pub codec: ResourceCodec, }实现中ResourceCodec提供了两个关键方法源码位于 src/components/validation/resources/mod.rsinto_encoder()由解码配置生成满足该解码的编码器逆由编码配置则直接构建编码器into_decoder(log_namespace)反向操作由编码配置生成解码器。此外还有一套deserializer_config_to_serializer/serializer_config_to_deserializer/decoder_framing_to_encoding_framer/encoder_framing_to_decoding_framer等互逆转换函数覆盖 Bytes、JSON、NewlineDelimited、LengthDelimited、VarintLengthDelimited 等常见 codec部分暂未实现的组合以todo!()/unimplemented!()标注。ExternalResource通过spawn_as_input驱动 source与spawn_as_output收集 sink 输出把资源真正拉起目前唯一落地的资源类型是HttpResourceConfig。2.3 测试用例YAML 驱动的输入与期望RFC 为测试用例定义了明确的文件约定tests/validation/components/component type/component name.yaml其中组件类型为复数形式sources、transforms、sinks组件名取自ValidatableComponent::component_name即 Vector 配置中引用该组件的名字。RFC 中的基础示例- name: happy path expectation: success events: - simple message 1 - simple message 2 - simple message 3配套的 Rust 类型RFC 原型与实际实现略有差异pub enum TestCaseExpectation { Success, Failure, PartialSuccess } pub enum TestEvent { Passthrough(EventData), Modified { modified: bool, event: EventData }, } pub enum EventData { Log(String) } pub struct TestCase { pub expectation: TestCaseExpectation, pub events: VecTestEvent, }RFC 详细解释了这些辅助类型的设计动机EventData减少样板常见的日志事件通常被解析为带message字段的 log event因此测试用例里只需写一个普通字符串反序列化时自动构造成标准形态免去声明这是 log 事件、字符串要放进message字段等冗余信息。这一模式可推广到各类 metric 类型。TestEvent表达修改后诱导失败很多情况下仅靠调整事件数据本身无法诱发失败而是需要外部资源配合例如使用错误的 codec。与其在测试用例里穷举如何修改才能让组件失败不如把如何诱发失败的责任交给外部资源测试用例只声明这条事件需要被修改。对http_serversource 而言最自然的失败路径就是载荷无法被解码因此外部 HTTP 客户端可以用一个与配置不同的编码来编码该事件。RFC 中的示例- name: one bad apple expectation: partial_success events: - good message 1 - modified: true event: bad message 1 - good message 22.4 可插拔 Validator校验逻辑的插件化RFC 将组件校验到底校验什么抽象为Validatortraitpub trait Validator { fn name(self) - static str; fn check_validation( self, component_type: ComponentType, expectation: TestCaseExpectation, inputs: [TestEvent], outputs: [Event], telemetry_events: [Event], ) - ResultVecString, VecString; }Validator 在拓扑运行结束、所有输出与遥测事件收集完毕后被调用。每个 Validator 都能拿到该测试用例运行的全部关键信息组件类型、期望结果、输入事件、输出事件、全部遥测事件——这恰好覆盖了两个最重要 Validator 的基础需求Component Specification 校验器与Metrics Correctness 校验器。值得强调的是收集信息是运行器的职责Validator 无需自行采集这也让 Validator 本身可以被轻松地单元测试。当前仓库实现src/components/validation/validators/mod.rs中check_validation额外接收了一个runner_metrics: RunnerMetrics参数。RunnerMetrics定义于 src/components/validation/mod.rs由输入/输出驱动任务填充作为期望值与组件实际发出的指标做对比其字段与组件规范中的指标一一对应pub struct RunnerMetrics { pub received_events_total: u64, pub received_event_bytes_total: u64, pub received_bytes_total: u64, pub sent_bytes_total: u64, pub sent_event_bytes_total: u64, pub sent_events_total: u64, pub errors_total: u64, pub discarded_events_total: u64, }ComponentMetricType枚举则把这些字段映射为组件规范中规定的指标名源码 src/components/validation/validators/mod.rscomponent_received_events_total、component_received_event_bytes_total、component_received_bytes_total、component_sent_events_total、component_sent_bytes_total、component_sent_event_bytes_total、component_errors_total、component_discarded_events_total——这些正是 docs/specs/component.md 中 Instrumentation 一节规定的核心计数器。目前唯一落地的标准 Validator 是StandardValidators::ComponentSpec见 src/components/validation/validators/component_spec/mod.rs。2.5 Runner把所有环节串起来RFC 用一段测试代码演示 Runner 的用法注意 RFC 中的从inventory收集全部组件被设计为最终形态当前仓库实际是先通过validate_component按路径驱动单个组件#[test] async fn compliance() { let validatable_components get_all_validatable_components(); for validatable_component in validatable_components { let component_name validatable_component.component_name(); let component_type validatable_component.component_type(); let mut runner Runner::from_component(validatable_component); runner.add_validator(StandardValidators::ComponentSpec); match runner.run_validation().await { Ok(test_case_results) { /* 逐条展示成功/失败详情 */ } Err(e) panic!(Failed to complete validation run for component {}: {}, component_name, e), } } }Runner 的执行语义是为每个测试用例拉起所需的输入/输出任务、必要时拉起外部资源、构造组件拓扑并在独立隔离的 Tokio runtime中启动随后按正确顺序驱动这些任务直至完成收集输出事件与遥测事件最后调用 Validator 判定通过与否并以人类可读的文本输出成功或失败细节。三、从 RFC 到落地当前仓库的实现对照RFC 提出后仓库中已形成了完整的实现目录值得逐一对号入座RFC 概念仓库落地点ValidatableComponenttraitsrc/components/validation/mod.rsValidationConfiguration/ComponentConfiguration/ComponentTestCaseConfigsrc/components/validation/mod.rs组件注册宏register_validatable_component!src/components/validation/mod.rs基于inventory::submit!ExternalResource/ResourceCodec/ResourceDirection/ResourceDefinitionsrc/components/validation/resources/mod.rsHTTP 外部资源实现src/components/validation/resources/http.rs测试事件与编码TestEvent/EventData/encode_test_eventsrc/components/validation/resources/event.rsValidatortrait 与StandardValidatorssrc/components/validation/validators/mod.rsComponent Spec 校验器src/components/validation/validators/component_spec/mod.rsRunner/RunnerInput/RunnerOutput/ 拓扑构建src/components/validation/runner/mod.rs、src/components/validation/runner/config.rs任务协调TaskCoordinatorsrc/components/validation/sync.rs测试用例 YAML 反序列化src/components/validation/test_case.rs与 RFC 原型相比落地实现有几处明显演进Trait 形态更简洁ValidatableComponent收敛为单一的fn validation_configuration()把名称/类型/配置/外部资源全部封装进ValidationConfiguration并且一个组件可以声明多个ComponentTestCaseConfig每个可关联不同的test_case名与外部资源以覆盖需要不同配置才能触达的代码路径。注册机制落地新增register_validatable_component!宏inventory::submit!包装与ValidatableComponentDescription类型ValidatableComponentDescription::query支持按组件名类型检索配置。RFC 中通过#[configurable_component(...)]自动收集全部组件的设想在 Plan of Attack 中被明确为最后的收尾步骤。测试事件模型具体化RawTestEvent支持三种形态——Passthrough原样使用、AlternateEncoder用与配置不同的编码器编码诱导解码失败、ResourceReject事件编码成功但外部资源主动拒绝诱导失败。其中AlternateEncoder的实现逻辑src/components/validation/resources/event.rs会检查当前编码器supports_json()然后在 JSON 与 Logfmt 两种序列化器之间取反选择非常巧妙地用最小代码实现了 RFC 中用错误编码诱发失败的设计。3.1 一次完整校验运行的内部时序结合 src/components/validation/runner/mod.rs 的Runner::run_validation实现一次校验运行的完整步骤为initialize_test_environment()调用crate::metrics::init_test()让指标记录器进入测试模式按线程隔离指标并停止日志早期缓冲避免internal_logssource 死锁。加载tests/validation/components/type/name.yaml中的全部测试用例serde_yaml反序列化。对每个测试用例通过TopologyBuilder::from_configuration构造合法拓扑的ConfigBuilder——注意运行器会为被测组件注入填充组件filler例如被测对象是 sink 时补一个 source 喂数据、被测对象是 source 时补一个 sink 收集输出。若组件声明了外部资源则按其方向spawn_as_inputsource 场景输入事件经 channel 送进外部资源或spawn_as_outputsink 场景外部资源经 channel 回传收集到的输出事件。用TaskCoordinator分阶段Input / Output / Topology / Telemetry协调各任务的就绪与关闭等待拓扑启动后再 sleep 2 秒确保组件真正就绪。启动输入驱动任务发送事件并累计RunnerMetrics期望值与输出驱动任务收集输出事件带 8 秒超时保护。按顺序关闭各阶段先收完输入、再收完输出、最后关遥测与拓扑保证确定性。将输入、输出、遥测事件与RunnerMetrics一并交给每个 Validator 执行check_validation汇总为RunnerResults。若有任何失败panic!并打印失败详情全部通过则输出成功信息。其中spawn_component_topology会在独立线程里构建一个 current-thread Tokio runtime运行RunningTopology并关闭 healthchecks——这正是 RFC 所强调的隔离不同测试用例的遥测不会互相污染验证框架自身代码产生的内部遥测也不会泄漏进被测组件的收集结果。3.2 真实的测试用例文件长什么样仓库tests/validation/components/目录下已有 7 个组件的测试用例sources/http_server.yaml、sources/http_client.yaml、sources/splunk_hec.yaml、sources/datadog_agent.yaml、sinks/http.yaml、sinks/splunk_hec_logs.yaml、sinks/datadog_logs.yaml。以 tests/validation/components/sources/http_server.yaml 为例它正好体现了 RFC 中happy path 失败路径两种用例- name: happy path expectation: success events: - log: simple message 1 - log: simple message 2 - log: simple message 3 - name: sad path expectation: partial_success events: - log: simple message 1 - log: simple message 2 - fail_encoding_of: log: simple message with the wrong encoding对比可见落地后的 YAML 语法与 RFC 原型略有差异modified: true演变为更明确的fail_encoding_of:键对应RawTestEvent::AlternateEncoderpartial_success的期望值命名保持一致。log:键对应EventData::Log另外实现中还支持log_builder:键值对形式构造日志事件见 src/components/validation/resources/event.rs可以构造带自定义字段的事件例如datadog_agent等需要特定字段的 source 场景。测试的入口src/components/validation/mod.rs使用了test_generator::test_resources(tests/validation/components/**/*.yaml)宏为每个 YAML 文件自动生成一个测试函数并调用validate_component而validate_component会从路径中解析出组件类型与名称目录倒数第二段必须是sources/transforms/sinks最后一段去扩展名即组件名再通过ValidatableComponentDescription::query找到对应的校验配置并执行。3.3 组件侧如何接入一个实现示例实际实现ValidatableComponent的组件包括http_server、http_client、datadog_agent、splunk_hec、splunk_hec_logs、datadog_logs等如 src/sources/http_server.rs、src/sinks/http/config.rs、src/sinks/datadog/logs/config.rs。以 source 为例组件的接入方式大致是定义一个持有ValidationConfiguration的验证描述类型在validation_configuration()中通过ValidationConfiguration::from_source(...)指定组件名、LogNamespace与若干ComponentTestCaseConfig通过register_validatable_component!宏把该类型注册进inventory。这正是 RFC 中组件负责实现 trait、提供配置与外部资源设想的直接落地而把所有已注册组件一键全部校验则通过ValidatableComponentDescription::query与inventory迭代机制成为可能。四、设计权衡为什么这么做以及替代方案4.1 理由RationaleRFC 的核心理由非常朴素我们需要准确的内部遥测。用户依赖 Vector 的内部遥测判断其是否按预期运行、是否获得了部署的全部收益例如通过减少数据出口来节省成本。当所有组件在完全加入代码库的瞬间就被自动测试时不仅新组件能得到正确测试已有组件也能持续被回归测试覆盖。如果不做这件事那些很可能已经错了但至今未被发现的指标将继续漏网回归和漏测也会反复出现最终留下一串语义微妙的错误遥测。4.2 缺点DrawbacksRFC 坦承两个主要代价每个组件都要增加样板代码虽然不算繁重但ValidatableComponent实现与已有的SourceConfig等配置 trait 看起来非常相似属于额外的、长得像已有样板的新样板。同进程内运行拓扑带来隔离成本被测拓扑与测试框架运行在同一进程需要确保不同校验运行的内部遥测互不串扰且运行器自身代码产生的遥测不泄漏进被测组件的收集结果。这虽然可实现但需要额外的小工作量。4.3 先例Prior Art与替代方案AlternativesRFC 指出 Vector 已有针对组件规范的校验机制即assert_sink_compliance、assert_source_error等辅助方法可在 src/test_util 与各组件测试中找到使用痕迹。它们与本提案思路相近——在代码运行前后观察系统状态并计算校验结果。但现有机制只断言特定内部遥测被发出无法断言遥测数值正确更重要的是两者都无法保证一个可用组件真的被测过。一个被认真评估过的替代方案是像集成测试/soak test 那样真正构建 Vector 并启动独立进程从外部发送已知数据并收集输出类似lading在 soak test 中的做法即把Runner中从ConfigBuilder构建RunningTopology替换为生成真实 Vector 配置并启动一个 Vector 进程。该方案能彻底解决遥测隔离每次测试都是全新进程也允许提供完整配置文件。但其代价是失去进程内程序化控制能力无法使用应用内同步原语判断组件/任务就绪只能退化为不断尝试连接 TCP socket 直到连上收集/判定错误更难某些情况下被迫解析 Vector 进程的 stdout/stderr 来理解配置问题。4.4 悬而未决的问题与未来改进RFC 记录的 Outstanding Questions 包括外部资源定义模型是否足够灵活以覆盖所有外部资源形态对网络 socket 特定编码这类简单场景显然够用但能否平滑外推以及能否在不真正跑起 Kafka broker 之类外部系统的情况下有意义地提供这类资源。Plan of Attack按 RFC 原文列出的推进路线多数已在当前仓库中兑现合并 RFC PR含 PoC 实现——已完成即 src/components/validation 整套代码实现 Component Specification 校验器——已完成ComponentSpecValidator实现 Metrics Correctness 校验器校验source 收到的字节数指标 实际发送的字节数等——尚未在StandardValidators中出现属于待办实现更多外部资源raw socket、可模拟的特定服务如 Elasticsearch——其本质是带特定路由的 HTTP——当前仅有HttpResourceConfig为更多组件实现ValidatableComponent先在硬编码列表中逐个加入最后再切换为全有或全无将获取全部可校验组件的方法改为从inventory注册自动收集从而真正实现凡编译进二进制且可配置使用#[configurable_component(...)]的组件都必须通过校验。Future Improvements则展望了更远的方向增加高基数检测、功能校验等更多 Validator以类似 property testing 的方式驱动输入从而发现本应处理却没有处理的合法输入、或组件已确认处理事件但指标未更新等问题允许在测试用例数据中直接指定组件配置覆盖ValidatableComponent::component_configuration的默认值把ValidatableComponent的名称/类型部分抽取为可由#[configurable_component(...)]自动派生的通用 trait以及尝试将各组件配置 trait 与ValidatableComponent统一为更通用的基础 trait。五、如何在当前仓库中查看与运行这套校验以下操作均基于当前仓库的只读源码读者可按需在自己的环境中执行阅读设计文档先读 rfcs/2022-11-04-automatic-component-validation.md 了解设计动机再对照 docs/specs/component.md 的 Instrumentation 一节理解组件必须发出哪些事件与指标如component_received_events_total、component_sent_bytes_total、component_errors_total、component_discarded_events_total等详见 docs/specs/instrumentation.md。查看实现核心代码集中在 src/components/validation 目录下mod.rs、runner/、resources/、validators/、sync.rs、test_case.rs组件接入示例可参考 src/sources/http_server.rs 与 src/sinks/http/config.rs。查看测试用例全部现有测试用例位于 tests/validation/components 目录按sources/transforms/sinks分目录存放。运行校验测试仓库通过test_generator为每个 YAML 文件生成测试需要开启component-validation-testsfeature 及相关构建配置代码路径见 src/components/validation/mod.rs 底部的#[cfg(all(test, feature component-validation-tests))] mod tests并使用cargo test系列命令执行完整命令应以仓库Cargo.toml与 CI 配置为准。总结Vector 的自动组件校验机制回答了如何让每个可用组件都被正确测试这一工程难题。它以ValidatableComponenttrait 作为组件自我声明的入口以ExternalResource方向 载荷编码描述组件与外界的依赖关系以 YAML 测试用例表达输入事件 期望结果以可插拔的Validator承载组件规范符合性与指标正确性等校验逻辑并由Runner在隔离的 Tokio runtime 中自动完成建拓扑 → 驱动输入 → 收集输出与遥测 → 执行校验 → 汇报结果的全流程。RFC 中的设计与当前仓库 src/components/validation 的实现高度一致且已经通过tests/validation/components下的真实用例落地运行——这正是 Vector 保证其内部遥测长期准确、一致的底层基础设施。【免费下载链接】vectorA high-performance observability data pipeline.项目地址: https://gitcode.com/GitHub_Trending/vect/vector创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考