logstash-filter-list2fields 0.1.0 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9832818142f818906d8759e43dbc910d12f5e37f
4
- data.tar.gz: 63aa2f896df825be60ffe05a4e2a6ed04c95c66d
3
+ metadata.gz: 484bb95370a4baf2895cda0b34310b2c698192cc
4
+ data.tar.gz: ba91bfb3dca14654a53c35b8c45648f52e750cd9
5
5
  SHA512:
6
- metadata.gz: 7d4417e96eec33160430d59e4eb4b54dc7b9aaa3cef9ef6aa59983410538ba59814ca54760c9a26d144898753fc1ceb7b9f29c4d61c34519fe408a4b66eee4ce
7
- data.tar.gz: 17171e3a3477456cde677cc483979983b074ebfd8bdeab622d7889f310b0b7e175a8c131e9f0f34842dc521e59265054a78b45b3caed0ef2740ed8c85d863442
6
+ metadata.gz: b2ebdeefc163d42dcdd9411603a84a863a636378e8c213acd1a8c585ee4f872376bd7317608ab57b73e3333ae61773ef8f8e8d05e21e508814304b14ae12fe64
7
+ data.tar.gz: 3bb28663abced9e74f534d57112a940f2af02c121f2f9797e4f895a6f6d480ab17e86e50ce25a0622e75492de6503f476480000cc630025820c588aceaf3058e
data/README.md CHANGED
@@ -1,15 +1,25 @@
1
- # Logstash Plugin
1
+ # Logstash list2fields Filter Plugin
2
2
 
3
3
 
