-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
615 additions
and
358 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,4 +22,4 @@ nsgflowlogsbeat: | |
ignore_older: 0 | ||
|
||
# Number of workers | ||
message_processor_workers: 4 | ||
#workers: 4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,59 @@ | ||
// +build !integration | ||
|
||
package config | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/elastic/beats/libbeat/common" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
type validationTestCase struct { | ||
config Config | ||
errMsg string | ||
} | ||
|
||
func (v validationTestCase) run(t *testing.T) { | ||
if v.errMsg == "" { | ||
assert.NoError(t, v.config.Validate()) | ||
} else { | ||
err := v.config.Validate() | ||
if err != nil { | ||
assert.Contains(t, err.Error(), v.errMsg) | ||
} else { | ||
t.Errorf("expected error with '%s'", v.errMsg) | ||
} | ||
} | ||
} | ||
|
||
func TestConfigValidate(t *testing.T) { | ||
testCases := []validationTestCase{ | ||
// Top-level config | ||
{ | ||
Config{ | ||
StorageAccountName: "<storage_account_name>", | ||
StorageAccountKey: "<storage_account_key>", | ||
ContainerName: "<container_name>", | ||
CheckpointsTableName: "<checkpoints_table_name>", | ||
}, | ||
"", // No Error | ||
}, | ||
{ | ||
Config{}, | ||
"4 errors: account name is required; account key is required; checkpoints table name is required; container name is required", | ||
}, | ||
} | ||
|
||
for _, test := range testCases { | ||
test.run(t) | ||
} | ||
} | ||
|
||
func newConfig(from map[string]interface{}) *common.Config { | ||
cfg, err := common.NewConfigFrom(from) | ||
if err != nil { | ||
panic(err) | ||
} | ||
return cfg | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package nsgflowlogs | ||
|
||
import ( | ||
"context" | ||
"sync" | ||
|
||
"github.com/elastic/beats/libbeat/common" | ||
"github.com/elastic/beats/libbeat/common/atomic" | ||
"github.com/elastic/beats/libbeat/logp" | ||
"github.com/lstyles/nsgflowlogsbeat/checkpoint" | ||
"github.com/lstyles/nsgflowlogsbeat/config" | ||
) | ||
|
||
type EventACKer struct { | ||
active *atomic.Int | ||
wg *sync.WaitGroup | ||
config *config.Config | ||
checkpointTable *checkpoint.Table | ||
} | ||
|
||
func NewEventACKer(config *config.Config) (*EventACKer, error) { | ||
|
||
ct, err := checkpoint.NewCheckpointTable(config.StorageAccountName, config.StorageAccountKey, config.CheckpointsTableName, config.CheckpointsTableTimeout) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &EventACKer{ | ||
active: atomic.NewInt(0), | ||
wg: &sync.WaitGroup{}, | ||
config: config, | ||
checkpointTable: ct, | ||
}, nil | ||
} | ||
|
||
// ACKEvents receives callbacks from the publisher for every event that is | ||
// published. It persists the record number of the last event in each | ||
func (a *EventACKer) ACKLastEvent(data []interface{}) { | ||
|
||
for _, d := range data { | ||
|
||
logp.Info("Acking event %v", d) | ||
msg := d.(common.MapStr) | ||
batch_complete, err := msg.GetValue("batch_complete") | ||
if err != nil { | ||
logp.Error(err) | ||
continue | ||
} | ||
|
||
if batch_complete.(bool) { | ||
logp.Info("Batch complete: %v", batch_complete) | ||
|
||
index, _ := msg.GetValue("index") | ||
partitionKey, _ := msg.GetValue("partitionKey") | ||
rowKey, _ := msg.GetValue("rowKey") | ||
etag, _ := msg.GetValue("etag") | ||
|
||
a.checkpointTable.UpdateCheckpoint(partitionKey.(string), rowKey.(string), etag.(string), index.(int64)) | ||
} | ||
|
||
} | ||
} | ||
|
||
func (a *EventACKer) ACKCount(i int) { | ||
logp.Info("Acking %d out of %d active events.", i, a.Active()) | ||
a.active.Add(-1 * i) | ||
a.wg.Add(-1 * i) | ||
} | ||
|
||
// Wait waits for all events to be ACKed or for the context to be done. | ||
func (a *EventACKer) Wait(ctx context.Context) { | ||
ctx, cancel := context.WithCancel(ctx) | ||
go func() { | ||
defer cancel() | ||
a.wg.Wait() | ||
}() | ||
<-ctx.Done() | ||
} | ||
|
||
// Add adds to the number of active events. | ||
func (a *EventACKer) Add(delta int) { | ||
a.active.Add(delta) | ||
a.wg.Add(delta) | ||
} | ||
|
||
// Active returns the number of active events (published but not yet ACKed). | ||
func (a *EventACKer) Active() int { | ||
return a.active.Load() | ||
} |
Oops, something went wrong.