fluent-plugin-nested-hash-filter 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8086358c385e65ba72177e5d387af2dbc59d9327
4
- data.tar.gz: 00dd2d49d61abda94163664ebcc5147dc4a8439c
3
+ metadata.gz: c092a833fd6982c036035b9292b70b08a25c0ae8
4
+ data.tar.gz: 0c9291bb5874ed145888843d59e1e455cda1676c
5
5
  SHA512:
6
- metadata.gz: 9bf597fb8200cb91327b6e061b9749ad88f17a8af45037ff7360eef64d80acbcf3c7fd7dd65c1f5f2f8814d269e37eeb3e83f5ef5f27e9b633b4a88bd412d676
7
- data.tar.gz: 9e850518c9d05ea283c89d473269301b0923dc275dc60a74f671841aa1c859f545509bbe9a42c059a16628e8a68e991359869edadec2f5dcb81bafd055a65ff4
6
+ metadata.gz: 1a94d9e631ce5a6a85470ac71bf48dcda611b1303f262a620b0277565b106086b364346e956ad051b388426f9212b93477af096a65690e388bf1a9cf60be68d2
7
+ data.tar.gz: 0842ec1d2f922a108576476d1499ab4317cc07039e34ab7e67b17044a52397aaee7b2b5c1e73cf3b8b956fb82225bcc6922cbc970dba3cef7d5e7cd09f887879
data/README.md CHANGED
@@ -26,6 +26,7 @@ Add config to your `td-agent.conf`
26
26
  <filter {MATCH_PATTERN}>
27
27
  type nested_hash
28
28
  connector .
29
+ acts_as_json ["key1", "key2-1.key2-2"]
29
30
  </filter>
30
31
  ```
31
32
 
@@ -36,6 +37,7 @@ Add config to your `td-agent.conf`
36
37
  type nested_hash
37
38
  tag_prefix {PREFIX}
38
39
  connector .
40
+ acts_as_json ["key1", "key2-1.key2-2"]
39
41
  </match>
40
42
  ```
41
43
 
@@ -43,6 +45,8 @@ Add config to your `td-agent.conf`
43
45
 
44
46
  `connector` is optional parameter to connect nested-keys. (default: `.`) not for tag prefix connection.
45
47
 
48
+ `acts_as_json` is optional parameter to convert string to hash in json format. (default: `[]` empty)
49
+
46
50
  - ex: matched tag is `access.log` and `tag_prefix` is `converted.`, then log will be passed with tag name `converted.access.log`.
47
51
 
48
52
  ## Development
@@ -51,6 +55,13 @@ After checking out the repo, run `bundle install` to install dependencies.
51
55
 
52
56
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
53
57
 
58
+ ## Demo script
59
+
60
+ ```
61
+ bundle exec ruby script/demo_logger.rb
62
+ ```
63
+
64
+
54
65
  ## Contributing
55
66
 
