-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Description
A note for the community
- Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
- If you are interested in working on this issue or have submitted a pull request, please leave a comment
Problem
Loki sink: Inconsistent handling of null
values between static and dynamic structured_metadata
fields
Problem
The Loki sink handles null values inconsistently between static (templated) and dynamic (expanded with *
) structured_metadata fields. This creates unexpected "<null>"
string values in Loki that interfere with queries.
Current Behavior
-
Dynamic fields (using
*
expansion): Null values are correctly droppedstructured_metadata: "metadata_*": "{{ metadata }}" # null fields are omitted ✓
-
Static fields (using templates): Null values become the string
"<null>"
structured_metadata: request_id: "{{ request_id }}" # missing field → "<null>" ✗
Expected Behavior
Both static and dynamic structured_metadata fields should handle null values consistently by omitting the field entirely rather than sending "<null>"
.
Impact
This causes several issues:
- Query failures:
| request_id != ""
doesn't match logs whererequest_id
is literally"<null>"
- Storage waste: Storing meaningless
"<null>"
strings - User confusion: Unexpected string values instead of missing fields
Steps to Reproduce
-
Configure Vector with Loki sink:
sinks: loki: type: loki structured_metadata: # Static field request_id: "{{ request_id }}" # Dynamic field "dynamic_*": "{{ metadata }}"
-
Send an event without
request_id
field -
Query Loki:
{service="test"} | request_id != ""
-
Observe that the query returns no results because
request_id
contains the string"<null>"
Relevant Code
The issue is in sink/loki/sink.rs
:
pair_expansion()
function correctly checks for"<null>"
and skips dynamic fieldsbuild_structured_metadata()
doesn't perform this check for static fields after template rendering
// This check only happens for dynamic fields:
if val == "<null>" {
warn!("Encountered \"null\" value for dynamic pair. key: {}", key);
continue;
}
Proposed Solution
Add a null check in build_structured_metadata()
after template rendering:
let value_s = value.unwrap();
// Skip fields that rendered as <null>
if value_s == "<null>" {
warn!("Skipping structured metadata field '{}' with <null> value", key_s);
continue;
}
Version Information
- Vector version: 0.48.0 (and earlier)
- Loki version: 3.0+
Additional Context
This inconsistency also affects labels in the same way. The same fix should be applied to both build_labels()
and build_structured_metadata()
.
Related code locations:
src/sinks/loki/sink.rs
:EventEncoder::build_structured_metadata()
src/common/expansion.rs
:pair_expansion()
Configuration
Version
0.48.0
Debug Output
Example Data
No response
Additional Context
No response
References
Related #23040