logstash-codec-avro 3.2.4-java → 3.3.0-java

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
  SHA256:
3
- metadata.gz: 944e629ff565ac22e6ebec71ab3aadc1fa66c0419b00d5f474cbfa6e51f8adde
4
- data.tar.gz: d7bca5cd5bc59a91bbacc07e4a3fb05caf9a9e88e03bda3fab9994edaf2a4bc6
3
+ metadata.gz: fee9cf4a669e1ea2fffd5012bc923e829a474831236a87b2a658ae7cb524dd4a
4
+ data.tar.gz: 4a7c182a568787e1f2c7d1b3cb346cf1a9dba4b4cff08f095cb89790b1ec7c10
5
5
  SHA512:
6
- metadata.gz: e59d5692fdd014b990a83036f6f17766056bdf0649cb4c041a2a79319ebfe07bc5071957592e22a7ed50cedec31d50be75101524d0cb283cfe10de60640e91bb
7
- data.tar.gz: 43d4194f8ff16af1fb66c38822a6aa834af7c704233b29c364365f2ec2ae90870479fdbdbc1aed7b616ad07f4ff4c704abbb17a81cd652965f836e474b50c6f3
6
+ metadata.gz: a43c7ded1c5719b78c4826186168d4a414f0bcf0884286066987705c23db288a190ca085b5f4abbc274fb617b5bd29e3bb97587b276c495cc789ecf7a90a1956
7
+ data.tar.gz: 21412260698ff42f352f562333d9a574b5ca1fbcc8cf914c0f397386a6149a4df8dda234a0a2cdbd401b15a785436d9ec456115021ec1146e36b477423ab79b7
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 3.3.0
2
+ - Add ECS support. Add target option and event.original [#36](https://github.com/logstash-plugins/logstash-codec-avro/pull/36)
3
+
1
4
  ## 3.2.4
2
5
  - [DOC] Add clarifications on partial deserialization [#35](https://github.com/logstash-plugins/logstash-codec-avro/pull/35)
3
6
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Logstash Plugin
2
2
 
3
- [![Travis Build Status](https://travis-ci.org/logstash-plugins/logstash-codec-avro.svg)](https://travis-ci.org/logstash-plugins/logstash-codec-avro)
3
+ [![Travis Build Status](https://travis-ci.com/logstash-plugins/logstash-codec-avro.svg)](https://travis-ci.com/logstash-plugins/logstash-codec-avro)
4
4
 
5
5
  This is a plugin for [Logstash](https://github.com/elastic/logstash).
6
6
 
data/docs/index.asciidoc CHANGED
@@ -26,6 +26,11 @@ This plugin is used to serialize Logstash events as
26
26
  Avro datums, as well as deserializing Avro datums into
27
27
  Logstash events.
28
28
 
29
+ [id="plugins-{type}s-{plugin}-ecs_metadata"]
30
+ ==== Event Metadata and the Elastic Common Schema (ECS)
31
+
32
+ The plugin behaves the same regardless of ECS compatibility, except adding the original message to `[event][original]`.
33
+
29
34
  ==== Encoding
30
35
 
31
36
  This codec is for serializing individual Logstash events
@@ -76,12 +81,25 @@ output {
76
81
  [cols="<,<,<",options="header",]
77
82
  |=======================================================================
78
83
  |Setting |Input type|Required
84
+ | <<plugins-{type}s-{plugin}-ecs_compatibility>> | <<string,string>>|No
79
85
  | <<plugins-{type}s-{plugin}-schema_uri>> |<<string,string>>|Yes
80
86
  | <<plugins-{type}s-{plugin}-tag_on_failure>> |<<boolean,boolean>>|No
87
+ | <<plugins-{type}s-{plugin}-target>> |<<string,string>>|No
81
88
  |=======================================================================
82
89
 
83
90
  &nbsp;
84
91
 
92
+ [id="plugins-{type}s-{plugin}-ecs_compatibility"]
93
+ ===== `ecs_compatibility`
94
+
95
+ * Value type is <<string,string>>
96
+ * Supported values are:
97
+ ** `disabled`: Avro data added at root level
98
+ ** `v1`,`v8`: Elastic Common Schema compliant behavior (`[event][original]` is also added)
99
+
100
+ Controls this plugin's compatibility with the {ecs-ref}[Elastic Common Schema (ECS)].
101
+
102
+
85
103
  [id="plugins-{type}s-{plugin}-schema_uri"]
86
104
  ===== `schema_uri`
87
105
 
@@ -104,4 +122,25 @@ example:
104
122
 
105
123
  tag events with `_avroparsefailure` when decode fails
106
124
 
125
+ [id="plugins-{type}s-{plugin}-target"]
126
+ ===== `target`
127
+
128
+ * Value type is <<string,string>>
129
+ * There is no default value for this setting.
130
+ * This is only relevant when decode data into an event
107
131
 
132
+ Define the target field for placing the values. If this setting is not
133
+ set, the Avro data will be stored at the root (top level) of the event.
134
+
135
+ *Example*
136
+ [source,ruby]
137
+ ----------------------------------
138
+ input {
139
+ kafka {
140
+ codec => avro {
141
+ schema_uri => "/tmp/schema.avsc"
142
+ target => "[document]"
143
+ }
144
+ }
145
+ }
146
+ ----------------------------------
@@ -6,17 +6,21 @@ require "logstash/codecs/base"
6
6
  require "logstash/event"
7
7
  require "logstash/timestamp"
8
8
  require "logstash/util"
9
+ require 'logstash/plugin_mixins/ecs_compatibility_support'
10
+ require 'logstash/plugin_mixins/ecs_compatibility_support/target_check'
11
+ require 'logstash/plugin_mixins/validator_support/field_reference_validation_adapter'
12
+ require 'logstash/plugin_mixins/event_support/event_factory_adapter'
9
13
 
10
14
  # Read serialized Avro records as Logstash events
11
15
  #
12
- # This plugin is used to serialize Logstash events as
13
- # Avro datums, as well as deserializing Avro datums into
16
+ # This plugin is used to serialize Logstash events as
17
+ # Avro datums, as well as deserializing Avro datums into
14
18
  # Logstash events.
15
19
  #
16
20
  # ==== Encoding
17
- #
18
- # This codec is for serializing individual Logstash events
19
- # as Avro datums that are Avro binary blobs. It does not encode
21
+ #
22
+ # This codec is for serializing individual Logstash events
23
+ # as Avro datums that are Avro binary blobs. It does not encode
20
24
  # Logstash events into an Avro file.
21
25
  #
22
26
  #
@@ -48,6 +52,12 @@ require "logstash/util"
48
52
  class LogStash::Codecs::Avro < LogStash::Codecs::Base
49
53
  config_name "avro"
50
54
 
55
+ include LogStash::PluginMixins::ECSCompatibilitySupport(:disabled, :v1, :v8 => :v1)
56
+ include LogStash::PluginMixins::ECSCompatibilitySupport::TargetCheck
57
+
58
+ extend LogStash::PluginMixins::ValidatorSupport::FieldReferenceValidationAdapter
59
+
60
+ include LogStash::PluginMixins::EventSupport::EventFactoryAdapter
51
61
 
52
62
  # schema path to fetch the schema from.
53
63
  # This can be a 'http' or 'file' scheme URI
@@ -60,11 +70,22 @@ class LogStash::Codecs::Avro < LogStash::Codecs::Base
60
70
  # tag events with `_avroparsefailure` when decode fails
61
71
  config :tag_on_failure, :validate => :boolean, :default => false
62
72
 
73
+ # Defines a target field for placing decoded fields.
74
+ # If this setting is omitted, data gets stored at the root (top level) of the event.
75
+ #
76
+ # NOTE: the target is only relevant while decoding data into a new event.
77
+ config :target, :validate => :field_reference
78
+
63
79
  def open_and_read(uri_string)
64
80
  open(uri_string).read
65
81
  end
66
82
 
67
83
  public
84
+ def initialize(*params)
85
+ super
86
+ @original_field = ecs_select[disabled: nil, v1: '[event][original]']
87
+ end
88
+
68
89
  def register
69
90
  @schema = Avro::Schema.parse(open_and_read(schema_uri))
70
91
  end
@@ -74,11 +95,13 @@ class LogStash::Codecs::Avro < LogStash::Codecs::Base
74
95
  datum = StringIO.new(Base64.strict_decode64(data)) rescue StringIO.new(data)
75
96
  decoder = Avro::IO::BinaryDecoder.new(datum)
76
97
  datum_reader = Avro::IO::DatumReader.new(@schema)
77
- yield LogStash::Event.new(datum_reader.read(decoder))
98
+ event = targeted_event_factory.new_event(datum_reader.read(decoder))
99
+ event.set(@original_field, data.dup.freeze) if @original_field
100
+ yield event
78
101
  rescue => e
79
102
  if tag_on_failure
80
103
  @logger.error("Avro parse error, original data now in message field", :error => e)
81
- yield LogStash::Event.new("message" => data, "tags" => ["_avroparsefailure"])
104
+ yield event_factory.new_event("message" => data, "tags" => ["_avroparsefailure"])
82
105
  else
83
106
  raise e
84
107
  end
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-codec-avro'
4
- s.version = '3.2.4'
4
+ s.version = '3.3.0'
5
5
  s.platform = 'java'
6
6
  s.licenses = ['Apache-2.0']
7
7
  s.summary = "Reads serialized Avro records as Logstash events"
@@ -22,10 +22,13 @@ Gem::Specification.new do |s|
22
22
 
23
23
  # Gem dependencies
24
24
  s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
25
-
26
25
  s.add_runtime_dependency "avro" #(Apache 2.0 license)
26
+ s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~> 1.3'
27
+ s.add_runtime_dependency 'logstash-mixin-event_support', '~> 1.0'
28
+ s.add_runtime_dependency 'logstash-mixin-validator_support', '~> 1.0'
27
29
 
28
30
  s.add_development_dependency 'logstash-devutils'
29
31
  s.add_development_dependency 'insist'
32
+
30
33
  end
31
34
 
@@ -5,80 +5,115 @@ require 'avro'
5
5
  require 'base64'
6
6
  require 'logstash/codecs/avro'
7
7
  require 'logstash/event'
8
+ require 'logstash/plugin_mixins/ecs_compatibility_support/spec_helper'
8
9
 
9
- describe LogStash::Codecs::Avro do
10
+ describe LogStash::Codecs::Avro, :ecs_compatibility_support, :aggregate_failures do
10
11
 
11
- context "non binary data" do
12
- let (:avro_config) {{ 'schema_uri' => '
12
+ ecs_compatibility_matrix(:disabled, :v1, :v8 => :v1) do |ecs_select|
13
+ before(:each) do
14
+ allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
15
+ end
16
+
17
+ context "non binary data" do
18
+ let (:avro_config) {{ 'schema_uri' => '
13
19
  {"type": "record", "name": "Test",
14
20
  "fields": [{"name": "foo", "type": ["null", "string"]},
15
21
  {"name": "bar", "type": "int"}]}' }}
16
- let (:test_event) {LogStash::Event.new({ "foo" => "hello", "bar" => 10 })}
22
+ let (:test_event_hash) { { "foo" => "hello", "bar" => 10 } }
23
+ let (:test_event) {LogStash::Event.new(test_event_hash)}
17
24
 
18
- subject do
19
- allow_any_instance_of(LogStash::Codecs::Avro).to \
25
+ subject do
26
+ allow_any_instance_of(LogStash::Codecs::Avro).to \
20
27
  receive(:open_and_read).and_return(avro_config['schema_uri'])
21
- next LogStash::Codecs::Avro.new(avro_config)
22
- end
28
+ next LogStash::Codecs::Avro.new(avro_config)
29
+ end
23
30
 
24
- context "#decode" do
25
- it "should return an LogStash::Event from raw and base64 encoded avro data" do
26
- schema = Avro::Schema.parse(avro_config['schema_uri'])
27
- dw = Avro::IO::DatumWriter.new(schema)
28
- buffer = StringIO.new
29
- encoder = Avro::IO::BinaryEncoder.new(buffer)
30
- dw.write(test_event.to_hash, encoder)
31
-
32
- subject.decode(Base64.strict_encode64(buffer.string)) do |event|
33
- insist {event.is_a? LogStash::Event}
34
- insist {event.get("foo")} == test_event.get("foo")
35
- insist {event.get("bar")} == test_event.get("bar")
36
- end
37
- subject.decode(buffer.string) do |event|
38
- insist {event.is_a? LogStash::Event}
39
- insist {event.get("foo")} == test_event.get("foo")
40
- insist {event.get("bar")} == test_event.get("bar")
31
+ context "#decode" do
32
+ it "should return an LogStash::Event from raw and base64 encoded avro data" do
33
+ schema = Avro::Schema.parse(avro_config['schema_uri'])
34
+ dw = Avro::IO::DatumWriter.new(schema)
35
+ buffer = StringIO.new
36
+ encoder = Avro::IO::BinaryEncoder.new(buffer)
37
+ dw.write(test_event.to_hash, encoder)
38
+
39
+ subject.decode(Base64.strict_encode64(buffer.string)) do |event|
40
+ insist {event.is_a? LogStash::Event}
41
+ insist {event.get("foo")} == test_event.get("foo")
42
+ insist {event.get("bar")} == test_event.get("bar")
43
+ expect(event.get('[event][original]')).to eq(Base64.strict_encode64(buffer.string)) if ecs_compatibility != :disabled
44
+ end
45
+ subject.decode(buffer.string) do |event|
46
+ insist {event.is_a? LogStash::Event}
47
+ insist {event.get("foo")} == test_event.get("foo")
48
+ insist {event.get("bar")} == test_event.get("bar")
49
+ expect(event.get('[event][original]')).to eq(buffer.string) if ecs_compatibility != :disabled
50
+ end
41
51
  end
42
- end
43
52
 
44
- it "should throw exception if decoding fails" do
45
- expect {subject.decode("not avro") {|_| }}.to raise_error NoMethodError
53
+ it "should throw exception if decoding fails" do
54
+ expect {subject.decode("not avro") {|_| }}.to raise_error NoMethodError
55
+ end
46
56
  end
47
- end
48
57
 
49
- context "#decode with tag_on_failure" do
50
- let (:avro_config) {super.merge("tag_on_failure" => true)}
58
+ context "#decode with tag_on_failure" do
59
+ let (:avro_config) {{ 'schema_uri' => '
60
+ {"type": "record", "name": "Test",
61
+ "fields": [{"name": "foo", "type": ["null", "string"]},
62
+ {"name": "bar", "type": "int"}]}',
63
+ 'tag_on_failure' => true}}
51
64
 
52
- it "should tag event on failure" do
53
- subject.decode("not avro") do |event|
54
- insist {event.is_a? LogStash::Event}
55
- insist {event.get("tags")} == ["_avroparsefailure"]
65
+ it "should tag event on failure" do
66
+ subject.decode("not avro") do |event|
67
+ insist {event.is_a? LogStash::Event}
68
+ insist {event.get("tags")} == ["_avroparsefailure"]
69
+ end
56
70
  end
57
71
  end
58
- end
59
72
 
60
- context "#encode" do
61
- it "should return avro data from a LogStash::Event" do
62
- got_event = false
63
- subject.on_event do |event, data|
73
+ context "#decode with target" do
74
+ let(:avro_target) { "avro_target" }
75
+ let (:avro_config) {{ 'schema_uri' => '
76
+ {"type": "record", "name": "Test",
77
+ "fields": [{"name": "foo", "type": ["null", "string"]},
78
+ {"name": "bar", "type": "int"}]}',
79
+ 'target' => avro_target}}
80
+
81
+ it "should return an LogStash::Event with content in target" do
64
82
  schema = Avro::Schema.parse(avro_config['schema_uri'])
65
- datum = StringIO.new(Base64.strict_decode64(data))
66
- decoder = Avro::IO::BinaryDecoder.new(datum)
67
- datum_reader = Avro::IO::DatumReader.new(schema)
68
- record = datum_reader.read(decoder)
69
-
70
- insist {record["foo"]} == test_event.get("foo")
71
- insist {record["bar"]} == test_event.get("bar")
72
- insist {event.is_a? LogStash::Event}
73
- got_event = true
83
+ dw = Avro::IO::DatumWriter.new(schema)
84
+ buffer = StringIO.new
85
+ encoder = Avro::IO::BinaryEncoder.new(buffer)
86
+ dw.write(test_event.to_hash, encoder)
87
+
88
+ subject.decode(buffer.string) do |event|
89
+ insist {event.get("[#{avro_target}][foo]")} == test_event.get("foo")
90
+ insist {event.get("[#{avro_target}][bar]")} == test_event.get("bar")
91
+ end
74
92
  end
75
- subject.encode(test_event)
76
- insist {got_event}
77
93
  end
78
94
 
79
- context "binary data" do
95
+ context "#encode" do
96
+ it "should return avro data from a LogStash::Event" do
97
+ got_event = false
98
+ subject.on_event do |event, data|
99
+ schema = Avro::Schema.parse(avro_config['schema_uri'])
100
+ datum = StringIO.new(Base64.strict_decode64(data))
101
+ decoder = Avro::IO::BinaryDecoder.new(datum)
102
+ datum_reader = Avro::IO::DatumReader.new(schema)
103
+ record = datum_reader.read(decoder)
104
+
105
+ insist {record["foo"]} == test_event.get("foo")
106
+ insist {record["bar"]} == test_event.get("bar")
107
+ insist {event.is_a? LogStash::Event}
108
+ got_event = true
109
+ end
110
+ subject.encode(test_event)
111
+ insist {got_event}
112
+ end
113
+
114
+ context "binary data" do
80
115
 
81
- let (:avro_config) {{ 'schema_uri' => '{"namespace": "com.systems.test.data",
116
+ let (:avro_config) {{ 'schema_uri' => '{"namespace": "com.systems.test.data",
82
117
  "type": "record",
83
118
  "name": "TestRecord",
84
119
  "fields": [
@@ -87,29 +122,31 @@ describe LogStash::Codecs::Avro do
87
122
  {"name": "latitude", "type": ["double", "null"]}
88
123
  ]
89
124
  }' }}
90
- let (:test_event) {LogStash::Event.new({ "name" => "foo", "longitude" => 21.01234.to_f, "latitude" => 111.0123.to_f })}
125
+ let (:test_event) {LogStash::Event.new({ "name" => "foo", "longitude" => 21.01234.to_f, "latitude" => 111.0123.to_f })}
91
126
 
92
- subject do
93
- allow_any_instance_of(LogStash::Codecs::Avro).to \
127
+ subject do
128
+ allow_any_instance_of(LogStash::Codecs::Avro).to \
94
129
  receive(:open_and_read).and_return(avro_config['schema_uri'])
95
- next LogStash::Codecs::Avro.new(avro_config)
96
- end
130
+ next LogStash::Codecs::Avro.new(avro_config)
131
+ end
97
132
 
98
- it "should correctly encode binary data" do
99
- schema = Avro::Schema.parse(avro_config['schema_uri'])
100
- dw = Avro::IO::DatumWriter.new(schema)
101
- buffer = StringIO.new
102
- encoder = Avro::IO::BinaryEncoder.new(buffer)
103
- dw.write(test_event.to_hash, encoder)
133
+ it "should correctly encode binary data" do
134
+ schema = Avro::Schema.parse(avro_config['schema_uri'])
135
+ dw = Avro::IO::DatumWriter.new(schema)
136
+ buffer = StringIO.new
137
+ encoder = Avro::IO::BinaryEncoder.new(buffer)
138
+ dw.write(test_event.to_hash, encoder)
104
139
 
105
- subject.decode(Base64.strict_encode64(buffer.string)) do |event|
106
- insist {event.is_a? LogStash::Event}
107
- insist {event.get("name")} == test_event.get("name")
108
- insist {event.get("longitude")} == test_event.get("longitude")
109
- insist {event.get("latitude")} == test_event.get("latitude")
140
+ subject.decode(Base64.strict_encode64(buffer.string)) do |event|
141
+ insist {event.is_a? LogStash::Event}
142
+ insist {event.get("name")} == test_event.get("name")
143
+ insist {event.get("longitude")} == test_event.get("longitude")
144
+ insist {event.get("latitude")} == test_event.get("latitude")
145
+ end
110
146
  end
111
147
  end
112
148
  end
149
+
113
150
  end
114
151
  end
115
152
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-codec-avro
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.4
4
+ version: 3.3.0
5
5
  platform: java
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-21 00:00:00.000000000 Z
11
+ date: 2021-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -44,6 +44,48 @@ dependencies:
44
44
  - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '1.3'
53
+ name: logstash-mixin-ecs_compatibility_support
54
+ prerelease: false
55
+ type: :runtime
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.3'
61
+ - !ruby/object:Gem::Dependency
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '1.0'
67
+ name: logstash-mixin-event_support
68
+ prerelease: false
69
+ type: :runtime
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1.0'
75
+ - !ruby/object:Gem::Dependency
76
+ requirement: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '1.0'
81
+ name: logstash-mixin-validator_support
82
+ prerelease: false
83
+ type: :runtime
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '1.0'
47
89
  - !ruby/object:Gem::Dependency
48
90
  requirement: !ruby/object:Gem::Requirement
49
91
  requirements:
@@ -112,8 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
154
  - !ruby/object:Gem::Version
113
155
  version: '0'
114
156
  requirements: []
115
- rubyforge_project:
116
- rubygems_version: 2.6.13
157
+ rubygems_version: 3.1.6
117
158
  signing_key:
118
159
  specification_version: 4
119
160
  summary: Reads serialized Avro records as Logstash events