Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherry-pick #18585 to 7.x: Add support for array parsing in azure-eventhub input #18650

Merged
merged 2 commits into from
May 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
- Improve ECS categorization field mappings in osquery module. {issue}16176[16176] {pull}17881[17881]
- Add support for v10, v11 and v12 logs on Postgres {issue}13810[13810] {pull}17732[17732]
- Add dashboard for Google Cloud Audit and AWS CloudTrail. {pull}17379[17379]
- Add support for array parsing in azure-eventhub input. {pull}18585[18585]
- The `logstash` module can now automatically detect the log file format (JSON or plaintext) and process it accordingly. {issue}9964[9964] {pull}18095[18095]
- Improve ECS categorization field mappings in coredns module. {issue}16159[16159] {pull}18424[18424]
- Improve ECS categorization field mappings in envoyproxy module. {issue}16161[16161] {pull}18395[18395]
Expand Down
32 changes: 25 additions & 7 deletions x-pack/filebeat/input/azureeventhub/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,14 +203,32 @@ func (a *azureInput) processEvents(event *eventhub.Event, partitionID string) bo

// parseMultipleMessages will try to split the message into multiple ones based on the group field provided by the configuration
func (a *azureInput) parseMultipleMessages(bMessage []byte) []string {
var obj map[string][]interface{}
err := json.Unmarshal(bMessage, &obj)
if err != nil {
a.log.Errorw(fmt.Sprintf("deserializing multiple messages using the group object `records`"), "error", err)
}
var mapObject map[string][]interface{}
var messages []string
if len(obj[expandEventListFromField]) > 0 {
for _, ms := range obj[expandEventListFromField] {
// check if the message is a "records" object containing a list of events
err := json.Unmarshal(bMessage, &mapObject)
if err == nil {
if len(mapObject[expandEventListFromField]) > 0 {
for _, ms := range mapObject[expandEventListFromField] {
js, err := json.Marshal(ms)
if err == nil {
messages = append(messages, string(js))
} else {
a.log.Errorw(fmt.Sprintf("serializing message %s", ms), "error", err)
}
}
}
} else {
a.log.Debugf("deserializing multiple messages to a `records` object returning error: %s", err)
// in some cases the message is an array
var arrayObject []interface{}
err = json.Unmarshal(bMessage, &arrayObject)
if err != nil {
// return entire message
a.log.Debugf("deserializing multiple messages to an array returning error: %s", err)
return []string{string(bMessage)}
}
for _, ms := range arrayObject {
js, err := json.Marshal(ms)
if err == nil {
messages = append(messages, string(js))
Expand Down
31 changes: 27 additions & 4 deletions x-pack/filebeat/input/azureeventhub/input_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"testing"
"time"

"github.com/elastic/beats/v7/libbeat/logp"

eventhub "github.com/Azure/azure-event-hubs-go/v3"
"github.com/stretchr/testify/assert"

Expand Down Expand Up @@ -70,17 +72,38 @@ func TestProcessEvents(t *testing.T) {
}

func TestParseMultipleMessages(t *testing.T) {
// records object
msg := "{\"records\":[{\"test\":\"this is some message\",\"time\":\"2019-12-17T13:43:44.4946995Z\"}," +
"{\"test\":\"this is 2nd message\",\"time\":\"2019-12-17T13:43:44.4946995Z\"}," +
"{\"test\":\"this is 3rd message\",\"time\":\"2019-12-17T13:43:44.4946995Z\"}]}"
input := azureInput{}
messages := input.parseMultipleMessages([]byte(msg))
assert.NotNil(t, messages)
assert.Equal(t, len(messages), 3)
msgs := []string{
fmt.Sprintf("{\"test\":\"this is some message\",\"time\":\"2019-12-17T13:43:44.4946995Z\"}"),
fmt.Sprintf("{\"test\":\"this is 2nd message\",\"time\":\"2019-12-17T13:43:44.4946995Z\"}"),
fmt.Sprintf("{\"test\":\"this is 3rd message\",\"time\":\"2019-12-17T13:43:44.4946995Z\"}")}
input := azureInput{log: logp.NewLogger(fmt.Sprintf("%s test for input", inputName))}
messages := input.parseMultipleMessages([]byte(msg))
assert.NotNil(t, messages)
assert.Equal(t, len(messages), 3)
for _, ms := range messages {
assert.Contains(t, msgs, ms)
}

// array of events
msg1 := "[{\"test\":\"this is some message\",\"time\":\"2019-12-17T13:43:44.4946995Z\"}," +
"{\"test\":\"this is 2nd message\",\"time\":\"2019-12-17T13:43:44.4946995Z\"}," +
"{\"test\":\"this is 3rd message\",\"time\":\"2019-12-17T13:43:44.4946995Z\"}]"
messages = input.parseMultipleMessages([]byte(msg1))
assert.NotNil(t, messages)
assert.Equal(t, len(messages), 3)
for _, ms := range messages {
assert.Contains(t, msgs, ms)
}

// one event only
msg2 := "{\"test\":\"this is some message\",\"time\":\"2019-12-17T13:43:44.4946995Z\"}"
messages = input.parseMultipleMessages([]byte(msg2))
assert.NotNil(t, messages)
assert.Equal(t, len(messages), 1)
for _, ms := range messages {
assert.Contains(t, msgs, ms)
}
Expand Down