Skip to main content

KV Pack

Transform String Data

Synopsis

Builds a single key<kv_separator>value string from a list of key-value pairs, supporting template resolution for dynamic values, and writes the result to a target field.

Schema

- kv_pack:
field: <ident>
items:
- key: <string>
value: <string>
separator: <string>
kv_separator: <string>
sort: <enum>
skip_empty: <boolean>
description: <text>
if: <script>
ignore_failure: <boolean>
ignore_missing: <boolean>
on_failure: <processor[]>
on_success: <processor[]>
tag: <string>

Configuration

The following fields are used to define the processor:

FieldRequiredDefaultDescription
fieldY-Target field to store the joined key-value string
itemsY-Array of key-value pairs to include in the string
items.keyY-Key name for the pair
items.valueY-Value for the pair (supports templates)
separatorN;Character(s) used to separate key-value pairs
kv_separatorN=Character(s) used to separate a key from its value
sortNascSort order for keys: asc or desc
skip_emptyNfalseSkip items with empty values
descriptionN-Explanatory note
ifN-Condition to run
ignore_failureNfalseContinue if processor fails
ignore_missingNfalseContinue if source field doesn't exist
on_failureN-Processors to run on failure
on_successN-Processors to run on success
tagN-Processor identifier

Item Configuration

Each item in the items array supports:

  • key: The key name in the resulting string
  • value: The value to assign (supports template expressions like {{field_name}})

Details

kv_pack fuses what previously took a bag_pack (resolve items into a map) followed by a join_kv (re-walk that map back into a string) into one step: it resolves each item value once, optionally skips empties, sorts the keys, and joins them straight into the target field as a string. There is no intermediate map, and unlike bag_pack, kv_pack does not write a sort-index metadata field alongside the result.

Keys are always sorted before joining, case-insensitively. The default (sort: asc, or sort omitted) sorts ascending; sort: desc sorts descending. kv_pack does not support an index sort mode, since it never builds the sort-index metadata that mode depends on — pipelines that need index-ordered output keep using bag_pack followed by join_kv with sort: index.

Values support template expressions using {{field_name}} syntax, allowing dynamic content insertion from other fields in the log entry. A value without {{ is used as a literal string verbatim. Template-resolved values that are whole numbers are formatted without decimal places, non-whole numeric values are formatted with 6 decimal places, and booleans are formatted as true/false; this value formatting is shared with join_kv so the two produce identical output for the same items.

The skip_empty option excludes items whose resolved value is null, an empty string, or an empty array/object from the joined string. When ignore_missing is enabled, items whose templated value references a missing field are skipped rather than causing the processor to fail.

Examples

Basic Usage

Joining user fields into a single key-value string...

{
"user": {
"name": "john_doe",
"dept": "engineering"
}
}
- kv_pack:
field: user_summary
items:
- key: username
value: "{{user.name}}"
- key: department
value: "{{user.dept}}"
- key: role
value: "admin"

produces a single string with keys sorted ascending:

{
"user": {
"name": "john_doe",
"dept": "engineering"
},
"user_summary": "department=engineering;role=admin;username=john_doe"
}

Custom Separators

Using custom pair and key-value separators...

{
"http": {
"method": "GET",
"status": 200,
"path": "/api/users"
}
}
- kv_pack:
field: http_summary
separator: "|"
kv_separator: ":"
items:
- key: method
value: "{{http.method}}"
- key: status
value: "{{http.status}}"
- key: path
value: "{{http.path}}"

joins with the configured separators, keys sorted ascending:

{
"http": {
"method": "GET",
"status": 200,
"path": "/api/users"
},
"http_summary": "method:GET|path:/api/users|status:200"
}

Sort Order

Sorting keys in descending order...

{
"event": {
"action": "login",
"user": "alice",
"status": "success"
}
}
- kv_pack:
field: event_summary
sort: desc
items:
- key: action
value: "{{event.action}}"
- key: user
value: "{{event.user}}"
- key: status
value: "{{event.status}}"

reverses the key ordering:

{
"event": {
"action": "login",
"user": "alice",
"status": "success"
},
"event_summary": "user=alice;status=success;action=login"
}

Skip Empty Values

Using skip_empty to exclude null and empty values...

{
"user": {
"email": "john@example.com",
"phone": "",
"address": null,
"city": "Berlin"
}
}
- kv_pack:
field: contact_summary
skip_empty: true
items:
- key: email
value: "{{user.email}}"
- key: phone
value: "{{user.phone}}"
- key: address
value: "{{user.address}}"
- key: city
value: "{{user.city}}"

only includes non-empty values:

{
"user": {
"email": "john@example.com",
"phone": "",
"address": null,
"city": "Berlin"
},
"contact_summary": "city=Berlin;email=john@example.com"
}