4
4
  This is a plugin for [Logstash](https://github.com/elastic/logstash).
5
5
 
6
6
  It is fully free and fully open source. The license is Apache 2.0, meaning you are pretty much free to use it however you want in whatever way.
7
7
 
8
+ ## Installation
9
+
10
+ You can download the plugin from [rubygems](https://rubygems.org/gems/logstash-filter-list2fields) and install it from your logstash home directory like so:
11
+
12
+ bin/plugin install logstash-filter-list2fields-$VERSION.gem
13
+
8
14
  ## Documentation
9
15
 
10
- This filter rearranges key-value-pairs from the following structure
16
+ This filter rearranges key-value-pairs from the following structures
17
+
18
+ example 1: "awesome_list" => [ { "animal" => "horse"} , {"food" => "bacon"} ]
19
+
20
+ or
11
21
 
12
- "awesome_list" => [ { "key" => "animal", "value" => "horse"} , {"key" => "food", "value" => "bacon"} ]
22
+ example 2: "awesome_list" => [ { "key" => "animal", "value" => "horse"} , {"key" => "food", "value" => "bacon"} ]
13
23
 
14
24
  into separate logstash event fields:
15
25
 
@@ -19,11 +29,11 @@ into separate logstash event fields:
19
29
  ## Configuration
20
30
 
21
31
  * source : name of the field which contains the list of key value pairs (required). In the example above, this would be "awesome_list".
22
- * key : name of the key for the key field in the list of key value pairs. Headache? Example: If this is your incoming data:
23
- "awesome_list" => [ { "name" => "animal", "content" => "horse"} , {"name" => "food", "content" => "bacon"} ]
24
- then the key would be "name". Optional, defaults to "key".
25
- * value : name of the key for the value field in the list of key value pairs. In the above example, this would be "content". Optional, defaults to "value".
26
- * prefix : string to prepend to the new fields that will be added to the logstash event. Optional, defaults to empty.
32
+ * prefix : string to prepend to the new fields that will be added to the logstash event. Optional.
33
+ * key : optional for example 1, required for example #2: name of the key for the key field in the list of key value pairs. Headache? Example: If this is your incoming data:
34
+ example 3: "awesome_list" => [ { "name" => "animal", "content" => "horse"} , {"name" => "food", "content" => "bacon"} ]
35
+ then the key would be "name".
36
+ * value : optional for example 1, required for example #2: name of the key for the value field in the list of key value pairs. In example 3, this would be "content".
27
37
 
28
38
 
29
39
  ## Contributing
@@ -2,7 +2,6 @@
2
2
  require "logstash/filters/base"
3
3
  require "logstash/namespace"
4
4
 
5
- # TODO docu
6
5
  class LogStash::Filters::List2fields < LogStash::Filters::Base
7
6
 
8
7
  config_name "list2fields"
@@ -10,37 +9,69 @@ class LogStash::Filters::List2fields < LogStash::Filters::Base
10
9
  # The name of the field which contains the list of key value pairs
11
10
  config :source, :validate => :string
12
11
 
13
- # The name of the field which contains the key inside a list element
14
- config :key, :validate => :string, :default => "key"
12
+ # The name of the field which contains the key inside a list element. If this is set then "value" needs to be set also.
13
+ config :key, :validate => :string, :default => ""
15
14
 
16
- # The name of the field which contains the value inside a list element
17
- config :value, :validate => :string, :default => "value"
15
+ # The name of the field which contains the value inside a list element. If this is set then "key" needs to be set also.
16
+ config :value, :validate => :string, :default => ""
18
17
 
19
18
  # Prefix for the elements that will be added.
20
19
  config :prefix, :validate => :string, :default => ""
21
20
 
21
+ # Remove source field after transformation
22
+ config :remove_source, :validate => :boolean, :default => true
23
+
24
+ # if you want to have debug information for this plugin only and you dont want to set the whole logstash to debug.
25
+ config :debug, :validate => :boolean, :default => false
26
+
22
27
  public
23
28
  def register
24
-
29
+ @access_by_name = !@key.empty? && !@value.empty?
25
30
  end # def register
26
31
 
27
32
  public
28
33
  def filter(event)
29
- input = event[@source]
30
- if !input.nil? && (input.is_a? Enumerable)
34
+ input = event.get(@source)
35
+ if !input.nil? && (input.is_a? Enumerable)
31
36
  input.each do |entry|
32
37
  begin
33
- if entry.is_a?(::Hash)
34
- new_key = @prefix.to_s + entry[@key].to_s
35
- event[new_key] = entry[@value]
36
- else
37
- new_key = @prefix.to_s + entry.instance_variable_get("@" + @key)
38
- event[new_key] = entry.instance_variable_get("@" + @value)
39
- end # if is hash
38
+ @logger.warn(entry.to_a.to_s)
39
+ if @access_by_name
40
+
41
+ if entry.is_a?(::Hash) # see spec file: test case 1
42
+ if !entry[@key].nil?
43
+ new_key = @prefix.to_s + entry[@key].to_s
44
+ value = entry[@value]
45
+ @logger.info("Adding new field " + new_key + " with value " + value)
46
+ else # might be a symbol then and we need to convert our keys to :keys
47
+ new_key = @prefix.to_s + entry[@key.to_sym].to_s
48
+ value = entry[@value.to_sym]
49
+ @logger.info("Adding new field " + new_key + ", value " + value)
50
+ end
51
+ event.set(new_key, value)
52
+ else # it's an object of some unknown class.
53
+ @logger.warn("Data structure not supported. " + entry.inspect.to_s)
54
+ end # if is hash
55
+
56
+ else # access by position, no key / value names provided
57
+
58
+ if entry.is_a?(::Hash) # see spec file: test case 2
59
+ new_key = @prefix.to_s + entry.keys[0].to_s
60
+ event.set(new_key, entry.values[0])
61
+
62
+ else # it's an object of some unknown class.
63
+ @logger.warn("Data structure not supported. " + entry.inspect.to_s)
64
+ end # if is hash
65
+
66
+ end # acess type
40
67
  rescue
41
68
  @logger.debug("Could not find key " + @key + " in incoming data, please check your config. ")
42
69
  end
43
- end # do
70
+ end # do
71
+ if @remove_source
72
+ event.remove(@source)
73
+ end
74
+
44
75
  end # if input.nil?
45
76
  end # def filter
46
77
  end # class LogStash::Filters::List2fields
@@ -1,13 +1,12 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-filter-list2fields'
4
- s.version = '0.1.0'
4
+ s.version = '0.1.3'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "$summary"
7
7
  s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
8
- s.authors = ["Elastic"]
9
- s.email = 'info@elastic.co'
10
- s.homepage = "http://www.elastic.co/guide/en/logstash/current/index.html"
8
+ s.authors = ["Inga Feick"]
9
+ s.email = 'inga.feick@trivago.com'
11
10
  s.require_paths = ["lib"]
12
11
 
13
12
  # Files
@@ -20,7 +19,7 @@ Gem::Specification.new do |s|
20
19
  s.metadata = { "logstash_plugin" => "true", "logstash_group" => "filter" }
21
20
 
22
21
  # Gem dependencies
23
- s.add_runtime_dependency "logstash-core", ">= 2.0.0.beta2", "< 3.0.0"
22
+ s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
24
23
 
25
24
  s.add_development_dependency 'logstash-devutils'
26
25
  end
@@ -4,64 +4,132 @@ require "logstash/filters/list2fields"
4
4
 
5
5
  describe LogStash::Filters::List2fields do
6
6
 
7
- let(:plugin) { LogStash::Filters::List2fields.new("source" => "message") }
8
-
9
- before do
10
- plugin.register
11
- end
12
-
13
- context "when a prefix is set" do
14
-
15
- let(:plugin_prefix) { LogStash::Filters::List2fields.new("source" => "message", "prefix" => "l2f_") } # TODO there's got to be a more beautiful way to do this
16
- let(:event) { LogStash::Event.new("cheese" => "chili", "message" => [{"key"=>"foo","value"=>"bar"},{"key"=>"cheese","value"=>"bacon"}]) }
7
+ # Test cases: 1 [ { "key" => "animal", "value" => "horse"} , {"key" => "food", "value" => "bacon"} ] list of hashes with splitted fields for key and value
8
+ # Test cases: 2 [ { "animal" => "horse"} , {"food" => "bacon"} ] list of hashes with k => v structure
9
+
10
+ context "without prefix" do
11
+
12
+ let(:plugin) { LogStash::Filters::List2fields.new("source" => "message") }
13
+
17
14
  before do
18
- plugin_prefix.filter(event)
15
+ plugin.register
19
16
  end
17
+
18
+ context "when the source field is empty" do
19
+
20
+ let(:event) { LogStash::Event.new() }
21
+ it "should not throw an exception" do
22
+ expect {
23
+ plugin.filter(event)
24
+ }.not_to raise_error
25
+ end # it
26
+ end # context
27
+
28
+ context "when the source field is not iterable" do
29
+
30
+ let(:event) { LogStash::Event.new("message" => "i_am_not_iterable" ) }
31
+ it "should not throw an exception" do
32
+ expect {
33
+ plugin.filter(event)
34
+ }.not_to raise_error
35
+ end # it
36
+ end # context
37
+
38
+ context "when remove_source is set to true" do
39
+
40
+ let(:event) { LogStash::Event.new("message" => [{"key"=>"foo","value"=>"bar"}]) }
41
+ before do
42
+ plugin.filter(event)
43
+ end
20
44
 
21
- it "should have new fields with the prefix in the key" do
22
- expect(event["l2f_foo"]).to eq("bar")
23
- expect(event["l2f_cheese"]).to eq("bacon")
24
- end # it
45
+ it "should remove the input field" do
46
+ expect(event.get("message")).to be_nil
47
+ end # it
48
+ end # context
25
49
 
26
- it "should not overwrite existing fields" do
27
- expect(event["cheese"]).to eq("chili")
28
- end # it
29
- end # context
50
+ context "when remove_source is set to false" do
51
+
52
+ let(:event) { LogStash::Event.new("message" => [{"key"=>"foo","value"=>"bar"}]) }
53
+ let(:plugin) { LogStash::Filters::List2fields.new("source" => "message", "remove_source" => false) }
54
+
55
+ before do
56
+ plugin.register
57
+ plugin.filter(event)
58
+ end
30
59
 
60
+ it "should not remove the input field" do
61
+ expect(event.get("message")).not_to be_empty
62
+ end # it
63
+ end # context
31
64
 
32
- context "when the source field is empty" do
33
65
 
34
- let(:event) { LogStash::Event.new() }
35
- it "should not throw an exception" do
36
- expect {
66
+ context "operates on a list of hashes with splitted key and value entries (using names) (testcase 1)" do
67
+ let(:event) { LogStash::Event.new("cheese" => "chili", "message" => [{"key"=>"foo","value"=>"bar"},{"key"=>"cheese","value"=>"gorgonzola"}]) }
68
+ let(:plugin) { LogStash::Filters::List2fields.new("source" => "message", "key" => "key", "value" => "value") }
69
+ before do
70
+ plugin.register
37
71
  plugin.filter(event)
38
- }.not_to raise_error
39
- end # it
40
- end # context
72
+ end
41
73
 
42
- context "when the source field is not iterable" do
74
+ it "should have new fields" do
75
+ expect(event.get("foo")).to eq("bar")
76
+ expect(event.get("cheese")).to eq("gorgonzola")
77
+ end # it
78
+ end # context
43
79
 
44
- let(:event) { LogStash::Event.new("message" => "i_am_not_iterable" ) }
45
- it "should not throw an exception" do
46
- expect {
80
+
81
+ context "operates on a list of hashes with key and value in one tuple (testcase 2)." do
82
+ let(:event) { LogStash::Event.new("cheese" => "chili", "message" => [{"foo"=>"bar"},{"cheese"=>"gorgonzola"}]) }
83
+ before do
84
+ plugin.register
47
85
  plugin.filter(event)
48
- }.not_to raise_error
49
- end # it
50
- end # context
86
+ end
51
87
 
88
+ it "should have new fields" do
89
+ expect(event.get("foo")).to eq("bar")
90
+ expect(event.get("cheese")).to eq("gorgonzola")
91
+ end # it
92
+ end # context
52
93
 
53
- context "when there is a nested list" do
94
+ end # context no prefix set
54
95
 
55
- let(:event) { LogStash::Event.new("message" => [{"key"=>"foo","value"=>"bar"},{"key"=>"cheese","value"=>"bacon"}]) }
56
- before do
57
- plugin.filter(event)
58
- end
96
+ context "with prefix " do
97
+
98
+ context "operates on a list of hashes with splitted key and value entries (using names) (testcase 1)" do
99
+ let(:plugin) { LogStash::Filters::List2fields.new("source" => "message", "prefix" => "l2f_", "key" => "key", "value" => "value") }
100
+ let(:event) { LogStash::Event.new("cheese" => "chili", "message" => [{"key"=>"foo","value"=>"bar"},{"key"=>"cheese","value"=>"gorgonzola"}]) }
101
+ before do
102
+ plugin.register
103
+ plugin.filter(event)
104
+ end
105
+
106
+ it "should have new fields with the prefix in the key" do
107
+ expect(event.get("l2f_foo")).to eq("bar")
108
+ expect(event.get("l2f_cheese")).to eq("gorgonzola")
109
+ end # it
110
+
111
+ it "should not overwrite existing fields" do
112
+ expect(event.get("cheese")).to eq("chili")
113
+ end # it
114
+ end # context
115
+
116
+
117
+
118
+ context "operates on a list of hashes with key and value in one tuple (testcase 2)." do
119
+ let(:plugin) { LogStash::Filters::List2fields.new("source" => "message", "prefix" => "l2f_") }
120
+ let(:event) { LogStash::Event.new("cheese" => "chili", "message" => [{"foo"=>"bar"},{"cheese"=>"gorgonzola"}]) }
121
+ before do
122
+ plugin.register
123
+ plugin.filter(event)
124
+ end
125
+
126
+ it "should have new fields with the prefix in the key" do
127
+ expect(event.get("l2f_foo")).to eq("bar")
128
+ expect(event.get("l2f_cheese")).to eq("gorgonzola")
129
+ end # it
130
+ end # context
59
131
 
60
- it "should have new fields" do
61
- expect(event["foo"]).to eq("bar")
62
- expect(event["cheese"]).to eq("bacon")
63
- end # it
132
+ end # context prefix set
64
133
 
65
- end # context
66
134
  end # describe
67
135
 
metadata CHANGED
@@ -1,51 +1,51 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-filter-list2fields
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
- - Elastic
7
+ - Inga Feick
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-25 00:00:00.000000000 Z
11
+ date: 2016-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: logstash-core
15
- version_requirements: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - '>='
18
- - !ruby/object:Gem::Version
19
- version: 2.0.0.beta2
20
- - - <
21
- - !ruby/object:Gem::Version
22
- version: 3.0.0
23
14
  requirement: !ruby/object:Gem::Requirement
24
15
  requirements:
25
16
  - - '>='
26
17
  - !ruby/object:Gem::Version
27
- version: 2.0.0.beta2
28
- - - <
18
+ version: '1.60'
19
+ - - <=
29
20
  - !ruby/object:Gem::Version
30
- version: 3.0.0
21
+ version: '2.99'
22
+ name: logstash-core-plugin-api
31
23
  prerelease: false
32
24
  type: :runtime
33
- - !ruby/object:Gem::Dependency
34
- name: logstash-devutils
35
25
  version_requirements: !ruby/object:Gem::Requirement
36
26
  requirements:
37
27
  - - '>='
38
28
  - !ruby/object:Gem::Version
39
- version: '0'
29
+ version: '1.60'
30
+ - - <=
31
+ - !ruby/object:Gem::Version
32
+ version: '2.99'
33
+ - !ruby/object:Gem::Dependency
40
34
  requirement: !ruby/object:Gem::Requirement
41
35
  requirements:
42
36
  - - '>='
43
37
  - !ruby/object:Gem::Version
44
38
  version: '0'
39
+ name: logstash-devutils
45
40
  prerelease: false
46
41
  type: :development
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
47
  description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
48
- email: info@elastic.co
48
+ email: inga.feick@trivago.com
49
49
  executables: []
50
50
  extensions: []
51
51
  extra_rdoc_files: []
@@ -61,7 +61,7 @@ files:
61
61
  - spec/filters/list2filters_spec.rb
62
62
  - vendor/GeoIPASNum-2014-02-12.dat
63
63
  - vendor/GeoLiteCity-2013-01-18.dat
64
- homepage: http://www.elastic.co/guide/en/logstash/current/index.html
64
+ homepage:
65
65
  licenses:
66
66
  - Apache License (2.0)
67
67
  metadata: