fluent-plugin-nested-hash-filter 0.0.3 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +27 -9
- data/fluent-plugin-nested-hash-filter.gemspec +1 -1
- data/lib/fluent/plugin/filter_nested_hash.rb +3 -1
- data/lib/fluent/plugin/nested_hash_filter/nested_object.rb +20 -17
- data/lib/fluent/plugin/out_nested_hash.rb +2 -1
- data/test/fluent/plugin/filter_nested_hash_test.rb +22 -3
- data/test/fluent/plugin/nested_hash_filter/nested_object_test.rb +64 -42
- data/test/fluent/plugin/out_nested_hash_test.rb +26 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8086358c385e65ba72177e5d387af2dbc59d9327
|
4
|
+
data.tar.gz: 00dd2d49d61abda94163664ebcc5147dc4a8439c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bf597fb8200cb91327b6e061b9749ad88f17a8af45037ff7360eef64d80acbcf3c7fd7dd65c1f5f2f8814d269e37eeb3e83f5ef5f27e9b633b4a88bd412d676
|
7
|
+
data.tar.gz: 9e850518c9d05ea283c89d473269301b0923dc275dc60a74f671841aa1c859f545509bbe9a42c059a16628e8a68e991359869edadec2f5dcb81bafd055a65ff4
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# fluent-plugin-nested-hash-filter
|
2
2
|
|
3
|
-
[](https://travis-ci.org/sugilog/fluent-plugin-nested-hash-filter)
|
4
|
+
[](http://badge.fury.io/rb/fluent-plugin-nested-hash-filter)
|
4
5
|
|
5
6
|
|
6
7
|
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/fluent/plugin/filter_nested_hash`.
|
@@ -9,23 +10,40 @@ TODO: Delete this and the text above, and describe your gem
|
|
9
10
|
|
10
11
|
## Installation
|
11
12
|
|
12
|
-
|
13
|
+
install to your td-agent env
|
13
14
|
|
14
15
|
```ruby
|
15
|
-
gem
|
16
|
+
td-agent-gem install fluent-plugin-nested-hash-filter
|
16
17
|
```
|
17
18
|
|
18
|
-
|
19
|
+
## Usage
|
19
20
|
|
20
|
-
|
21
|
+
Add config to your `td-agent.conf`
|
21
22
|
|
22
|
-
|
23
|
+
**Filter**: just only convert passed hash into flatten key-value pair.
|
23
24
|
|
24
|
-
|
25
|
+
```
|
26
|
+
<filter {MATCH_PATTERN}>
|
27
|
+
type nested_hash
|
28
|
+
connector .
|
29
|
+
</filter>
|
30
|
+
```
|
25
31
|
|
26
|
-
|
32
|
+
**Output**: convert passed hash into flatten key-value pair, and rename tag.
|
33
|
+
|
34
|
+
```
|
35
|
+
<match {MATCH_PATTERN}>
|
36
|
+
type nested_hash
|
37
|
+
tag_prefix {PREFIX}
|
38
|
+
connector .
|
39
|
+
</match>
|
40
|
+
```
|
41
|
+
|
42
|
+
`tag_prefix` is required parameter to add prefix to matched tag name.
|
43
|
+
|
44
|
+
`connector` is optional parameter to connect nested-keys. (default: `.`) not for tag prefix connection.
|
27
45
|
|
28
|
-
|
46
|
+
- ex: matched tag is `access.log` and `tag_prefix` is `converted.`, then log will be passed with tag name `converted.access.log`.
|
29
47
|
|
30
48
|
## Development
|
31
49
|
|
@@ -4,6 +4,8 @@ module Fluent
|
|
4
4
|
class FilterNestedHash < Filter
|
5
5
|
Plugin.register_filter("nested_hash", self)
|
6
6
|
|
7
|
+
config_param :connector, :string, :default => nil
|
8
|
+
|
7
9
|
def configure conf
|
8
10
|
super
|
9
11
|
end
|
@@ -17,7 +19,7 @@ module Fluent
|
|
17
19
|
end
|
18
20
|
|
19
21
|
def filter tag, time, record
|
20
|
-
Fluent::NestedHashFilter::NestedObject.convert record
|
22
|
+
Fluent::NestedHashFilter::NestedObject.convert record, connector: @connector
|
21
23
|
end
|
22
24
|
end
|
23
25
|
end
|
@@ -1,21 +1,24 @@
|
|
1
1
|
module Fluent
|
2
2
|
module NestedHashFilter
|
3
|
-
|
4
|
-
|
3
|
+
class NestedObject
|
4
|
+
DEFAULT_CONNECTOR = "."
|
5
5
|
|
6
|
-
def self.
|
7
|
-
|
8
|
-
|
6
|
+
def self.convert object, options = {}
|
7
|
+
converter = new options
|
8
|
+
converter.select object
|
9
|
+
converter.output
|
9
10
|
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
select object
|
12
|
+
attr_accessor :output, :output_keys
|
13
|
+
attr_reader :connector
|
14
14
|
|
15
|
-
|
15
|
+
def initialize options = {}
|
16
|
+
@output = {}
|
17
|
+
@output_keys = []
|
18
|
+
@connector = options[:connector] || DEFAULT_CONNECTOR
|
16
19
|
end
|
17
20
|
|
18
|
-
def
|
21
|
+
def select object
|
19
22
|
case object
|
20
23
|
when Hash
|
21
24
|
convert_hash object
|
@@ -26,25 +29,25 @@ module Fluent
|
|
26
29
|
end
|
27
30
|
end
|
28
31
|
|
29
|
-
def
|
32
|
+
def add_key key
|
30
33
|
@output_keys.push key
|
31
34
|
end
|
32
35
|
|
33
|
-
def
|
36
|
+
def pop_key
|
34
37
|
@output_keys.pop
|
35
38
|
end
|
36
39
|
|
37
|
-
def
|
38
|
-
@output_keys.join
|
40
|
+
def current_key
|
41
|
+
@output_keys.join connector
|
39
42
|
end
|
40
43
|
|
41
|
-
def
|
44
|
+
def update value
|
42
45
|
unless current_key.empty?
|
43
46
|
@output.update current_key => value
|
44
47
|
end
|
45
48
|
end
|
46
49
|
|
47
|
-
def
|
50
|
+
def convert_hash hash
|
48
51
|
if hash.keys.empty?
|
49
52
|
update nil
|
50
53
|
end
|
@@ -56,7 +59,7 @@ module Fluent
|
|
56
59
|
end
|
57
60
|
end
|
58
61
|
|
59
|
-
def
|
62
|
+
def convert_array array
|
60
63
|
if array.empty?
|
61
64
|
update nil
|
62
65
|
end
|
@@ -5,6 +5,7 @@ module Fluent
|
|
5
5
|
Plugin.register_output("nested_hash", self)
|
6
6
|
|
7
7
|
config_param :tag_prefix, :string
|
8
|
+
config_param :connector, :string, :default => nil
|
8
9
|
|
9
10
|
def configure conf
|
10
11
|
super
|
@@ -20,7 +21,7 @@ module Fluent
|
|
20
21
|
|
21
22
|
def emit tag, es, chain
|
22
23
|
es.each do |time, record|
|
23
|
-
record = Fluent::NestedHashFilter::NestedObject.convert record
|
24
|
+
record = Fluent::NestedHashFilter::NestedObject.convert record, connector: @connector
|
24
25
|
Fluent::Engine.emit @tag_prefix + tag, time, record
|
25
26
|
end
|
26
27
|
|
@@ -33,9 +33,13 @@ class FilterNestedHashTest < Test::Unit::TestCase
|
|
33
33
|
|
34
34
|
sub_test_case "configure" do
|
35
35
|
test "check default" do
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
driver = create_driver "default"
|
37
|
+
assert_equal nil, driver.instance.connector
|
38
|
+
end
|
39
|
+
|
40
|
+
test "with connector" do
|
41
|
+
driver = create_driver "connector -"
|
42
|
+
assert_equal "-", driver.instance.connector
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
@@ -55,6 +59,21 @@ class FilterNestedHashTest < Test::Unit::TestCase
|
|
55
59
|
assert_equal expect_message, result[:message]
|
56
60
|
end
|
57
61
|
|
62
|
+
test "with connector" do
|
63
|
+
driver = emit "connector -", [
|
64
|
+
{a: 1, b: {c: 2, d: {e: 3, f:4}, g: [10, 20, 30]}, h: [], i: {}},
|
65
|
+
{a: {b: {c: 1, d: {e: 2, f:3}, g: [10, 20, 30]}, h: [], i: {}}}
|
66
|
+
]
|
67
|
+
|
68
|
+
expect_message = {"a" => 1, "b-c" => 2, "b-d-e" => 3, "b-d-f" => 4, "b-g-0" => 10, "b-g-1" => 20, "b-g-2" => 30, "h" => nil, "i" => nil}
|
69
|
+
result = filtered driver, 0
|
70
|
+
assert_equal expect_message, result[:message]
|
71
|
+
|
72
|
+
expect_message = {"a-b-c" => 1, "a-b-d-e" => 2, "a-b-d-f" => 3, "a-b-g-0" => 10, "a-b-g-1" => 20, "a-b-g-2" => 30, "a-h" => nil, "a-i" => nil}
|
73
|
+
result = filtered driver, 1
|
74
|
+
assert_equal expect_message, result[:message]
|
75
|
+
end
|
76
|
+
|
58
77
|
test "with invalid record" do
|
59
78
|
driver = emit "", ["message", {hoge: 1, fuga: {"test0" => 2, "test1" => 3}}]
|
60
79
|
|
@@ -3,12 +3,12 @@ require "fluent/plugin/nested_hash_filter/nested_object"
|
|
3
3
|
|
4
4
|
class NestedObjectTest < Test::Unit::TestCase
|
5
5
|
setup do
|
6
|
-
klass.
|
6
|
+
@instance = klass.new
|
7
7
|
end
|
8
8
|
|
9
9
|
sub_test_case "constants" do
|
10
|
-
test "::
|
11
|
-
assert_equal ".", klass::
|
10
|
+
test "::DEFAULT_CONNECTOR" do
|
11
|
+
assert_equal ".", klass::DEFAULT_CONNECTOR
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -35,11 +35,26 @@ class NestedObjectTest < Test::Unit::TestCase
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
sub_test_case "initialize" do
|
39
|
+
test "without options" do
|
40
|
+
assert_equal Hash.new, @instance.output
|
41
|
+
assert_equal Array.new, @instance.output_keys
|
42
|
+
assert_equal ".", @instance.connector
|
43
|
+
end
|
44
|
+
|
45
|
+
test "with options" do
|
46
|
+
@instance = klass.new connector: "-"
|
47
|
+
assert_equal Hash.new, @instance.output
|
48
|
+
assert_equal Array.new, @instance.output_keys
|
49
|
+
assert_equal "-", @instance.connector
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
38
53
|
sub_test_case "select" do
|
39
54
|
test "object is hash" do
|
40
|
-
|
55
|
+
@instance.add_key "test"
|
41
56
|
object = {hoge: 1, fuga: "2"}
|
42
|
-
|
57
|
+
@instance.select object
|
43
58
|
|
44
59
|
assert_equal Set["test.hoge", "test.fuga"], output.keys.to_set
|
45
60
|
assert_equal 1, output["test.hoge"]
|
@@ -47,9 +62,9 @@ class NestedObjectTest < Test::Unit::TestCase
|
|
47
62
|
end
|
48
63
|
|
49
64
|
test "object is array" do
|
50
|
-
|
65
|
+
@instance.add_key "test"
|
51
66
|
object = [:hoge, "fuga"]
|
52
|
-
|
67
|
+
@instance.select object
|
53
68
|
|
54
69
|
assert_equal Set["test.0", "test.1"], output.keys.to_set
|
55
70
|
assert_equal :hoge, output["test.0"]
|
@@ -57,27 +72,27 @@ class NestedObjectTest < Test::Unit::TestCase
|
|
57
72
|
end
|
58
73
|
|
59
74
|
test "object is string" do
|
60
|
-
|
75
|
+
@instance.add_key "test"
|
61
76
|
object = "hoge"
|
62
|
-
|
77
|
+
@instance.select object
|
63
78
|
|
64
79
|
assert_equal Set["test"], output.keys.to_set
|
65
80
|
assert_equal "hoge", output["test"]
|
66
81
|
end
|
67
82
|
|
68
83
|
test "object is number" do
|
69
|
-
|
84
|
+
@instance.add_key "test"
|
70
85
|
object = 12345
|
71
|
-
|
86
|
+
@instance.select object
|
72
87
|
|
73
88
|
assert_equal Set["test"], output.keys.to_set
|
74
89
|
assert_equal 12345, output["test"]
|
75
90
|
end
|
76
91
|
|
77
92
|
test "object is nil" do
|
78
|
-
|
93
|
+
@instance.add_key "test"
|
79
94
|
object = nil
|
80
|
-
|
95
|
+
@instance.select object
|
81
96
|
|
82
97
|
assert_equal Set["test"], output.keys.to_set
|
83
98
|
assert_equal nil, output["test"]
|
@@ -86,64 +101,71 @@ class NestedObjectTest < Test::Unit::TestCase
|
|
86
101
|
|
87
102
|
sub_test_case "add_key" do
|
88
103
|
test "add" do
|
89
|
-
|
104
|
+
@instance.add_key "test"
|
90
105
|
assert_equal ["test"], output_keys
|
91
|
-
|
106
|
+
@instance.add_key 1
|
92
107
|
assert_equal ["test", 1], output_keys
|
93
|
-
|
108
|
+
@instance.add_key "hoge"
|
94
109
|
assert_equal ["test", 1, "hoge"], output_keys
|
95
110
|
end
|
96
111
|
end
|
97
112
|
|
98
113
|
sub_test_case "pop_key" do
|
99
114
|
test "remove key by pop" do
|
100
|
-
|
101
|
-
|
102
|
-
|
115
|
+
@instance.add_key "test"
|
116
|
+
@instance.add_key 1
|
117
|
+
@instance.add_key "hoge"
|
103
118
|
assert_equal ["test", 1, "hoge"], output_keys
|
104
119
|
|
105
|
-
|
120
|
+
@instance.pop_key
|
106
121
|
assert_equal ["test", 1], output_keys
|
107
122
|
|
108
|
-
|
123
|
+
@instance.pop_key
|
109
124
|
assert_equal ["test"], output_keys
|
110
125
|
|
111
|
-
|
126
|
+
@instance.pop_key
|
112
127
|
assert_equal [], output_keys
|
113
128
|
end
|
114
129
|
|
115
130
|
test "without output_keys" do
|
116
131
|
assert_nothing_raised do
|
117
|
-
|
132
|
+
@instance.pop_key
|
118
133
|
end
|
119
134
|
end
|
120
135
|
end
|
121
136
|
|
122
137
|
sub_test_case "current_key" do
|
123
138
|
test "with output_keys" do
|
124
|
-
|
125
|
-
|
126
|
-
assert_equal "test.1",
|
139
|
+
@instance.add_key "test"
|
140
|
+
@instance.add_key 1
|
141
|
+
assert_equal "test.1", @instance.current_key
|
127
142
|
end
|
128
143
|
|
129
144
|
test "without output_keys" do
|
130
|
-
assert_equal "",
|
145
|
+
assert_equal "", @instance.current_key
|
146
|
+
end
|
147
|
+
|
148
|
+
test "for not default connector" do
|
149
|
+
@instance = klass.new connector: "-"
|
150
|
+
@instance.add_key "test"
|
151
|
+
@instance.add_key 1
|
152
|
+
assert_equal "test-1", @instance.current_key
|
131
153
|
end
|
132
154
|
end
|
133
155
|
|
134
156
|
sub_test_case "update" do
|
135
157
|
test "with current_key" do
|
136
|
-
|
137
|
-
|
138
|
-
|
158
|
+
@instance.add_key "test"
|
159
|
+
@instance.add_key 1
|
160
|
+
@instance.update 12345
|
139
161
|
|
140
162
|
assert_equal ["test.1"], output.keys
|
141
163
|
assert_equal 12345, output["test.1"]
|
142
164
|
end
|
143
165
|
|
144
166
|
test "without current_key" do
|
145
|
-
assert
|
146
|
-
|
167
|
+
assert @instance.current_key.empty?
|
168
|
+
@instance.update 12345
|
147
169
|
|
148
170
|
assert_equal [], output.keys
|
149
171
|
end
|
@@ -151,17 +173,17 @@ class NestedObjectTest < Test::Unit::TestCase
|
|
151
173
|
|
152
174
|
sub_test_case "convert_hash" do
|
153
175
|
test "hash is blank" do
|
154
|
-
|
176
|
+
@instance.add_key "test"
|
155
177
|
object = {}
|
156
|
-
|
178
|
+
@instance.convert_hash object
|
157
179
|
assert_equal ["test"], output.keys
|
158
180
|
assert_equal nil, output["test"]
|
159
181
|
end
|
160
182
|
|
161
183
|
test "convert" do
|
162
|
-
|
184
|
+
@instance.add_key "test"
|
163
185
|
object = {"a" => "hoge", "b" => 1, "c" => {"hoge" => "fuga"}, "d" => [10, 20], "e" => nil}
|
164
|
-
|
186
|
+
@instance.convert_hash object
|
165
187
|
assert_equal ["test.a", "test.b", "test.c.hoge", "test.d.0", "test.d.1", "test.e"], output.keys
|
166
188
|
assert_equal "hoge", output["test.a"]
|
167
189
|
assert_equal 1, output["test.b"]
|
@@ -174,17 +196,17 @@ class NestedObjectTest < Test::Unit::TestCase
|
|
174
196
|
|
175
197
|
sub_test_case "convert_array" do
|
176
198
|
test "array is empty" do
|
177
|
-
|
199
|
+
@instance.add_key "test"
|
178
200
|
object = []
|
179
|
-
|
201
|
+
@instance.convert_array object
|
180
202
|
assert_equal ["test"], output.keys
|
181
203
|
assert_equal nil, output["test"]
|
182
204
|
end
|
183
205
|
|
184
206
|
test "convert" do
|
185
|
-
|
207
|
+
@instance.add_key "test"
|
186
208
|
object = ["hoge", 1, {"hoge" => "fuga"}, [10, 20], nil]
|
187
|
-
|
209
|
+
@instance.convert_array object
|
188
210
|
assert_equal ["test.0", "test.1", "test.2.hoge", "test.3.0", "test.3.1", "test.4"], output.keys
|
189
211
|
assert_equal "hoge", output["test.0"]
|
190
212
|
assert_equal 1, output["test.1"]
|
@@ -196,11 +218,11 @@ class NestedObjectTest < Test::Unit::TestCase
|
|
196
218
|
end
|
197
219
|
|
198
220
|
def output
|
199
|
-
|
221
|
+
@instance.output
|
200
222
|
end
|
201
223
|
|
202
224
|
def output_keys
|
203
|
-
|
225
|
+
@instance.output_keys
|
204
226
|
end
|
205
227
|
|
206
228
|
def klass
|
@@ -33,13 +33,20 @@ class OutNestedHashTest < Test::Unit::TestCase
|
|
33
33
|
|
34
34
|
sub_test_case "configure" do
|
35
35
|
test "check_default" do
|
36
|
-
create_driver "tag_prefix default"
|
36
|
+
driver = create_driver "tag_prefix default"
|
37
|
+
assert_equal "default", driver.instance.tag_prefix
|
38
|
+
assert_equal nil, driver.instance.connector
|
37
39
|
end
|
38
40
|
|
39
|
-
test "tag_prefix" do
|
41
|
+
test "with tag_prefix" do
|
40
42
|
driver = create_driver "tag_prefix filtered."
|
41
43
|
assert_equal "filtered.", driver.instance.tag_prefix
|
42
44
|
end
|
45
|
+
|
46
|
+
test "with connector" do
|
47
|
+
driver = create_driver "tag_prefix default\nconnector -"
|
48
|
+
assert_equal "-", driver.instance.connector
|
49
|
+
end
|
43
50
|
end
|
44
51
|
|
45
52
|
sub_test_case "emit" do
|
@@ -60,6 +67,23 @@ class OutNestedHashTest < Test::Unit::TestCase
|
|
60
67
|
assert_equal expect_message, result[:message]
|
61
68
|
end
|
62
69
|
|
70
|
+
test "with connector" do
|
71
|
+
driver = emit "tag_prefix filtered.\nconnector -", "test", [
|
72
|
+
{a: 1, b: {c: 2, d: {e: 3, f:4}, g: [10, 20, 30]}, h: [], i: {}},
|
73
|
+
{a: {b: {c: 1, d: {e: 2, f:3}, g: [10, 20, 30]}, h: [], i: {}}}
|
74
|
+
]
|
75
|
+
|
76
|
+
expect_message = {"a" => 1, "b-c" => 2, "b-d-e" => 3, "b-d-f" => 4, "b-g-0" => 10, "b-g-1" => 20, "b-g-2" => 30, "h" => nil, "i" => nil}
|
77
|
+
result = emitted driver, 0
|
78
|
+
assert_equal "filtered.test", result[:tag]
|
79
|
+
assert_equal expect_message, result[:message]
|
80
|
+
|
81
|
+
expect_message = {"a-b-c" => 1, "a-b-d-e" => 2, "a-b-d-f" => 3, "a-b-g-0" => 10, "a-b-g-1" => 20, "a-b-g-2" => 30, "a-h" => nil, "a-i" => nil}
|
82
|
+
result = emitted driver, 1
|
83
|
+
assert_equal "filtered.test", result[:tag]
|
84
|
+
assert_equal expect_message, result[:message]
|
85
|
+
end
|
86
|
+
|
63
87
|
test "with invalid record" do
|
64
88
|
driver = emit "tag_prefix filtered.", "test", ["message", {hoge: 1, fuga: {"test0" => 2, "test1" => 3}}]
|
65
89
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-nested-hash-filter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- sugilog
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|