56
67
  1. Fork it ( https://github.com/sugilog/fluent-plugin-nested-hash-filter/fork )
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "fluent-plugin-nested-hash-filter"
7
- spec.version = "0.1.0"
7
+ spec.version = "0.2.0"
8
8
  spec.authors = ["sugilog"]
9
9
  spec.email = ["sugilog@gmail.com"]
10
10
 
@@ -21,4 +21,5 @@ Gem::Specification.new do |spec|
21
21
  spec.add_development_dependency "test-unit"
22
22
  spec.add_development_dependency "guard"
23
23
  spec.add_development_dependency "guard-test"
24
+ spec.add_development_dependency "faker"
24
25
  end
@@ -5,6 +5,7 @@ module Fluent
5
5
  Plugin.register_filter("nested_hash", self)
6
6
 
7
7
  config_param :connector, :string, :default => nil
8
+ config_param :acts_as_json, :array, :default => []
8
9
 
9
10
  def configure conf
10
11
  super
@@ -19,7 +20,7 @@ module Fluent
19
20
  end
20
21
 
21
22
  def filter tag, time, record
22
- Fluent::NestedHashFilter::NestedObject.convert record, connector: @connector
23
+ Fluent::NestedHashFilter::NestedObject.convert record, connector: @connector, jsonify_keys: @acts_as_json
23
24
  end
24
25
  end
25
26
  end
@@ -1,3 +1,5 @@
1
+ require 'json'
2
+
1
3
  module Fluent
2
4
  module NestedHashFilter
3
5
  class NestedObject
@@ -9,13 +11,14 @@ module Fluent
9
11
  converter.output
10
12
  end
11
13
 
12
- attr_accessor :output, :output_keys
14
+ attr_accessor :output, :output_keys, :jsonify_keys
13
15
  attr_reader :connector
14
16
 
15
17
  def initialize options = {}
16
- @output = {}
17
- @output_keys = []
18
- @connector = options[:connector] || DEFAULT_CONNECTOR
18
+ @output = {}
19
+ @output_keys = []
20
+ @connector = options[:connector] || DEFAULT_CONNECTOR
21
+ @jsonify_keys = init_jsonify_keys options[:jsonify_keys]
19
22
  end
20
23
 
21
24
  def select object
@@ -41,10 +44,45 @@ module Fluent
41
44
  @output_keys.join connector
42
45
  end
43
46
 
47
+ def acts_as_json value
48
+ json = JSON.parse value
49
+ select json
50
+ rescue TypeError => error
51
+ err = JSON::ParserError.new error.message
52
+ err.set_backtrace err.backtrace
53
+ raise err
54
+ rescue JSON::ParserError => error
55
+ raise error
56
+ ensure
57
+ jsonified!
58
+ end
59
+
60
+ def jsonify_key?
61
+ !!@jsonify_keys[current_key]
62
+ end
63
+
64
+ def jsonified!
65
+ @jsonify_keys[current_key] = false
66
+ end
67
+
68
+ def init_jsonify_keys keys
69
+ keys = keys || []
70
+ values = [true] * keys.size
71
+ zipped = keys.zip values
72
+ Hash[ zipped ]
73
+ end
74
+
44
75
  def update value
45
- unless current_key.empty?
76
+ case
77
+ when current_key.empty?
78
+ return
79
+ when jsonify_key?
80
+ acts_as_json value
81
+ else
46
82
  @output.update current_key => value
47
83
  end
84
+ rescue JSON::ParserError
85
+ @output.update current_key => value
48
86
  end
49
87
 
50
88
  def convert_hash hash
@@ -6,6 +6,7 @@ module Fluent
6
6
 
7
7
  config_param :tag_prefix, :string
8
8
  config_param :connector, :string, :default => nil
9
+ config_param :acts_as_json, :array, :default => []
9
10
 
10
11
  def configure conf
11
12
  super
@@ -21,7 +22,7 @@ module Fluent
21
22
 
22
23
  def emit tag, es, chain
23
24
  es.each do |time, record|
24
- record = Fluent::NestedHashFilter::NestedObject.convert record, connector: @connector
25
+ record = Fluent::NestedHashFilter::NestedObject.convert record, connector: @connector, jsonify_keys: @acts_as_json
25
26
  Fluent::Engine.emit @tag_prefix + tag, time, record
26
27
  end
27
28
 
@@ -0,0 +1,72 @@
1
+ require "rubygems"
2
+ require "logger"
3
+ require "json"
4
+ require "faker"
5
+ require "uri"
6
+
7
+ FILE_PATH = "/tmp/fluent-plugin-nested-hash-filter.demo.log"
8
+ @count = 0
9
+
10
+ def main
11
+ loop do
12
+ object = generate
13
+ output object
14
+ sleep 0.1
15
+ @count += 1
16
+ end
17
+ end
18
+
19
+ def generate
20
+ case @count % 100
21
+ when 0..85
22
+ session_id = @count
23
+ when 86..95
24
+ session_id = ""
25
+ when 96..98
26
+ session_id = @count.to_s.rjust 10, "0"
27
+ else
28
+ session_id = Faker::Lorem.characters 20
29
+ end
30
+
31
+ case @count % 100
32
+ when 0..98
33
+ access = Time.now.to_s
34
+ number = Faker::Number.number 10
35
+ else
36
+ access = "undefined"
37
+ number = ""
38
+ end
39
+
40
+ uri = URI.parse Faker::Internet.url
41
+ expired = Time.now + ( 3 * 60 * 60 * 24 )
42
+ adsid = Faker::Number.number 8
43
+
44
+ {
45
+ session_id: session_id,
46
+ session: {
47
+ expired: expired,
48
+ ads: {
49
+ _id: adsid,
50
+ list: Faker::Lorem.words,
51
+ }
52
+ }.to_json,
53
+ count: number,
54
+ access: access,
55
+ uri: uri.path,
56
+ query: {
57
+ keyword: Faker::Lorem.words,
58
+ page: 0
59
+ },
60
+ response: Faker::Lorem.sentence,
61
+ email: Faker::Internet.safe_email
62
+ }
63
+ end
64
+
65
+ def output object
66
+ File.open FILE_PATH, "a" do |file|
67
+ line = object.to_json
68
+ file.puts line
69
+ end
70
+ end
71
+
72
+ main
@@ -35,11 +35,19 @@ class FilterNestedHashTest < Test::Unit::TestCase
35
35
  test "check default" do
36
36
  driver = create_driver "default"
37
37
  assert_equal nil, driver.instance.connector
38
+ assert_equal [], driver.instance.acts_as_json
38
39
  end
39
40
 
40
41
  test "with connector" do
41
42
  driver = create_driver "connector -"
42
43
  assert_equal "-", driver.instance.connector
44
+ assert_equal [], driver.instance.acts_as_json
45
+ end
46
+
47
+ test "with acts_as_json" do
48
+ driver = create_driver "acts_as_json [\"hoge.1\", \"fuga\"]"
49
+ assert_equal nil, driver.instance.connector
50
+ assert_equal ["hoge.1", "fuga"], driver.instance.acts_as_json
43
51
  end
44
52
  end
45
53
 
@@ -74,6 +82,16 @@ class FilterNestedHashTest < Test::Unit::TestCase
74
82
  assert_equal expect_message, result[:message]
75
83
  end
76
84
 
85
+ test "with acts_as_json" do
86
+ driver = emit "acts_as_json [\"a\",\"b.c\"]", [
87
+ {a: "[100, 200]", b: {c: '{"x": 1, "y": 2, "z": 3}', d: {e: 3, f:4}, g: [10, 20, 30]}, h: [], i: {}},
88
+ ]
89
+
90
+ expect_message = {"a.0" => 100, "a.1" => 200, "b.c.x" => 1, "b.c.y" => 2, "b.c.z" => 3, "b.d.e" => 3, "b.d.f" => 4, "b.g.0" => 10, "b.g.1" => 20, "b.g.2" => 30, "h" => nil, "i" => nil}
91
+ result = filtered driver, 0
92
+ assert_equal expect_message, result[:message]
93
+ end
94
+
77
95
  test "with invalid record" do
78
96
  driver = emit "", ["message", {hoge: 1, fuga: {"test0" => 2, "test1" => 3}}]
79
97
 
@@ -40,13 +40,25 @@ class NestedObjectTest < Test::Unit::TestCase
40
40
  assert_equal Hash.new, @instance.output
41
41
  assert_equal Array.new, @instance.output_keys
42
42
  assert_equal ".", @instance.connector
43
+ assert_equal Hash.new, @instance.jsonify_keys
43
44
  end
44
45
 
45
- test "with options" do
46
+ test "with connector option" do
46
47
  @instance = klass.new connector: "-"
47
48
  assert_equal Hash.new, @instance.output
48
49
  assert_equal Array.new, @instance.output_keys
49
50
  assert_equal "-", @instance.connector
51
+ assert_equal Hash.new, @instance.jsonify_keys
52
+ end
53
+
54
+ test "with jsonify_keys option" do
55
+ @instance = klass.new jsonify_keys: ["hoge.1", "fuga"]
56
+ assert_equal Hash.new, @instance.output
57
+ assert_equal Array.new, @instance.output_keys
58
+ assert_equal ".", @instance.connector
59
+ assert_equal ["fuga", "hoge.1"], @instance.jsonify_keys.keys.sort
60
+ assert @instance.jsonify_keys["hoge.1"]
61
+ assert @instance.jsonify_keys["fuga"]
50
62
  end
51
63
  end
52
64
 
@@ -153,6 +165,129 @@ class NestedObjectTest < Test::Unit::TestCase
153
165
  end
154
166
  end
155
167
 
168
+ sub_test_case "acts_as_json" do
169
+ test "with strinfied json" do
170
+ value = {"hoge" => [ 10, 20 ], "fuga" => Date.new(2015, 1, 23)}.to_json
171
+ assert_instance_of String, value
172
+ result = @instance.acts_as_json value
173
+ assert_equal Set["fuga", "hoge"], result.keys.to_set
174
+ assert_equal [10, 20], result["hoge"]
175
+ assert_equal Date.new(2015, 1, 23).to_s, result["fuga"]
176
+ end
177
+
178
+ test "with non json format string" do
179
+ value = "hoge: [10, 20], fuga: 'undefined'"
180
+ result = nil
181
+
182
+ assert_raise JSON::ParserError do
183
+ result = @instance.acts_as_json value
184
+ end
185
+
186
+ assert_nil result
187
+ end
188
+
189
+ test "with nil" do
190
+ value = nil
191
+ result = nil
192
+
193
+ assert_raise JSON::ParserError do
194
+ result = @instance.acts_as_json value
195
+ end
196
+
197
+ assert_nil result
198
+ end
199
+
200
+ test "with integer" do
201
+ value = 123
202
+ result = nil
203
+
204
+ assert_raise JSON::ParserError do
205
+ result = @instance.acts_as_json value
206
+ end
207
+
208
+ assert_nil result
209
+ end
210
+
211
+ test "with hash" do
212
+ value = {"hoge" => [ 10, 20 ], "fuga" => Date.new(2015, 1, 23)}
213
+ result = nil
214
+
215
+ assert_raise JSON::ParserError do
216
+ result = @instance.acts_as_json value
217
+ end
218
+
219
+ assert_nil result
220
+ end
221
+
222
+ test "with array" do
223
+ value = [ 10, 20 ]
224
+ result = nil
225
+
226
+ assert_raise JSON::ParserError do
227
+ result = @instance.acts_as_json value
228
+ end
229
+
230
+ assert_nil result
231
+ end
232
+ end
233
+
234
+ sub_test_case "jsonify_keys?" do
235
+ test "with no key" do
236
+ @instance.jsonify_keys = {}
237
+ @instance.output_keys = ["hoge", 0]
238
+ assert !@instance.jsonify_key?
239
+ end
240
+
241
+ test "with key" do
242
+ @instance.jsonify_keys = { "hoge.1" => true, "fuga" => false }
243
+
244
+ @instance.output_keys = ["hoge", 1]
245
+ assert @instance.jsonify_key?
246
+
247
+ @instance.output_keys = ["fuga"]
248
+ assert !@instance.jsonify_key?
249
+ end
250
+ end
251
+
252
+ sub_test_case "jsonified!" do
253
+ test "set false" do
254
+ @instance.jsonify_keys = { "hoge.1" => true, "fuga" => false }
255
+
256
+ @instance.output_keys = ["hoge", 1]
257
+ @instance.jsonified!
258
+ assert !@instance.jsonify_keys["hoge.1"]
259
+
260
+ @instance.output_keys = ["fuga"]
261
+ @instance.jsonified!
262
+ assert !@instance.jsonify_keys["fuga"]
263
+
264
+ @instance.output_keys = ["piyo"]
265
+ @instance.jsonified!
266
+ assert !@instance.jsonify_keys["piyo"]
267
+ end
268
+ end
269
+
270
+ sub_test_case "init_jsonify_keys" do
271
+ test "with array keys" do
272
+ jsonify_keys = @instance.init_jsonify_keys ["hoge.1", "fuga"]
273
+ assert_equal Set["fuga", "hoge.1"], jsonify_keys.keys.to_set
274
+ assert jsonify_keys["hoge.1"]
275
+ assert jsonify_keys["fuga"]
276
+ end
277
+
278
+ test "with empty keys" do
279
+ jsonify_keys = @instance.init_jsonify_keys []
280
+ assert jsonify_keys.keys.empty?
281
+ assert_equal Hash.new, jsonify_keys
282
+ end
283
+
284
+ test "with nil" do
285
+ jsonify_keys = @instance.init_jsonify_keys nil
286
+ assert jsonify_keys.keys.empty?
287
+ assert_equal Hash.new, jsonify_keys
288
+ end
289
+ end
290
+
156
291
  sub_test_case "update" do
157
292
  test "with current_key" do
158
293
  @instance.add_key "test"
@@ -169,6 +304,39 @@ class NestedObjectTest < Test::Unit::TestCase
169
304
 
170
305
  assert_equal [], output.keys
171
306
  end
307
+
308
+ test "with jsonify_keys" do
309
+ @instance.jsonify_keys = @instance.init_jsonify_keys ["hoge.1", "fuga"]
310
+ value = {"test" => [12345, 6789], "piyo" => nil}.to_json
311
+
312
+ @instance.add_key "hoge"
313
+ @instance.add_key 0
314
+ @instance.update value
315
+ assert_equal ["hoge.0"], output.keys
316
+ assert_equal value, output["hoge.0"]
317
+
318
+ @instance.pop_key
319
+ @instance.pop_key
320
+ @instance.add_key "hoge"
321
+ @instance.add_key 1
322
+ @instance.update value
323
+ assert_equal Set["hoge.0", "hoge.1.piyo", "hoge.1.test.0", "hoge.1.test.1"], output.keys.to_set
324
+ assert_equal value, output["hoge.0"]
325
+ assert_equal 12345, output["hoge.1.test.0"]
326
+ assert_equal 6789, output["hoge.1.test.1"]
327
+ assert_equal nil, output["hoge.1.piyo"]
328
+
329
+ @instance.pop_key
330
+ @instance.pop_key
331
+ @instance.add_key "fuga"
332
+ @instance.update 987654321
333
+ assert_equal Set["hoge.0", "hoge.1.piyo", "hoge.1.test.0", "hoge.1.test.1", "fuga"], output.keys.to_set
334
+ assert_equal value, output["hoge.0"]
335
+ assert_equal 12345, output["hoge.1.test.0"]
336
+ assert_equal 6789, output["hoge.1.test.1"]
337
+ assert_equal nil, output["hoge.1.piyo"]
338
+ assert_equal 987654321, output["fuga"]
339
+ end
172
340
  end
173
341
 
174
342
  sub_test_case "convert_hash" do
@@ -184,7 +352,7 @@ class NestedObjectTest < Test::Unit::TestCase
184
352
  @instance.add_key "test"
185
353
  object = {"a" => "hoge", "b" => 1, "c" => {"hoge" => "fuga"}, "d" => [10, 20], "e" => nil}
186
354
  @instance.convert_hash object
187
- assert_equal ["test.a", "test.b", "test.c.hoge", "test.d.0", "test.d.1", "test.e"], output.keys
355
+ assert_equal Set["test.a", "test.b", "test.c.hoge", "test.d.0", "test.d.1", "test.e"], output.keys.to_set
188
356
  assert_equal "hoge", output["test.a"]
189
357
  assert_equal 1, output["test.b"]
190
358
  assert_equal "fuga", output["test.c.hoge"]
@@ -207,7 +375,7 @@ class NestedObjectTest < Test::Unit::TestCase
207
375
  @instance.add_key "test"
208
376
  object = ["hoge", 1, {"hoge" => "fuga"}, [10, 20], nil]
209
377
  @instance.convert_array object
210
- assert_equal ["test.0", "test.1", "test.2.hoge", "test.3.0", "test.3.1", "test.4"], output.keys
378
+ assert_equal Set["test.0", "test.1", "test.2.hoge", "test.3.0", "test.3.1", "test.4"], output.keys.to_set
211
379
  assert_equal "hoge", output["test.0"]
212
380
  assert_equal 1, output["test.1"]
213
381
  assert_equal "fuga", output["test.2.hoge"]
@@ -36,16 +36,27 @@ class OutNestedHashTest < Test::Unit::TestCase
36
36
  driver = create_driver "tag_prefix default"
37
37
  assert_equal "default", driver.instance.tag_prefix
38
38
  assert_equal nil, driver.instance.connector
39
+ assert_equal [], driver.instance.acts_as_json
39
40
  end
40
41
 
41
42
  test "with tag_prefix" do
42
43
  driver = create_driver "tag_prefix filtered."
43
44
  assert_equal "filtered.", driver.instance.tag_prefix
45
+ assert_equal [], driver.instance.acts_as_json
44
46
  end
45
47
 
46
48
  test "with connector" do
47
49
  driver = create_driver "tag_prefix default\nconnector -"
50
+ assert_equal "default", driver.instance.tag_prefix
48
51
  assert_equal "-", driver.instance.connector
52
+ assert_equal [], driver.instance.acts_as_json
53
+ end
54
+
55
+ test "with acts_as_json" do
56
+ driver = create_driver "acts_as_json [\"hoge.1\", \"fuga\"]\ntag_prefix default"
57
+ assert_equal "default", driver.instance.tag_prefix
58
+ assert_equal nil, driver.instance.connector
59
+ assert_equal ["hoge.1", "fuga"], driver.instance.acts_as_json
49
60
  end
50
61
  end
51
62
 
@@ -84,6 +95,17 @@ class OutNestedHashTest < Test::Unit::TestCase
84
95
  assert_equal expect_message, result[:message]
85
96
  end
86
97
 
98
+ test "with acts_as_json" do
99
+ driver = emit "acts_as_json [\"a\",\"b.c\"]\ntag_prefix filtered.", "test", [
100
+ {a: "[100, 200]", b: {c: '{"x": 1, "y": 2, "z": 3}', d: {e: 3, f:4}, g: [10, 20, 30]}, h: [], i: {}},
101
+ ]
102
+
103
+ expect_message = {"a.0" => 100, "a.1" => 200, "b.c.x" => 1, "b.c.y" => 2, "b.c.z" => 3, "b.d.e" => 3, "b.d.f" => 4, "b.g.0" => 10, "b.g.1" => 20, "b.g.2" => 30, "h" => nil, "i" => nil}
104
+ result = emitted driver, 0
105
+ assert_equal "filtered.test", result[:tag]
106
+ assert_equal expect_message, result[:message]
107
+ end
108
+
87
109
  test "with invalid record" do
88
110
  driver = emit "tag_prefix filtered.", "test", ["message", {hoge: 1, fuga: {"test0" => 2, "test1" => 3}}]
89
111
 
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.1.0
4
+ version: 0.2.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-07-04 00:00:00.000000000 Z
11
+ date: 2015-07-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: faker
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  description: Fluent Plugin for converting nested hash into flatten key-value pair.
98
112
  email:
99
113
  - sugilog@gmail.com
@@ -111,6 +125,7 @@ files:
111
125
  - lib/fluent/plugin/filter_nested_hash.rb
112
126
  - lib/fluent/plugin/nested_hash_filter/nested_object.rb
113
127
  - lib/fluent/plugin/out_nested_hash.rb
128
+ - script/demo_logger.rb
114
129
  - test/fluent/plugin/filter_nested_hash_test.rb
115
130
  - test/fluent/plugin/nested_hash_filter/nested_object_test.rb
116
131
  - test/fluent/plugin/out_nested_hash_test.rb