正在显示
8 个修改的文件
包含
185 行增加
和
9 行删除
@@ -49,10 +49,9 @@ Processors: | @@ -49,10 +49,9 @@ Processors: | ||
49 | - index | 49 | - index |
50 | - beat | 50 | - beat |
51 | - docker_container | 51 | - docker_container |
52 | - - offset | ||
53 | - - prospector | ||
54 | - - source | ||
55 | - - stream | 52 | + - Action: transfer |
53 | + Field: message | ||
54 | + Target: data | ||
56 | Output: | 55 | Output: |
57 | ElasticSearch: | 56 | ElasticSearch: |
58 | Hosts: | 57 | Hosts: |
@@ -49,10 +49,9 @@ Processors: | @@ -49,10 +49,9 @@ Processors: | ||
49 | - index | 49 | - index |
50 | - beat | 50 | - beat |
51 | - docker_container | 51 | - docker_container |
52 | - - offset | ||
53 | - - prospector | ||
54 | - - source | ||
55 | - - stream | 52 | + - Action: transfer |
53 | + Field: message | ||
54 | + Target: data | ||
56 | Output: | 55 | Output: |
57 | ElasticSearch: | 56 | ElasticSearch: |
58 | Hosts: | 57 | Hosts: |
@@ -24,9 +24,11 @@ type ( | @@ -24,9 +24,11 @@ type ( | ||
24 | } | 24 | } |
25 | 25 | ||
26 | Filter struct { | 26 | Filter struct { |
27 | - Action string `json:",options=drop|remove_field"` | 27 | + Action string `json:",options=drop|remove_field|transfer"` |
28 | Conditions []Condition `json:",optional"` | 28 | Conditions []Condition `json:",optional"` |
29 | Fields []string `json:",optional"` | 29 | Fields []string `json:",optional"` |
30 | + Field string `json:",optional"` | ||
31 | + Target string `json:",optional"` | ||
30 | } | 32 | } |
31 | 33 | ||
32 | Processor struct { | 34 | Processor struct { |
@@ -5,6 +5,7 @@ import "github.com/tal-tech/go-stash/stash/config" | @@ -5,6 +5,7 @@ import "github.com/tal-tech/go-stash/stash/config" | ||
5 | const ( | 5 | const ( |
6 | filterDrop = "drop" | 6 | filterDrop = "drop" |
7 | filterRemoveFields = "remove_field" | 7 | filterRemoveFields = "remove_field" |
8 | + filterTransfer = "transfer" | ||
8 | opAnd = "and" | 9 | opAnd = "and" |
9 | opOr = "or" | 10 | opOr = "or" |
10 | typeContains = "contains" | 11 | typeContains = "contains" |
@@ -22,6 +23,8 @@ func CreateFilters(p config.Processor) []FilterFunc { | @@ -22,6 +23,8 @@ func CreateFilters(p config.Processor) []FilterFunc { | ||
22 | filters = append(filters, DropFilter(f.Conditions)) | 23 | filters = append(filters, DropFilter(f.Conditions)) |
23 | case filterRemoveFields: | 24 | case filterRemoveFields: |
24 | filters = append(filters, RemoveFieldFilter(f.Fields)) | 25 | filters = append(filters, RemoveFieldFilter(f.Fields)) |
26 | + case filterTransfer: | ||
27 | + filters = append(filters, TransferFilter(f.Field, f.Target)) | ||
25 | } | 28 | } |
26 | } | 29 | } |
27 | 30 |
stash/filter/removefieldfilter_test.go
0 → 100644
1 | +package filter | ||
2 | + | ||
3 | +import ( | ||
4 | + "testing" | ||
5 | + | ||
6 | + "github.com/stretchr/testify/assert" | ||
7 | +) | ||
8 | + | ||
9 | +func TestRemoveFieldFilter(t *testing.T) { | ||
10 | + tests := []struct { | ||
11 | + name string | ||
12 | + input map[string]interface{} | ||
13 | + fields []string | ||
14 | + expect map[string]interface{} | ||
15 | + }{ | ||
16 | + { | ||
17 | + name: "remove field", | ||
18 | + input: map[string]interface{}{ | ||
19 | + "a": "aa", | ||
20 | + "b": `{"c":"cc"}`, | ||
21 | + }, | ||
22 | + fields: []string{"b"}, | ||
23 | + expect: map[string]interface{}{ | ||
24 | + "a": "aa", | ||
25 | + }, | ||
26 | + }, | ||
27 | + { | ||
28 | + name: "remove field", | ||
29 | + input: map[string]interface{}{ | ||
30 | + "a": "aa", | ||
31 | + "b": `{"c":"cc"}`, | ||
32 | + }, | ||
33 | + fields: []string{"c"}, | ||
34 | + expect: map[string]interface{}{ | ||
35 | + "a": "aa", | ||
36 | + "b": `{"c":"cc"}`, | ||
37 | + }, | ||
38 | + }, | ||
39 | + } | ||
40 | + | ||
41 | + for _, test := range tests { | ||
42 | + t.Run(test.name, func(t *testing.T) { | ||
43 | + actual := RemoveFieldFilter(test.fields)(test.input) | ||
44 | + assert.EqualValues(t, test.expect, actual) | ||
45 | + }) | ||
46 | + } | ||
47 | +} |
stash/filter/transferfilter.go
0 → 100644
1 | +package filter | ||
2 | + | ||
3 | +import ( | ||
4 | + jsoniter "github.com/json-iterator/go" | ||
5 | +) | ||
6 | + | ||
7 | +func TransferFilter(field, target string) FilterFunc { | ||
8 | + return func(m map[string]interface{}) map[string]interface{} { | ||
9 | + val, ok := m[field] | ||
10 | + if !ok { | ||
11 | + return m | ||
12 | + } | ||
13 | + | ||
14 | + s, ok := val.(string) | ||
15 | + if !ok { | ||
16 | + return m | ||
17 | + } | ||
18 | + | ||
19 | + var nm map[string]interface{} | ||
20 | + if err := jsoniter.Unmarshal([]byte(s), &nm); err != nil { | ||
21 | + return m | ||
22 | + } | ||
23 | + | ||
24 | + delete(m, field) | ||
25 | + if len(target) > 0 { | ||
26 | + m[target] = nm | ||
27 | + } else { | ||
28 | + for k, v := range nm { | ||
29 | + m[k] = v | ||
30 | + } | ||
31 | + } | ||
32 | + | ||
33 | + return m | ||
34 | + } | ||
35 | +} |
stash/filter/transferfilter_test.go
0 → 100644
1 | +package filter | ||
2 | + | ||
3 | +import ( | ||
4 | + "testing" | ||
5 | + | ||
6 | + "github.com/stretchr/testify/assert" | ||
7 | +) | ||
8 | + | ||
9 | +func TestTransferFilter(t *testing.T) { | ||
10 | + tests := []struct { | ||
11 | + name string | ||
12 | + input map[string]interface{} | ||
13 | + field string | ||
14 | + target string | ||
15 | + expect map[string]interface{} | ||
16 | + }{ | ||
17 | + { | ||
18 | + name: "with target", | ||
19 | + input: map[string]interface{}{ | ||
20 | + "a": "aa", | ||
21 | + "b": `{"c":"cc"}`, | ||
22 | + }, | ||
23 | + field: "b", | ||
24 | + target: "data", | ||
25 | + expect: map[string]interface{}{ | ||
26 | + "a": "aa", | ||
27 | + "data": map[string]interface{}{ | ||
28 | + "c": "cc", | ||
29 | + }, | ||
30 | + }, | ||
31 | + }, | ||
32 | + { | ||
33 | + name: "without target", | ||
34 | + input: map[string]interface{}{ | ||
35 | + "a": "aa", | ||
36 | + "b": `{"c":"cc"}`, | ||
37 | + }, | ||
38 | + field: "b", | ||
39 | + expect: map[string]interface{}{ | ||
40 | + "a": "aa", | ||
41 | + "c": "cc", | ||
42 | + }, | ||
43 | + }, | ||
44 | + { | ||
45 | + name: "without field", | ||
46 | + input: map[string]interface{}{ | ||
47 | + "a": "aa", | ||
48 | + "b": `{"c":"cc"}`, | ||
49 | + }, | ||
50 | + field: "c", | ||
51 | + expect: map[string]interface{}{ | ||
52 | + "a": "aa", | ||
53 | + "b": `{"c":"cc"}`, | ||
54 | + }, | ||
55 | + }, | ||
56 | + { | ||
57 | + name: "with not json", | ||
58 | + input: map[string]interface{}{ | ||
59 | + "a": "aa", | ||
60 | + "b": `{"c":"cc"`, | ||
61 | + }, | ||
62 | + field: "b", | ||
63 | + expect: map[string]interface{}{ | ||
64 | + "a": "aa", | ||
65 | + "b": `{"c":"cc"`, | ||
66 | + }, | ||
67 | + }, | ||
68 | + { | ||
69 | + name: "with not string", | ||
70 | + input: map[string]interface{}{ | ||
71 | + "a": "aa", | ||
72 | + "b": map[string]interface{}{"c": "cc"}, | ||
73 | + }, | ||
74 | + field: "b", | ||
75 | + expect: map[string]interface{}{ | ||
76 | + "a": "aa", | ||
77 | + "b": map[string]interface{}{"c": "cc"}, | ||
78 | + }, | ||
79 | + }, | ||
80 | + } | ||
81 | + | ||
82 | + for _, test := range tests { | ||
83 | + t.Run(test.name, func(t *testing.T) { | ||
84 | + actual := TransferFilter(test.field, test.target)(test.input) | ||
85 | + assert.EqualValues(t, test.expect, actual) | ||
86 | + }) | ||
87 | + } | ||
88 | +} |
-
请 注册 或 登录 后发表评论