fluent-plugin-json-lookup 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ddf77b69fc683ba857cc1f189d8b39abf3971f9f
4
+ data.tar.gz: 99808744272c71e1021d715fb498b7b642865787
5
+ SHA512:
6
+ metadata.gz: 6e77efe375a623c907f4027f36620f4ba15a8a8535385aeb868ec5c9286daf9740c8b7ce5253fb5b1eecc080d618769c0253d893a78fb4364f937b1d914c2225
7
+ data.tar.gz: 3e85a8d7377904e1b6220cef6766149b1d42fecd694f2596bf8d7a22f2ec678358d2e560b5f967c00a7d1b96d3cf9766a33dce5c194728ef3cca11bccb14da9f
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ # Package
2
+ pkg/
3
+
4
+ *.gem
5
+
6
+ *.swp
7
+ .idea/
data/.rubocop.yml ADDED
@@ -0,0 +1,17 @@
1
+ Metrics/LineLength:
2
+ Max: 120
3
+ Documentation:
4
+ Enabled: false
5
+
6
+ # Configuration parameters: CountComments.
7
+ Metrics/ClassLength:
8
+ Max: 131
9
+
10
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
11
+ # URISchemes: http, https
12
+ Metrics/LineLength:
13
+ Max: 182
14
+
15
+ # Configuration parameters: CountComments.
16
+ Metrics/MethodLength:
17
+ Max: 29
data/.travis.yml ADDED
@@ -0,0 +1,23 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 2.2
5
+ - 2.3
6
+ - 2.4
7
+ - ruby-head
8
+
9
+ gemfile:
10
+ - Gemfile
11
+ - Gemfile.v0.12
12
+
13
+ matrix:
14
+ allow_failures:
15
+ - rvm: ruby-head
16
+
17
+ before_install:
18
+ - gem update bundler
19
+ - gem install rubocop
20
+
21
+ script:
22
+ - rubocop
23
+ - bundle exec rake test
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify gem's dependencies in fluent-plugin-json-lookup.gemspec
4
+
5
+ gemspec
data/Gemfile.v0.12 ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify gem's dependencies in fluent-plugin-json-lookup.gemspec
4
+ gem 'fluentd', '~> 0.12.0'
5
+
6
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Skuid, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # fluent-plugin-json-lookup
2
+
3
+ Fluentd filter plugin for looking up json objects from messages.
4
+
5
+ ## Installation
6
+
7
+ Use RubyGems:
8
+
9
+ gem install fluent-plugin-json-lookup
10
+
11
+ ## Configuration
12
+
13
+ ### Use of the `json_lookup` filter.
14
+
15
+ ```
16
+ <filter pattern>
17
+ @type json_lookup
18
+ lookup_key kubernetes_container_name
19
+ json_key kubernetes_annotations_fluentd_org/keys
20
+ remove_json_key true
21
+ </filter>
22
+ ```
23
+
24
+ If following record is passed:
25
+
26
+ ```json
27
+ {
28
+ "kubernetes_container_name" : "nginx",
29
+ "kubernetes_annotations_fluentd_org/keys" : "{\"nginx\": {\"es_type\": \"nginx\", \"es_index\": \"fluentd-nginx-\"}, \"webapp\": {\"es_type\": \"application\", \"es_index\": \"fluentd-app-\"}}"
30
+ }
31
+ ```
32
+
33
+ then the emitted record would be:
34
+
35
+ ```json
36
+ {
37
+ "kubernetes_container_name": "nginx",
38
+ "es_type": "nginx",
39
+ "es_index": "fluentd-nginx-"
40
+ }
41
+ ```
42
+
43
+ ### Alternate use of the `json_lookup` filter.
44
+
45
+ ```
46
+ <filter pattern>
47
+ @type json_lookup
48
+ lookup_key nginx
49
+ json_key kubernetes_annotations_fluentd_org/keys
50
+ use_lookup_key_value false
51
+ remove_json_key false
52
+ </filter>
53
+ ```
54
+
55
+ If following record is passed:
56
+
57
+ ```json
58
+ {
59
+ "kubernetes_container_name" : "arbitrary",
60
+ "kubernetes_annotations_fluentd_org/keys" : "{\"nginx\": {\"es_type\": \"nginx\", \"es_index\": \"fluentd-nginx-\"}}"
61
+ }
62
+ ```
63
+
64
+ then the emitted record would be:
65
+
66
+ ```json
67
+ {
68
+ "kubernetes_container_name" : "arbitrary",
69
+ "kubernetes_annotations_fluentd_org/keys" : "{\"nginx\": {\"es_type\": \"nginx\", \"es_index\": \"fluentd-nginx-\"}}",
70
+ "es_type": "nginx",
71
+ "es_index": "fluentd-nginx-"
72
+ }
73
+ ```
74
+
75
+ If the value of `lookup_key` is not present, not a JSON object, or is malformed
76
+ JSON, the message will pass through unaltered (unless `remove_json_key` is set
77
+ to true).
78
+
79
+ ## `json_key`
80
+
81
+ The `json_key` specifies which log value to parse as json and perform a lookup
82
+ in.
83
+
84
+ ## `lookup_key`
85
+
86
+ The lookup key is used to specify the key within the deserialized `json_key`'s
87
+ value.
88
+
89
+ ## `use_lookup_key_value`
90
+
91
+ When `use_lookup_key_value` is set to true, the value of `lookup_key` is used,
92
+ rather then the configuration key's name. Defaults to `true`.
93
+
94
+ ## `remove_json_key`
95
+
96
+ When set to `true`, remove's the `json_key` from the message. Defaults to
97
+ `false`.
98
+
99
+ ## License
100
+
101
+ MIT (See [License](/LICENSE))
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'bundler'
2
+ require 'bundler/gem_tasks'
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new('test') do |test|
7
+ test.libs << 'lib' << 'test'
8
+ test.test_files = FileList['test/test_*.rb']
9
+ test.verbose = true
10
+ end
11
+
12
+ task 'default' => ['build']
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = 'fluent-plugin-json-lookup'
6
+ gem.description = 'Filter plugin for looking up a json object out of a record'
7
+ gem.homepage = 'https://github.com/skuid/fluent-plugin-json-lookup'
8
+ gem.summary = gem.description
9
+ gem.version = File.read('VERSION').strip
10
+ gem.authors = ['Micah Hausler']
11
+ gem.email = 'micah@skuid.com'
12
+ gem.has_rdoc = false
13
+ gem.license = 'MIT'
14
+ gem.files = `git ls-files`.split("\n")
15
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
17
+ gem.require_paths = ['lib']
18
+
19
+ gem.add_dependency 'fluentd', ['>= 0.10.58', '< 2']
20
+ gem.add_runtime_dependency 'yajl-ruby', '~> 1.0'
21
+ gem.add_development_dependency 'rake', '>= 0.9.2'
22
+ gem.add_development_dependency('test-unit', ['~> 3.1.4'])
23
+ end
@@ -0,0 +1,85 @@
1
+ require 'fluent/filter'
2
+ require 'yajl'
3
+
4
+ module Fluent
5
+ if defined?(Filter)
6
+ class JsonLookupFilter < Filter
7
+ Fluent::Plugin.register_filter('json_lookup', self)
8
+
9
+ config_param :lookup_key,
10
+ :string,
11
+ default: nil,
12
+ desc: <<-DESC
13
+ The `lookup_key` is used in looking up the contents of the `json_key`.
14
+ DESC
15
+
16
+ config_param :use_lookup_key_value,
17
+ :bool,
18
+ default: true,
19
+ desc: <<-DESC
20
+ When `use_lookup_key_value` is set to `true`, the plugin performs the lookup
21
+ using `lookup_key`'s value, rather than a hard-coded value.
22
+ DESC
23
+
24
+ config_param :json_key,
25
+ :string,
26
+ default: nil,
27
+ desc: 'The `json_key`` is a key that contains a string of json.'
28
+
29
+ config_param :remove_json_key,
30
+ :bool,
31
+ default: false,
32
+ desc: 'Remove the `json_key` from each record. Defaults to false.'
33
+
34
+ BUILTIN_CONFIGURATIONS = %w(
35
+ type @type log_level @log_level id @id lookup_key json_key
36
+ use_lookup_key_value remove_json_key
37
+ ).freeze
38
+
39
+ def configure(conf)
40
+ super
41
+
42
+ conf.each_pair do |k, v|
43
+ unless BUILTIN_CONFIGURATIONS.include?(k)
44
+ conf.key(k)
45
+ log.warn "Extra key provided! Ignoring '#{k} #{v}'"
46
+ end
47
+ end
48
+
49
+ # GC.start
50
+ end
51
+
52
+ def deserialize_and_lookup(content, lookup)
53
+ values = {}
54
+ begin
55
+ deserialized = Yajl.load(content)
56
+ if deserialized.is_a?(Hash) && deserialized.key?(lookup) && deserialized[lookup].is_a?(Hash)
57
+ values = deserialized[lookup]
58
+ end
59
+ rescue Yajl::ParseError
60
+ log.error "Error in plugin json_lookup, error parsing json_key's value #{content}'"
61
+ end
62
+ values
63
+ end
64
+
65
+ def filter_stream(_tag, es)
66
+ new_es = MultiEventStream.new
67
+ es.each do |time, record|
68
+ values = {}
69
+ if record.key?(@json_key)
70
+ lookup = @use_lookup_key_value ? record[@lookup_key] : @lookup_key
71
+ if record[@json_key][0] == '{'
72
+ values = deserialize_and_lookup(record[@json_key], lookup)
73
+ end
74
+ end
75
+ record.merge!(values)
76
+
77
+ record.delete(@json_key) if @remove_json_key && record.key?(@json_key)
78
+
79
+ new_es.add(time, record)
80
+ end
81
+ new_es
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,156 @@
1
+ require 'fluent/test'
2
+ require 'fluent/plugin/filter_json_lookup'
3
+ require 'test/unit'
4
+
5
+ exit unless defined?(Fluent::Filter)
6
+
7
+ class JsonLookupFilterTest < Test::Unit::TestCase
8
+ def setup
9
+ Fluent::Test.setup
10
+ @tag = 'test.tag'
11
+ end
12
+
13
+ CONFIG = '
14
+ @type json_lookup
15
+ lookup_key kubernetes_container_name
16
+ json_key kubernetes_annotations_fluentd_org/keys
17
+ remove_json_key true
18
+ '.freeze
19
+
20
+ def create_driver(conf = CONFIG)
21
+ Fluent::Test::FilterTestDriver.new(Fluent::JsonLookupFilter, @tag).configure(conf, true)
22
+ end
23
+
24
+ def test_lookup_exists
25
+ d = create_driver
26
+
27
+ d.run do
28
+ d.emit(
29
+ 'kubernetes_container_name' => 'nginx',
30
+ 'kubernetes_annotations_fluentd_org/keys' => '{"nginx": {"es_type": "nginx", "es_index": "fluentd-nginx-"}, "webapp": {"es_type": "application", "es_index": "fluentd-app-"}}'
31
+ )
32
+ d.emit(
33
+ 'kubernetes_container_name' => 'webapp',
34
+ 'kubernetes_annotations_fluentd_org/keys' => '{"nginx": {"es_type": "nginx", "es_index": "fluentd-nginx-"}, "webapp": {"es_type": "application", "es_index": "fluentd-app-"}}'
35
+ )
36
+ end
37
+
38
+ assert_equal [
39
+ { 'kubernetes_container_name' => 'nginx', 'es_type' => 'nginx', 'es_index' => 'fluentd-nginx-' },
40
+ { 'kubernetes_container_name' => 'webapp', 'es_type' => 'application', 'es_index' => 'fluentd-app-' }
41
+ ], d.filtered_as_array.map(&:last)
42
+ end
43
+
44
+ def test_lookup_exists_keep_key
45
+ d = create_driver '
46
+ @type json_lookup
47
+ lookup_key kubernetes_container_name
48
+ json_key kubernetes_annotations_fluentd_org/keys
49
+ '
50
+
51
+ d.run do
52
+ d.emit(
53
+ 'kubernetes_container_name' => 'nginx',
54
+ 'kubernetes_annotations_fluentd_org/keys' => '{"nginx": {"t": "nginx", "i": "fluentd-nginx-"}, "webapp": {"t": "application", "i": "fluentd-app-"}}'
55
+ )
56
+ d.emit(
57
+ 'kubernetes_container_name' => 'webapp',
58
+ 'kubernetes_annotations_fluentd_org/keys' => '{"nginx": {"t": "nginx", "i": "fluentd-nginx-"}, "webapp": {"t": "application", "i": "fluentd-app-"}}'
59
+ )
60
+ end
61
+
62
+ assert_equal [
63
+ {
64
+ 'i' => 'fluentd-nginx-',
65
+ 'kubernetes_container_name' => 'nginx',
66
+ 'kubernetes_annotations_fluentd_org/keys' => '{"nginx": {"t": "nginx", "i": "fluentd-nginx-"}, "webapp": {"t": "application", "i": "fluentd-app-"}}',
67
+ 't' => 'nginx'
68
+ },
69
+ {
70
+ 'i' => 'fluentd-app-',
71
+ 'kubernetes_container_name' => 'webapp',
72
+ 'kubernetes_annotations_fluentd_org/keys' => '{"nginx": {"t": "nginx", "i": "fluentd-nginx-"}, "webapp": {"t": "application", "i": "fluentd-app-"}}',
73
+ 't' => 'application'
74
+ }
75
+ ], d.filtered_as_array.map(&:last)
76
+ end
77
+
78
+ def test_lookup_exists_hard_code
79
+ d = create_driver '
80
+ @type json_lookup
81
+ lookup_key hardcoded
82
+ json_key kubernetes_annotations_fluentd_org/keys
83
+ use_lookup_key_value false
84
+ remove_json_key true
85
+ '
86
+
87
+ d.run do
88
+ d.emit(
89
+ 'kubernetes_container_name' => 'nginx',
90
+ 'kubernetes_annotations_fluentd_org/keys' => '{"hardcoded": {"t": "hardcoded", "i": "fluentd-hardcoded-"}, "webapp": {"t": "application", "i": "fluentd-app-"}}'
91
+ )
92
+ d.emit(
93
+ 'kubernetes_container_name' => 'webapp',
94
+ 'kubernetes_annotations_fluentd_org/keys' => '{"nginx": {"t": "nginx", "i": "fluentd-nginx-"}, "webapp": {"t": "application", "i": "fluentd-app-"}}'
95
+ )
96
+ end
97
+
98
+ assert_equal [
99
+ {
100
+ 'i' => 'fluentd-hardcoded-',
101
+ 'kubernetes_container_name' => 'nginx',
102
+ 't' => 'hardcoded'
103
+ },
104
+ {
105
+ 'kubernetes_container_name' => 'webapp'
106
+ }
107
+ ], d.filtered_as_array.map(&:last)
108
+ end
109
+
110
+ def test_lookup_absent
111
+ d = create_driver
112
+
113
+ d.run do
114
+ d.emit(
115
+ 'kubernetes_container_name' => 'nginx',
116
+ 'kubernetes_annotations_fluentd_org/keys' => '{"webapp": {"t": "application", "i": "fluentd-app-"}}'
117
+ )
118
+ d.emit(
119
+ 'kubernetes_container_name' => 'webapp',
120
+ 'kubernetes_annotations_fluentd_org/keys' => '{"nginx": {"t": "nginx", "i": "fluentd-nginx-"}}'
121
+ )
122
+ d.emit(
123
+ 'other_key' => 'value',
124
+ 'kubernetes_annotations_fluentd_org/keys' => '{"nginx": {"t": "nginx", "i": "fluentd-nginx-"}}'
125
+ )
126
+ d.emit('kubernetes_container_name' => 'webapp')
127
+ end
128
+
129
+ assert_equal [
130
+ { 'kubernetes_container_name' => 'nginx' },
131
+ { 'kubernetes_container_name' => 'webapp' },
132
+ { 'other_key' => 'value' },
133
+ { 'kubernetes_container_name' => 'webapp' }
134
+ ], d.filtered_as_array.map(&:last)
135
+ end
136
+
137
+ def test_lookup_malformed
138
+ d = create_driver
139
+
140
+ d.run do
141
+ d.emit(
142
+ 'kubernetes_container_name' => 'nginx',
143
+ 'kubernetes_annotations_fluentd_org/keys' => '{{"webapp": {"t": "application", "i": "fluentd-app-"}}'
144
+ )
145
+ d.emit(
146
+ 'kubernetes_container_name' => 'nginx',
147
+ 'kubernetes_annotations_fluentd_org/keys' => '{"nginx": ["t", "nginx", "i", "fluentd-nginx-"]}'
148
+ )
149
+ end
150
+
151
+ assert_equal [
152
+ { 'kubernetes_container_name' => 'nginx' },
153
+ { 'kubernetes_container_name' => 'nginx' }
154
+ ], d.filtered_as_array.map(&:last)
155
+ end
156
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-json-lookup
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Micah Hausler
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-02-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fluentd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.10.58
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.10.58
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2'
33
+ - !ruby/object:Gem::Dependency
34
+ name: yajl-ruby
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 0.9.2
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 0.9.2
61
+ - !ruby/object:Gem::Dependency
62
+ name: test-unit
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 3.1.4
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 3.1.4
75
+ description: Filter plugin for looking up a json object out of a record
76
+ email: micah@skuid.com
77
+ executables: []
78
+ extensions: []
79
+ extra_rdoc_files: []
80
+ files:
81
+ - ".gitignore"
82
+ - ".rubocop.yml"
83
+ - ".travis.yml"
84
+ - Gemfile
85
+ - Gemfile.v0.12
86
+ - LICENSE
87
+ - README.md
88
+ - Rakefile
89
+ - VERSION
90
+ - fluent-plugin-json-lookup.gemspec
91
+ - lib/fluent/plugin/filter_json_lookup.rb
92
+ - test/test_filter_json_lookup.rb
93
+ homepage: https://github.com/skuid/fluent-plugin-json-lookup
94
+ licenses:
95
+ - MIT
96
+ metadata: {}
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ requirements: []
112
+ rubyforge_project:
113
+ rubygems_version: 2.6.8
114
+ signing_key:
115
+ specification_version: 4
116
+ summary: Filter plugin for looking up a json object out of a record
117
+ test_files:
118
+ - test/test_filter_json_lookup.rb