feat(remap, lua, codecs): add auto value to metric_tag_values#25376
feat(remap, lua, codecs): add auto value to metric_tag_values#25376kaarolch wants to merge 3 commits intovectordotdev:masterfrom
auto value to metric_tag_values#25376Conversation
The `metric_tag_values` option (used by the `remap` and `lua` transforms) gains an `auto` value that exposes single-value tags as strings and multi-value tags as arrays, instead of forcing every tag into one form. Writes follow the same convention -- assigning a string or null to a tag stores it as a single tag, assigning an array stores it as a multi-value tag. This preserves the on-the-wire shape of metrics that mix single- and multi-value tags. The change replaces the internal `multi_value_tags: bool` plumbing with a `MetricTagMode` enum (`Single`/`Full`/`Auto`) in `vector-core`, with a `From<MetricTagValues>` conversion at the codecs boundary. `VrlTarget` and the Lua serialization paths dispatch on the new variant for both read (precompute) and write (insert) operations. Includes round-trip tests for Auto mode covering single/multi tag shapes, and write tests for string, array, and null assignments. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ed2edf3fe3
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| super::{Event, LogEvent, Metric}, | ||
| metric::LuaMetric, | ||
| }; | ||
| use crate::event::vrl_target::MetricTagMode; |
There was a problem hiding this comment.
Avoid importing MetricTagMode from vrl-only module
MetricTagMode is now imported from crate::event::vrl_target, but vrl_target is compiled only with feature = "vrl" while the lua feature does not enable that feature in vector-core. This makes vector-core --no-default-features --features lua fail with an unresolved module/type, so the commit breaks a valid feature combination that previously compiled.
Useful? React with 👍 / 👎.
Two follow-up fixes for PR vectordotdev#25376. P1 -- `vector-core --features lua` (without `vrl`) failed to compile because both lua submodules imported `MetricTagMode` from `crate::event::vrl_target`, but `vrl_target` is gated behind the `vrl` feature. Move `MetricTagMode` to a new always-compiled `event/metric_tag_mode.rs` module and re-export it from `crate::event`. Both vrl_target and the lua modules now reference the same type without forcing extra features. The codecs `From` impl already uses the canonical `vector_core::event::MetricTagMode` path, so no callers need to change. P2 -- in `auto` mode an empty tag set (`TagValueSet::Empty`, `len() == 0`) was emitted as `null` instead of `[]`, so a noop `.tags = .tags` round-trip silently converted an empty multi-value tag into a bare single-value tag. Change the discriminator in both `get_auto_value_tags` (VRL) and `LuaMetricTags::into_lua` (Lua) so only `len() == 1` scalarises -- empty sets keep their array shape. Adds two regression tests: * `metric_auto_read_empty_tag_set_returns_array` (vrl_target) * `auto_mode_empty_set_stays_array` (lua/metric) Verified: * `cargo check -p vector-core --no-default-features --features lua` * `cargo check -p vector-core --no-default-features --features vrl` * `cargo check -p vector-core --all-features` * `cargo test -p vector-core --features lua,vrl --lib auto` (9 passed, including the 2 new tests) * `cargo clippy -p vector-core --all-features --all-targets -- -D warnings` Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2f9283d63a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| let value = match tag_set.len() { | ||
| 1 => match tag_set.iter().next() { | ||
| Some(Some(s)) => Value::Bytes(s.as_bytes().to_vec().into()), | ||
| _ => Value::Null, |
There was a problem hiding this comment.
Preserve one-element arrays in auto metric tag mode
In auto mode, this branch scalarizes every tag set with len() == 1, which means an assignment like .tags.region = ["us-east-1"] is read back as a scalar string on the next transform pass instead of an array. That breaks the new mode’s documented write contract (arrays should remain multi-value) and can silently change downstream behavior that checks is_array(.tags.region).
Useful? React with 👍 / 👎.
Summary
Add a new
autovalue to themetric_tag_valuesoption of theremapandluatransforms.In
automode each tag is exposed using the shape that matches its underlying storage:nullfor bare tags).nullentries for bare values).Writes follow the same convention -- assigning a string or
nullstores a single-value tag, assigning an array stores a multi-value tag. This preserves the on-the-wire shape of metrics that mix single- and multi-value tags, instead of either collapsing everything to a single string (single) or wrapping everything as an array (full).When we wrap everything as an array (
full) we have to always remember to additional check per each tags. I agree that we should not used multi-value but unfortunately format like Dogstatsd allow to it and sometimes we have to process them.Vector configuration
How did you test this PR?
cargo check -p vector --lib --all-featurescargo clippy --workspace --all-targets --all-features -- -D warningscargo test -p vector-core(covering the newvrl_targetandlua/metricround-trip tests)lib/vector-core/src/event/vrl_target.rsandlib/vector-core/src/event/lua/metric.rsexercising:automodeautomodenullkeeps the tag as a bare single-value tagvectorbuild usingvector-poc-auto.yaml-- verified that for the same input metric,the
iter_singlebranch collapsed multi-value tags, theiter_fullbranch wrapped single-value tags as arrays in the VRL view, and the
iter_autobranch preserved both shapes through a noopmap_valuesiteration.Local result:
Change Type
The new
autovalue is purely additive. Existing configurations usingsingle(the default) orfullkeep their current behavior, and nointernal API used outside the transforms changed shape.
Is this a breaking change?
Does this PR include user facing changes?
no-changeloglabel to this PR.References
Notes
@vectordotdev/vectorto reach out to us regarding this PR.pre-pushhook, please see this template.make fmtmake check-clippy(if there are failures it's possible some of them can be fixed withmake clippy-fix)make testgit merge origin masterandgit push.Cargo.lock), pleaserun
make build-licensesto regenerate the license inventory and commit the changes (if any). More details on the dd-rust-license-tool.