diff --git a/docs/config_interpolation.md b/docs/config_interpolation.md index 4498e7ca7b..090d5ec1bf 100644 --- a/docs/config_interpolation.md +++ b/docs/config_interpolation.md @@ -82,6 +82,9 @@ referred to will depend on the context of where the function is called. If a message contains the metadata key/value pair `foo: bar` the function `${!metadata:foo}` would resolve to `bar`. +If the argument is ommited then all key/value pairs within the metadata will be +printed in the following comma-separated format: `key1:value1,key2:value2,...`. + Message metadata can be modified using the [metadata processor](./processors/README.md#metadata). diff --git a/lib/util/text/function_vars.go b/lib/util/text/function_vars.go index 4459587fd1..56642dafe7 100644 --- a/lib/util/text/function_vars.go +++ b/lib/util/text/function_vars.go @@ -24,6 +24,7 @@ import ( "bytes" "os" "regexp" + "sort" "strconv" "strings" "sync" @@ -40,6 +41,7 @@ type Message interface { Get(p int) []byte GetJSON(p int) (interface{}, error) GetMetadata(key string) string + IterMetadata(func(k, v string) error) error Len() int } @@ -134,6 +136,19 @@ var functionVars = map[string]func(msg Message, arg string) []byte{ }, "json_field": jsonFieldFunction, "metadata": func(m Message, arg string) []byte { + if len(arg) == 0 { + keys := []string{} + m.IterMetadata(func(k, _ string) error { + keys = append(keys, k) + return nil + }) + sort.Strings(keys) + kvs := []string{} + for _, k := range keys { + kvs = append(kvs, k+":"+m.GetMetadata(k)) + } + return []byte(strings.Join(kvs, ",")) + } return []byte(m.GetMetadata(arg)) }, } diff --git a/lib/util/text/function_vars_test.go b/lib/util/text/function_vars_test.go index e1995c0aae..deb9d44dea 100644 --- a/lib/util/text/function_vars_test.go +++ b/lib/util/text/function_vars_test.go @@ -55,6 +55,7 @@ func TestFunctionVarDetection(t *testing.T) { func TestMetadataFunction(t *testing.T) { msg := types.NewMessage(nil) msg.SetMetadata("foo", "bar") + msg.SetMetadata("baz", "qux") act := string(ReplaceFunctionVariables( msg, []byte(`foo ${!metadata:foo} baz`), @@ -69,6 +70,13 @@ func TestMetadataFunction(t *testing.T) { if exp := "foo baz"; act != exp { t.Errorf("Wrong result: %v != %v", act, exp) } + + act = string(ReplaceFunctionVariables( + msg, []byte(`${!metadata}`), + )) + if exp := "baz:qux,foo:bar"; act != exp { + t.Errorf("Wrong result: %v != %v", act, exp) + } } func TestJSONFunction(t *testing.T) {