Mapping one log event into multiple
Introducing new methods for converting a single log event into multiple using the remap
transform
This release enables transforming a single log event into multiple log events using the remap
transform. The
groundwork for this was laid in 0.14.0, but we’ve been waiting to announce it until the addition of the
unnest
function in this release.
The basic premise is that if you assign an array to the root object, .
, in a VRL program run by remap
, then remap
will create one log event for each event in the array.
For example:
[transforms.remap]
type = "remap"
inputs = []
source = """
. = [{"message": "hello"}, {"message": "world"}]
"""
Would generate two output events:
{"message": "hello"}
{"message": "world"}
Any array elements that are not key/value objects will be converted to an log event by creating a log event with the
message
key set to the array element value.
See the remap
transform docs for more examples.
Additionally, to make it easier to convert an incoming log event into an array, we’ve added an unnest
function to VRL that transforms an incoming event where one of the fields is an array into an array of events, each with
one of the elements from the array field. This is easiest to see with an example:
[transforms.remap]
type = "remap"
inputs = []
source = """
. = {"host": "localhost", "events": [{"message": "hello"}, {"message": "world"}]} # to represent the incoming event
. = unnest(.events)
"""
Would output the following log events:
{ "events": { "message": "hello" }, "host": "localhost" }
{ "events": { "message": "world" }, "host": "localhost" }
In the future, we plan to add functionality to VRL to allow iterating over arrays, but, for now, the simple case of
mapping each event in an array separately can be done by having one remap
transform do the “exploding” of the event,
and another remap
transform to receive each new event.
An example of this:
[transforms.explode]
type = "remap"
inputs = []
source = """
. = {"host": "localhost", "events": [{"message": "hello"}, {"message": "world"}]} # to represent the incoming event
. = unnest(.events)
"""
[transforms.map]
type = "remap"
inputs = ["explode"]
source = """
# example of pulling up the nested field to merge it into the top-level
. |= .events
del(.events)
"""
Would output the following log events:
{ "message": "hello", "host": "localhost" }
{ "message": "world", "host": "localhost" }