diff --git a/Gemfile b/Gemfile index a6b25daefda..79c9f2af4a2 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,7 @@ source "https://rubygems.org" gem "logstash-core", "5.0.0.dev", :path => "./logstash-core" gem "logstash-core-event-java", "5.0.0.dev", :path => "./logstash-core-event-java" -gem "logstash-core-plugin-api", "1.0.0", :path => "./logstash-core-plugin-api" +gem "logstash-core-plugin-api", "2.0.0", :path => "./logstash-core-plugin-api" gem "file-dependencies", "0.1.6" gem "ci_reporter_rspec", "1.0.0", :group => :development gem "simplecov", :group => :development @@ -14,10 +14,10 @@ gem "coveralls", :group => :development # 1.6 is the last supported version on jruby. gem "tins", "1.6", :group => :development gem "rspec", "~> 3.1.0", :group => :development -gem "logstash-devutils", "~> 0.0.15", :group => :development +gem "logstash-devutils", :group => :development gem "benchmark-ips", :group => :development gem "octokit", "3.8.0", :group => :build -gem "stud", "~> 0.0.21", :group => :build +gem "stud", "~> 0.0.22", :group => :build gem "fpm", "~> 1.3.3", :group => :build gem "rubyzip", "~> 1.1.7", :group => :build gem "gems", "~> 0.8.3", :group => :build diff --git a/Gemfile.jruby-1.9.lock b/Gemfile.jruby-1.9.lock index 7510eb2679d..709340a1965 100644 --- a/Gemfile.jruby-1.9.lock +++ b/Gemfile.jruby-1.9.lock @@ -1,3 +1,136 @@ +GIT + remote: git://github.com/elastic/logstash-devutils.git + revision: e9af3a24824a41d0f19b025ca359e0735e820251 + branch: feature/plugin-api-2_0 + specs: + logstash-devutils (0.0.19-java) + fivemat + gem_publisher + insist (= 1.0.0) + kramdown + minitar + rake + rspec (~> 3.1.0) + rspec-wait + stud (>= 0.0.20) + +GIT + remote: git://github.com/logstash-plugins/logstash-codec-json.git + revision: 141d488f3a73706d5ae08dd41468fed285fbbdf9 + branch: feature/plugin-api-2_0 + specs: + logstash-codec-json (2.1.4) + logstash-core-plugin-api (~> 2.0) + +GIT + remote: git://github.com/logstash-plugins/logstash-codec-json_lines.git + revision: f1a3fda4d1affaa6da4b037eec78ee5f10287eb8 + branch: feature/plugin-api-2_0 + specs: + logstash-codec-json_lines (2.1.3) + logstash-codec-line (>= 2.1.0) + logstash-core-plugin-api (~> 2.0) + +GIT + remote: git://github.com/logstash-plugins/logstash-codec-line.git + revision: f912b6ca5137bef914ea0e605cb34520b0f172d4 + branch: feature/plugin-api-2_0 + specs: + logstash-codec-line (2.1.2) + logstash-core-plugin-api (~> 2.0) + +GIT + remote: git://github.com/logstash-plugins/logstash-codec-plain.git + revision: 5c5424905d5e06d7f7adc888411057c8a5681194 + branch: feature/plugin-api-2_0 + specs: + logstash-codec-plain (2.0.4) + logstash-core-plugin-api (~> 2.0) + +GIT + remote: git://github.com/logstash-plugins/logstash-filter-clone.git + revision: 4da247817809ff68a47557f022c8049536651564 + branch: feature/plugin-api-2_0 + specs: + logstash-filter-clone (2.0.6) + logstash-core-plugin-api (~> 2.0) + +GIT + remote: git://github.com/logstash-plugins/logstash-filter-grok.git + revision: 284dc6614b0cac6770cda2c18a52f8405146f1eb + branch: feature/plugin-api-2_0 + specs: + logstash-filter-grok (2.0.5) + jls-grok (~> 0.11.1) + logstash-core-plugin-api (~> 2.0) + logstash-patterns-core + +GIT + remote: git://github.com/logstash-plugins/logstash-filter-multiline.git + revision: fd1da31b7d1e0b44319c0f2865c767b36440583d + branch: feature/plugin-api-2_0 + specs: + logstash-filter-multiline (2.0.5) + jls-grok (~> 0.11.0) + logstash-core-plugin-api (~> 2.0) + logstash-patterns-core + +GIT + remote: git://github.com/logstash-plugins/logstash-filter-mutate.git + revision: f9624cc0a05354c308b2d22a5895c737eceaa08b + branch: feature/plugin-api-2_0 + specs: + logstash-filter-mutate (2.0.6) + logstash-core-plugin-api (~> 2.0) + +GIT + remote: git://github.com/logstash-plugins/logstash-input-generator.git + revision: 2557a4e7da667d6e801cac47e27ff297b6ecc79a + branch: feature/plugin-api-2_0 + specs: + logstash-input-generator (2.0.4) + logstash-codec-plain + logstash-core-plugin-api (~> 2.0) + +GIT + remote: git://github.com/logstash-plugins/logstash-input-stdin.git + revision: cca193c505f931500bd0f6be45afada2af0578ed + branch: feature/plugin-api-2_0 + specs: + logstash-input-stdin (2.0.4) + concurrent-ruby + logstash-codec-line + logstash-core-plugin-api (~> 2.0) + +GIT + remote: git://github.com/logstash-plugins/logstash-input-tcp.git + revision: b6f2705d7fc226c08dd0905561ef9373d2801a58 + branch: feature/plugin-api-2_0 + specs: + logstash-input-tcp (3.0.5) + logstash-codec-json + logstash-codec-json_lines + logstash-codec-line + logstash-codec-plain + logstash-core-plugin-api (~> 2.0) + +GIT + remote: git://github.com/logstash-plugins/logstash-output-stdout.git + revision: c150cb4f560b047372e15887e8b6bf421af22fc9 + branch: feature/plugin-api-2_0 + specs: + logstash-output-stdout (2.0.6) + logstash-codec-line + logstash-core-plugin-api (~> 2.0) + +GIT + remote: git://github.com/logstash-plugins/logstash-patterns-core.git + revision: e039ba2d3db6a01b6501fe0cab8a82453c6dc45f + branch: feature/plugin-api-2_0 + specs: + logstash-patterns-core (2.0.5) + logstash-core-plugin-api (~> 2.0) + PATH remote: ./logstash-core specs: @@ -10,8 +143,8 @@ PATH gems (~> 0.8.3) i18n (= 0.6.9) jrjackson (~> 0.3.7) - jruby-monitoring (~> 0.1) - jruby-openssl (= 0.9.13) + jruby-monitoring (~> 0.3.1) + jruby-openssl (= 0.9.16) logstash-core-event-java (~> 5.0.0.dev) minitar (~> 0.5.4) pry (~> 0.10.1) @@ -32,7 +165,7 @@ PATH PATH remote: ./logstash-core-plugin-api specs: - logstash-core-plugin-api (1.0.0-java) + logstash-core-plugin-api (2.0.0-java) logstash-core (= 5.0.0.dev) GEM @@ -42,7 +175,7 @@ GEM arr-pm (0.0.10) cabin (> 0) backports (3.6.8) - benchmark-ips (2.5.0) + benchmark-ips (2.6.1) builder (3.2.2) cabin (0.8.1) childprocess (0.5.9) @@ -71,6 +204,7 @@ GEM file-dependencies (0.1.6) minitar filesize (0.0.4) + fivemat (1.3.2) flores (0.0.6) fpm (1.3.3) arr-pm (~> 0.0.9) @@ -85,20 +219,13 @@ GEM i18n (0.6.9) insist (1.0.0) jar-dependencies (0.3.2) - jrjackson (0.3.8) - jruby-monitoring (0.3.0) - jruby-openssl (0.9.13-java) + jls-grok (0.11.2) + cabin (>= 0.6.0) + jrjackson (0.3.9-java) + jruby-monitoring (0.3.1) + jruby-openssl (0.9.16-java) json (1.8.3-java) kramdown (1.10.0) - logstash-devutils (0.0.18-java) - gem_publisher - insist (= 1.0.0) - kramdown - minitar - rake - rspec (~> 3.1.0) - rspec-wait - stud (>= 0.0.20) method_source (0.8.2) minitar (0.5.4) multipart-post (2.0.0) @@ -173,14 +300,27 @@ DEPENDENCIES flores (~> 0.0.6) fpm (~> 1.3.3) gems (~> 0.8.3) + logstash-codec-json! + logstash-codec-json_lines! + logstash-codec-line! + logstash-codec-plain! logstash-core (= 5.0.0.dev)! logstash-core-event-java (= 5.0.0.dev)! - logstash-core-plugin-api (= 1.0.0)! - logstash-devutils (~> 0.0.15) + logstash-core-plugin-api (= 2.0.0)! + logstash-devutils! + logstash-filter-clone! + logstash-filter-grok! + logstash-filter-multiline! + logstash-filter-mutate! + logstash-input-generator! + logstash-input-stdin! + logstash-input-tcp! + logstash-output-stdout! + logstash-patterns-core! octokit (= 3.8.0) rack-test rspec (~> 3.1.0) rubyzip (~> 1.1.7) simplecov - stud (~> 0.0.21) + stud (~> 0.0.22) tins (= 1.6) diff --git a/logstash-core-event-java/lib/logstash-core-event-java/logstash-core-event-java.jar b/logstash-core-event-java/lib/logstash-core-event-java/logstash-core-event-java.jar new file mode 100644 index 00000000000..ec9ed306bc6 Binary files /dev/null and b/logstash-core-event-java/lib/logstash-core-event-java/logstash-core-event-java.jar differ diff --git a/logstash-core-event-java/spec/event_spec.rb b/logstash-core-event-java/spec/event_spec.rb index 03cbffa73c6..8ccae4f6cf9 100644 --- a/logstash-core-event-java/spec/event_spec.rb +++ b/logstash-core-event-java/spec/event_spec.rb @@ -26,10 +26,10 @@ it "should serialize deep hash from field reference assignments" do e = LogStash::Event.new({TIMESTAMP => "2015-05-28T23:02:05.350Z"}) - e["foo"] = "bar" - e["bar"] = 1 - e["baz"] = 1.0 - e["[fancy][pants][socks]"] = "shoes" + e.set("foo", "bar") + e.set("bar", 1) + e.set("baz", 1.0) + e.set("[fancy][pants][socks]", "shoes") expect(JSON.parse(e.to_json)).to eq(JSON.parse("{\"@timestamp\":\"2015-05-28T23:02:05.350Z\",\"@version\":\"1\",\"foo\":\"bar\",\"bar\":1,\"baz\":1.0,\"fancy\":{\"pants\":{\"socks\":\"shoes\"}}}")) end end @@ -37,79 +37,79 @@ context "[]" do it "should get simple values" do e = LogStash::Event.new({"foo" => "bar", "bar" => 1, "baz" => 1.0, TIMESTAMP => "2015-05-28T23:02:05.350Z"}) - expect(e["foo"]).to eq("bar") - expect(e["[foo]"]).to eq("bar") - expect(e["bar"]).to eq(1) - expect(e["[bar]"]).to eq(1) - expect(e["baz"]).to eq(1.0) - expect(e["[baz]"]).to eq(1.0) - expect(e[TIMESTAMP].to_s).to eq("2015-05-28T23:02:05.350Z") - expect(e["[#{TIMESTAMP}]"].to_s).to eq("2015-05-28T23:02:05.350Z") + expect(e.get("foo")).to eq("bar") + expect(e.get("[foo]")).to eq("bar") + expect(e.get("bar")).to eq(1) + expect(e.get("[bar]")).to eq(1) + expect(e.get("baz")).to eq(1.0) + expect(e.get("[baz]")).to eq(1.0) + expect(e.get(TIMESTAMP).to_s).to eq("2015-05-28T23:02:05.350Z") + expect(e.get("[#{TIMESTAMP}]").to_s).to eq("2015-05-28T23:02:05.350Z") end it "should get deep hash values" do e = LogStash::Event.new({"foo" => {"bar" => 1, "baz" => 1.0}}) - expect(e["[foo][bar]"]).to eq(1) - expect(e["[foo][baz]"]).to eq(1.0) + expect(e.get("[foo][bar]")).to eq(1) + expect(e.get("[foo][baz]")).to eq(1.0) end it "should get deep array values" do e = LogStash::Event.new({"foo" => ["bar", 1, 1.0]}) - expect(e["[foo][0]"]).to eq("bar") - expect(e["[foo][1]"]).to eq(1) - expect(e["[foo][2]"]).to eq(1.0) - expect(e["[foo][3]"]).to be_nil + expect(e.get("[foo][0]")).to eq("bar") + expect(e.get("[foo][1]")).to eq(1) + expect(e.get("[foo][2]")).to eq(1.0) + expect(e.get("[foo][3]")).to be_nil end end context "[]=" do it "should set simple values" do e = LogStash::Event.new() - expect(e["foo"] = "bar").to eq("bar") - expect(e["foo"]).to eq("bar") + expect(e.set("foo", "bar")).to eq("bar") + expect(e.get("foo")).to eq("bar") e = LogStash::Event.new({"foo" => "test"}) - expect(e["foo"] = "bar").to eq("bar") - expect(e["foo"]).to eq("bar") + expect(e.set("foo", "bar")).to eq("bar") + expect(e.get("foo")).to eq("bar") end it "should set deep hash values" do e = LogStash::Event.new() - expect(e["[foo][bar]"] = "baz").to eq("baz") - expect(e["[foo][bar]"]).to eq("baz") - expect(e["[foo][baz]"]).to be_nil + expect(e.set("[foo][bar]", "baz")).to eq("baz") + expect(e.get("[foo][bar]")).to eq("baz") + expect(e.get("[foo][baz]")).to be_nil end it "should set deep array values" do e = LogStash::Event.new() - expect(e["[foo][0]"] = "bar").to eq("bar") - expect(e["[foo][0]"]).to eq("bar") - expect(e["[foo][1]"] = 1).to eq(1) - expect(e["[foo][1]"]).to eq(1) - expect(e["[foo][2]"] = 1.0 ).to eq(1.0) - expect(e["[foo][2]"]).to eq(1.0) - expect(e["[foo][3]"]).to be_nil + expect(e.set("[foo][0]", "bar")).to eq("bar") + expect(e.get("[foo][0]")).to eq("bar") + expect(e.set("[foo][1]", 1)).to eq(1) + expect(e.get("[foo][1]")).to eq(1) + expect(e.set("[foo][2]", 1.0)).to eq(1.0) + expect(e.get("[foo][2]")).to eq(1.0) + expect(e.get("[foo][3]")).to be_nil end it "should add key when setting nil value" do e = LogStash::Event.new() - e["[foo]"] = nil + e.set("[foo]", nil) expect(e.to_hash).to include("foo" => nil) end # BigDecinal is now natively converted by JRuby, see https://github.com/elastic/logstash/pull/4838 it "should set BigDecimal" do e = LogStash::Event.new() - e["[foo]"] = BigDecimal.new(1) - expect(e["foo"]).to be_kind_of(BigDecimal) - expect(e["foo"]).to eq(BigDecimal.new(1)) + e.set("[foo]", BigDecimal.new(1)) + expect(e.get("foo")).to be_kind_of(BigDecimal) + expect(e.get("foo")).to eq(BigDecimal.new(1)) end it "should set RubyBignum" do e = LogStash::Event.new() - e["[foo]"] = -9223372036854776000 - expect(e["foo"]).to be_kind_of(Bignum) - expect(e["foo"]).to eq(-9223372036854776000) + e.set("[foo]", -9223372036854776000) + expect(e.get("foo")).to be_kind_of(Bignum) + expect(e.get("foo")).to eq(-9223372036854776000) end end @@ -117,7 +117,7 @@ it "getters should present a Ruby LogStash::Timestamp" do e = LogStash::Event.new() expect(e.timestamp.class).to eq(LogStash::Timestamp) - expect(e[TIMESTAMP].class).to eq(LogStash::Timestamp) + expect(e.get(TIMESTAMP).class).to eq(LogStash::Timestamp) end it "to_hash should inject a Ruby LogStash::Timestamp" do @@ -134,9 +134,9 @@ it "should set timestamp" do e = LogStash::Event.new now = Time.now - e["@timestamp"] = LogStash::Timestamp.at(now.to_i) + e.set("@timestamp", LogStash::Timestamp.at(now.to_i)) expect(e.timestamp.to_i).to eq(now.to_i) - expect(e["@timestamp"].to_i).to eq(now.to_i) + expect(e.get("@timestamp").to_i).to eq(now.to_i) end end @@ -144,16 +144,16 @@ it "should append" do event = LogStash::Event.new("message" => "hello world") event.append(LogStash::Event.new("message" => "another thing")) - expect(event["message"]).to eq(["hello world", "another thing"]) + expect(event.get("message")).to eq(["hello world", "another thing"]) end end context "tags" do it "should tag" do event = LogStash::Event.new("message" => "hello world") - expect(event["tags"]).to be_nil - event["tags"] = ["foo"] - expect(event["tags"]).to eq(["foo"]) + expect(event.get("tags")).to be_nil + event.tag("foo") + expect(event.get("tags")).to eq(["foo"]) end end @@ -258,8 +258,8 @@ def self.warn(message) expect(LogStash::Event.from_json(source_json).size).to eq(1) event = LogStash::Event.from_json(source_json)[0] - expect(event["[foo]"]).to eq(1) - expect(event["[bar]"]).to eq("baz") + expect(event.get("[foo]")).to eq(1) + expect(event.get("[bar]")).to eq("baz") end it "should ignore blank strings" do diff --git a/logstash-core-event-java/src/main/java/com/logstash/ext/JrubyEventExtLibrary.java b/logstash-core-event-java/src/main/java/com/logstash/ext/JrubyEventExtLibrary.java index 1cb630d5a75..8cf5024f339 100644 --- a/logstash-core-event-java/src/main/java/com/logstash/ext/JrubyEventExtLibrary.java +++ b/logstash-core-event-java/src/main/java/com/logstash/ext/JrubyEventExtLibrary.java @@ -140,14 +140,14 @@ public IRubyObject ruby_initialize(ThreadContext context, IRubyObject[] args) return context.nil; } - @JRubyMethod(name = "[]", required = 1) + @JRubyMethod(name = "get", required = 1) public IRubyObject ruby_get_field(ThreadContext context, RubyString reference) { Object value = this.event.getField(reference.asJavaString()); return Rubyfier.deep(context.runtime, value); } - @JRubyMethod(name = "[]=", required = 2) + @JRubyMethod(name = "set", required = 2) public IRubyObject ruby_set_field(ThreadContext context, RubyString reference, IRubyObject value) { String r = reference.asJavaString(); diff --git a/logstash-core-event/lib/logstash/event.rb b/logstash-core-event/lib/logstash/event.rb index b1eb9d46cdb..7a9b7d133c9 100644 --- a/logstash-core-event/lib/logstash/event.rb +++ b/logstash-core-event/lib/logstash/event.rb @@ -54,6 +54,7 @@ class DeprecatedMethod < StandardError; end VERSION_ONE = "1" TIMESTAMP_FAILURE_TAG = "_timestampparsefailure" TIMESTAMP_FAILURE_FIELD = "_@timestamp" + TAGS = "tags".freeze METADATA = "@metadata".freeze METADATA_BRACKETS = "[#{METADATA}]".freeze @@ -113,7 +114,7 @@ def timestamp=(val) @data[TIMESTAMP] = val end - def [](fieldref) + def get(fieldref) if fieldref.start_with?(METADATA_BRACKETS) @metadata_accessors.get(fieldref[METADATA_BRACKETS.length .. -1]) elsif fieldref == METADATA @@ -123,7 +124,7 @@ def [](fieldref) end end - def []=(fieldref, value) + def set(fieldref, value) if fieldref == TIMESTAMP && !value.is_a?(LogStash::Timestamp) raise TypeError, "The field '@timestamp' must be a (LogStash::Timestamp, not a #{value.class} (#{value})" end @@ -201,8 +202,9 @@ def sprintf(format) def tag(value) # Generalize this method for more usability - self["tags"] ||= [] - self["tags"] << value unless self["tags"].include?(value) + tags = @accessors.get(TAGS) || [] + tags << value unless tags.include?(value) + @accessors.set(TAGS, tags) end def to_hash_with_metadata @@ -269,9 +271,8 @@ def init_timestamp(o) logger.warn("Error parsing #{TIMESTAMP} string, setting current time to #{TIMESTAMP}, original in #{TIMESTAMP_FAILURE_FIELD} field", :value => o.inspect, :exception => e.message) end - @data["tags"] ||= [] - @data["tags"] << TIMESTAMP_FAILURE_TAG unless @data["tags"].include?(TIMESTAMP_FAILURE_TAG) - @data[TIMESTAMP_FAILURE_FIELD] = o + tag(TIMESTAMP_FAILURE_TAG) + @accessors.set(TIMESTAMP_FAILURE_FIELD, o) LogStash::Timestamp.now end diff --git a/logstash-core-event/lib/logstash/string_interpolation.rb b/logstash-core-event/lib/logstash/string_interpolation.rb index 13044e4c005..aaa54981165 100644 --- a/logstash-core-event/lib/logstash/string_interpolation.rb +++ b/logstash-core-event/lib/logstash/string_interpolation.rb @@ -115,7 +115,7 @@ def initialize(key) end def evaluate(event) - value = event[@key] + value = event.get(@key) case value when nil diff --git a/logstash-core-event/spec/logstash/event_spec.rb b/logstash-core-event/spec/logstash/event_spec.rb index 0389ffc6d25..8c6d60db291 100644 --- a/logstash-core-event/spec/logstash/event_spec.rb +++ b/logstash-core-event/spec/logstash/event_spec.rb @@ -8,68 +8,68 @@ shared_examples "all event tests" do context "[]=" do it "should raise an exception if you attempt to set @timestamp to a value type other than a Time object" do - expect{subject["@timestamp"] = "crash!"}.to raise_error(TypeError) + expect{subject.set("@timestamp", "crash!")}.to raise_error(TypeError) end it "should assign simple fields" do - expect(subject["foo"]).to be_nil - expect(subject["foo"] = "bar").to eq("bar") - expect(subject["foo"]).to eq("bar") + expect(subject.get("foo")).to be_nil + expect(subject.set("foo", "bar")).to eq("bar") + expect(subject.get("foo")).to eq("bar") end it "should overwrite simple fields" do - expect(subject["foo"]).to be_nil - expect(subject["foo"] = "bar").to eq("bar") - expect(subject["foo"]).to eq("bar") + expect(subject.get("foo")).to be_nil + expect(subject.set("foo", "bar")).to eq("bar") + expect(subject.get("foo")).to eq("bar") - expect(subject["foo"] = "baz").to eq("baz") - expect(subject["foo"]).to eq("baz") + expect(subject.set("foo", "baz")).to eq("baz") + expect(subject.get("foo")).to eq("baz") end it "should assign deep fields" do - expect(subject["[foo][bar]"]).to be_nil - expect(subject["[foo][bar]"] = "baz").to eq("baz") - expect(subject["[foo][bar]"]).to eq("baz") + expect(subject.get("[foo][bar]")).to be_nil + expect(subject.set("[foo][bar]", "baz")).to eq("baz") + expect(subject.get("[foo][bar]")).to eq("baz") end it "should overwrite deep fields" do - expect(subject["[foo][bar]"]).to be_nil - expect(subject["[foo][bar]"] = "baz").to eq("baz") - expect(subject["[foo][bar]"]).to eq("baz") + expect(subject.get("[foo][bar]")).to be_nil + expect(subject.set("[foo][bar]", "baz")).to eq("baz") + expect(subject.get("[foo][bar]")).to eq("baz") - expect(subject["[foo][bar]"] = "zab").to eq("zab") - expect(subject["[foo][bar]"]).to eq("zab") + expect(subject.set("[foo][bar]", "zab")).to eq("zab") + expect(subject.get("[foo][bar]")).to eq("zab") end it "allow to set the @metadata key to a hash" do - subject["@metadata"] = { "action" => "index" } - expect(subject["[@metadata][action]"]).to eq("index") + subject.set("@metadata", { "action" => "index" }) + expect(subject.get("[@metadata][action]")).to eq("index") end it "should add key when setting nil value" do - subject["[baz]"] = nil + subject.set("[baz]", nil) expect(subject.to_hash).to include("baz" => nil) end it "should set nil element within existing array value" do - subject["[foo]"] = ["bar", "baz"] + subject.set("[foo]", ["bar", "baz"]) - expect(subject["[foo][0]"] = nil).to eq(nil) - expect(subject["[foo]"]).to eq([nil, "baz"]) + expect(subject.set("[foo][0]", nil)).to eq(nil) + expect(subject.get("[foo]")).to eq([nil, "baz"]) end it "should set nil in first element within empty array" do - subject["[foo]"] = [] + subject.set("[foo]", []) - expect(subject["[foo][0]"] = nil).to eq(nil) - expect(subject["[foo]"]).to eq([nil]) + expect(subject.set("[foo][0]", nil)).to eq(nil) + expect(subject.get("[foo]")).to eq([nil]) end it "should set nil in second element within empty array" do - subject["[foo]"] = [] + subject.set("[foo]", []) - expect(subject["[foo][1]"] = nil).to eq(nil) - expect(subject["[foo]"]).to eq([nil, nil]) + expect(subject.set("[foo][1]", nil)).to eq(nil) + expect(subject.get("[foo]")).to eq([nil, nil]) end end @@ -79,7 +79,7 @@ event = LogStash::Event.new({ "reference" => data }) LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin") data.downcase! - expect(event["reference_test"]).not_to eq(data) + expect(event.get("reference_test")).not_to eq(data) end it "should not return a Fixnum reference" do @@ -87,7 +87,7 @@ event = LogStash::Event.new({ "reference" => data }) LogStash::Util::Decorators.add_fields({"reference_test" => "%{reference}"}, event, "dummy-plugin") data += 41 - expect(event["reference_test"]).to eq("1") + expect(event.get("reference_test")).to eq("1") end it "should report a unix timestamp for %{+%s}" do @@ -124,7 +124,7 @@ it "should report fields with %{field} syntax" do expect(subject.sprintf("%{type}")).to eq("sprintf") - expect(subject.sprintf("%{message}")).to eq(subject["message"]) + expect(subject.sprintf("%{message}")).to eq(subject.get("message")) end it "should print deep fields" do @@ -153,35 +153,35 @@ end it "should render nil array values as leading empty string" do - expect(subject["foo"] = [nil, "baz"]).to eq([nil, "baz"]) + expect(subject.set("foo", [nil, "baz"])).to eq([nil, "baz"]) - expect(subject["[foo][0]"]).to be_nil - expect(subject["[foo][1]"]).to eq("baz") + expect(subject.get("[foo][0]")).to be_nil + expect(subject.get("[foo][1]")).to eq("baz") expect(subject.sprintf("%{[foo]}")).to eq(",baz") end it "should render nil array values as middle empty string" do - expect(subject["foo"] = ["bar", nil, "baz"]).to eq(["bar", nil, "baz"]) + expect(subject.set("foo", ["bar", nil, "baz"])).to eq(["bar", nil, "baz"]) - expect(subject["[foo][0]"]).to eq("bar") - expect(subject["[foo][1]"]).to be_nil - expect(subject["[foo][2]"]).to eq("baz") + expect(subject.get("[foo][0]")).to eq("bar") + expect(subject.get("[foo][1]")).to be_nil + expect(subject.get("[foo][2]")).to eq("baz") expect(subject.sprintf("%{[foo]}")).to eq("bar,,baz") end it "should render nil array values as trailing empty string" do - expect(subject["foo"] = ["bar", nil]).to eq(["bar", nil]) + expect(subject.set("foo", ["bar", nil])).to eq(["bar", nil]) - expect(subject["[foo][0]"]).to eq("bar") - expect(subject["[foo][1]"]).to be_nil + expect(subject.get("[foo][0]")).to eq("bar") + expect(subject.get("[foo][1]")).to be_nil expect(subject.sprintf("%{[foo]}")).to eq("bar,") end it "should render deep arrays with nil value" do - subject["[foo]"] = [[12, nil], 56] + subject.set("[foo]", [[12, nil], 56]) expect(subject.sprintf("%{[foo]}")).to eq("12,,56") end @@ -198,18 +198,18 @@ context "#[]" do it "should fetch data" do - expect(subject["type"]).to eq("sprintf") + expect(subject.get("type")).to eq("sprintf") end it "should fetch fields" do - expect(subject["a"]).to eq("b") - expect(subject['c']['d']).to eq("f") + expect(subject.get("a")).to eq("b") + expect(subject.get('c')['d']).to eq("f") end it "should fetch deep fields" do - expect(subject["[j][k1]"]).to eq("v") - expect(subject["[c][d]"]).to eq("f") - expect(subject['[f][g][h]']).to eq("i") - expect(subject['[j][k3][4]']).to eq("m") - expect(subject['[j][5]']).to eq(7) + expect(subject.get("[j][k1]")).to eq("v") + expect(subject.get("[c][d]")).to eq("f") + expect(subject.get('[f][g][h]')).to eq("i") + expect(subject.get('[j][k3][4]')).to eq("m") + expect(subject.get('[j][5]')).to eq(7) end @@ -217,7 +217,7 @@ count = 1000000 2.times do start = Time.now - count.times { subject["[j][k1]"] } + count.times { subject.get("[j][k1]") } duration = Time.now - start puts "event #[] rate: #{"%02.0f/sec" % (count / duration)}, elapsed: #{duration}s" end @@ -263,11 +263,11 @@ ) subject.overwrite(new_event) - expect(subject["message"]).to eq("foo bar") - expect(subject["type"]).to eq("new") + expect(subject.get("message")).to eq("foo bar") + expect(subject.get("type")).to eq("new") ["tags", "source", "a", "c", "f", "j"].each do |field| - expect(subject[field]).to be_nil + expect(subject.get(field)).to be_nil end end end @@ -275,7 +275,7 @@ context "#append" do it "should append strings to an array" do subject.append(LogStash::Event.new("message" => "another thing")) - expect(subject["message"]).to eq([ "hello world", "another thing" ]) + expect(subject.get("message")).to eq([ "hello world", "another thing" ]) end it "should concatenate tags" do @@ -283,54 +283,54 @@ # added to_a for when array is a Java Collection when produced from json input # TODO: we have to find a better way to handle this in tests. maybe override # rspec eq or == to do an explicit to_a when comparing arrays? - expect(subject["tags"].to_a).to eq([ "tag1", "tag2" ]) + expect(subject.get("tags").to_a).to eq([ "tag1", "tag2" ]) end context "when event field is nil" do it "should add single value as string" do subject.append(LogStash::Event.new({"field1" => "append1"})) - expect(subject[ "field1" ]).to eq("append1") + expect(subject.get("field1")).to eq("append1") end it "should add multi values as array" do subject.append(LogStash::Event.new({"field1" => [ "append1","append2" ]})) - expect(subject[ "field1" ]).to eq([ "append1","append2" ]) + expect(subject.get("field1")).to eq([ "append1","append2" ]) end end context "when event field is a string" do - before { subject[ "field1" ] = "original1" } + before { subject.set("field1", "original1") } it "should append string to values, if different from current" do subject.append(LogStash::Event.new({"field1" => "append1"})) - expect(subject[ "field1" ]).to eq([ "original1", "append1" ]) + expect(subject.get("field1")).to eq([ "original1", "append1" ]) end it "should not change value, if appended value is equal current" do subject.append(LogStash::Event.new({"field1" => "original1"})) - expect(subject[ "field1" ]).to eq("original1") + expect(subject.get("field1")).to eq("original1") end it "should concatenate values in an array" do subject.append(LogStash::Event.new({"field1" => [ "append1" ]})) - expect(subject[ "field1" ]).to eq([ "original1", "append1" ]) + expect(subject.get("field1")).to eq([ "original1", "append1" ]) end it "should join array, removing duplicates" do subject.append(LogStash::Event.new({"field1" => [ "append1","original1" ]})) - expect(subject[ "field1" ]).to eq([ "original1", "append1" ]) + expect(subject.get("field1")).to eq([ "original1", "append1" ]) end end context "when event field is an array" do - before { subject[ "field1" ] = [ "original1", "original2" ] } + before { subject.set("field1", [ "original1", "original2" ] )} it "should append string values to array, if not present in array" do subject.append(LogStash::Event.new({"field1" => "append1"})) - expect(subject[ "field1" ]).to eq([ "original1", "original2", "append1" ]) + expect(subject.get("field1")).to eq([ "original1", "original2", "append1" ]) end it "should not append string values, if the array already contains it" do subject.append(LogStash::Event.new({"field1" => "original1"})) - expect(subject[ "field1" ]).to eq([ "original1", "original2" ]) + expect(subject.get("field1")).to eq([ "original1", "original2" ]) end it "should join array, removing duplicates" do subject.append(LogStash::Event.new({"field1" => [ "append1","original1" ]})) - expect(subject[ "field1" ]).to eq([ "original1", "original2", "append1" ]) + expect(subject.get("field1")).to eq([ "original1", "original2", "append1" ]) end end @@ -342,7 +342,7 @@ data = { "@timestamp" => "2013-12-21T07:25:06.605Z" } event = LogStash::Event.new(data) - expect(event["@timestamp"]).to be_a(LogStash::Timestamp) + expect(event.get("@timestamp")).to be_a(LogStash::Timestamp) duration = 0 [warmup, count].each do |i| @@ -411,13 +411,13 @@ it "should tag for invalid value" do event = LogStash::Event.new("@timestamp" => "foo") expect(event.timestamp.to_i).to be_within(1).of Time.now.to_i - expect(event["tags"]).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG]) - expect(event[LogStash::Event::TIMESTAMP_FAILURE_FIELD]).to eq("foo") + expect(event.get("tags")).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG]) + expect(event.get(LogStash::Event::TIMESTAMP_FAILURE_FIELD)).to eq("foo") event = LogStash::Event.new("@timestamp" => 666) expect(event.timestamp.to_i).to be_within(1).of Time.now.to_i - expect(event["tags"]).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG]) - expect(event[LogStash::Event::TIMESTAMP_FAILURE_FIELD]).to eq(666) + expect(event.get("tags")).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG]) + expect(event.get(LogStash::Event::TIMESTAMP_FAILURE_FIELD)).to eq(666) end it "should warn for invalid value" do @@ -432,8 +432,8 @@ it "should tag for invalid string format" do event = LogStash::Event.new("@timestamp" => "foo") expect(event.timestamp.to_i).to be_within(1).of Time.now.to_i - expect(event["tags"]).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG]) - expect(event[LogStash::Event::TIMESTAMP_FAILURE_FIELD]).to eq("foo") + expect(event.get("tags")).to eq([LogStash::Event::TIMESTAMP_FAILURE_TAG]) + expect(event.get(LogStash::Event::TIMESTAMP_FAILURE_FIELD)).to eq("foo") end it "should warn for invalid string format" do @@ -478,7 +478,7 @@ end it "should still allow normal field access" do - expect(subject["hello"]).to eq("world") + expect(subject.get("hello")).to eq("world") end end @@ -491,15 +491,15 @@ expect(fieldref).to start_with("[@metadata]") # Set it. - subject[fieldref] = value + subject.set(fieldref, value) end it "should still allow normal field access" do - expect(subject["normal"]).to eq("normal") + expect(subject.get("normal")).to eq("normal") end it "should allow getting" do - expect(subject[fieldref]).to eq(value) + expect(subject.get(fieldref)).to eq(value) end it "should be hidden from .to_json" do @@ -522,10 +522,10 @@ context "with no metadata" do subject { LogStash::Event.new("foo" => "bar") } it "should have no metadata" do - expect(subject["@metadata"]).to be_empty + expect(subject.get("@metadata")).to be_empty end it "should still allow normal field access" do - expect(subject["foo"]).to eq("bar") + expect(subject.get("foo")).to eq("bar") end it "should not include the @metadata key" do @@ -599,7 +599,7 @@ end it "return the string containing the timestamp, the host and the message" do - expect(event1.to_s).to eq("#{timestamp.to_iso8601} #{event1["host"]} #{event1["message"]}") + expect(event1.to_s).to eq("#{timestamp.to_iso8601} #{event1.get("host")} #{event1.get("message")}") end end @@ -607,27 +607,27 @@ let(:event) { LogStash::Event.new({ "message" => "foo" }) } it "should invalidate target caching" do - expect(event["[a][0]"]).to be_nil + expect(event.get("[a][0]")).to be_nil - expect(event["[a][0]"] = 42).to eq(42) - expect(event["[a][0]"]).to eq(42) - expect(event["[a]"]).to eq({"0" => 42}) + expect(event.set("[a][0]", 42)).to eq(42) + expect(event.get("[a][0]")).to eq(42) + expect(event.get("[a]")).to eq({"0" => 42}) - expect(event["[a]"] = [42, 24]).to eq([42, 24]) - expect(event["[a]"]).to eq([42, 24]) + expect(event.set("[a]", [42, 24])).to eq([42, 24]) + expect(event.get("[a]")).to eq([42, 24]) - expect(event["[a][0]"]).to eq(42) + expect(event.get("[a][0]")).to eq(42) - expect(event["[a]"] = [24, 42]).to eq([24, 42]) - expect(event["[a][0]"]).to eq(24) + expect(event.set("[a]", [24, 42])).to eq([24, 42]) + expect(event.get("[a][0]")).to eq(24) - expect(event["[a][0]"] = {"a "=> 99, "b" => 98}).to eq({"a "=> 99, "b" => 98}) - expect(event["[a][0]"]).to eq({"a "=> 99, "b" => 98}) + expect(event.set("[a][0]", {"a "=> 99, "b" => 98})).to eq({"a "=> 99, "b" => 98}) + expect(event.get("[a][0]")).to eq({"a "=> 99, "b" => 98}) - expect(event["[a]"]).to eq([{"a "=> 99, "b" => 98}, 42]) - expect(event["[a][0]"]).to eq({"a "=> 99, "b" => 98}) - expect(event["[a][1]"]).to eq(42) - expect(event["[a][0][b]"]).to eq(98) + expect(event.get("[a]")).to eq([{"a "=> 99, "b" => 98}, 42]) + expect(event.get("[a][0]")).to eq({"a "=> 99, "b" => 98}) + expect(event.get("[a][1]")).to eq(42) + expect(event.get("[a][0][b]")).to eq(98) end end end diff --git a/logstash-core-plugin-api/lib/logstash-core-plugin-api/version.rb b/logstash-core-plugin-api/lib/logstash-core-plugin-api/version.rb index e83d1586c2e..ced5939392b 100644 --- a/logstash-core-plugin-api/lib/logstash-core-plugin-api/version.rb +++ b/logstash-core-plugin-api/lib/logstash-core-plugin-api/version.rb @@ -1,2 +1,2 @@ # encoding: utf-8 -LOGSTASH_CORE_PLUGIN_API = "1.0.0" +LOGSTASH_CORE_PLUGIN_API = "2.0.0" diff --git a/logstash-core/lib/logstash/config/config_ast.rb b/logstash-core/lib/logstash/config/config_ast.rb index 7a583d578df..96a7ee46a85 100644 --- a/logstash-core/lib/logstash/config/config_ast.rb +++ b/logstash-core/lib/logstash/config/config_ast.rb @@ -512,7 +512,7 @@ def compile end class Selector < RValue def compile - return "event[#{text_value.inspect}]" + return "event.get(#{text_value.inspect})" end end class SelectorElement < Node; end diff --git a/logstash-core/lib/logstash/filters/base.rb b/logstash-core/lib/logstash/filters/base.rb index c666a225bf7..d97c2342d63 100644 --- a/logstash-core/lib/logstash/filters/base.rb +++ b/logstash-core/lib/logstash/filters/base.rb @@ -187,12 +187,12 @@ def filter_matched(event) # this is important because a construct like event["tags"].delete(tag) will not work # in the current Java event implementation. see https://github.com/elastic/logstash/issues/4140 @remove_tag.each do |tag| - tags = event["tags"] + tags = event.get("tags") break if tags.nil? || tags.empty? tag = event.sprintf(tag) @logger.debug? and @logger.debug("filters/#{self.class.name}: removing tag", :tag => tag) tags.delete(tag) - event["tags"] = tags + event.set("tags", tags) end end # def filter_matched diff --git a/logstash-core/lib/logstash/inputs/base.rb b/logstash-core/lib/logstash/inputs/base.rb index d02bbd567e5..cb7a25d720b 100644 --- a/logstash-core/lib/logstash/inputs/base.rb +++ b/logstash-core/lib/logstash/inputs/base.rb @@ -97,7 +97,7 @@ def stop? protected def decorate(event) # Only set 'type' if not already set. This is backwards-compatible behavior - event["type"] = @type if @type && !event.include?("type") + event.set("type", @type) if @type && !event.include?("type") LogStash::Util::Decorators.add_fields(@add_field,event,"inputs/#{self.class.name}") LogStash::Util::Decorators.add_tags(@tags,event,"inputs/#{self.class.name}") diff --git a/logstash-core/lib/logstash/util/decorators.rb b/logstash-core/lib/logstash/util/decorators.rb index 265656e5ce9..c7807e883b1 100644 --- a/logstash-core/lib/logstash/util/decorators.rb +++ b/logstash-core/lib/logstash/util/decorators.rb @@ -7,7 +7,7 @@ module LogStash::Util # Decorators provides common manipulation on the event data. module Decorators extend self - + @logger = Cabin::Channel.get(LogStash) # fields is a hash of field => value @@ -22,11 +22,11 @@ def add_fields(fields,event, pluginname) # note below that the array field needs to be updated then reassigned to the event. # this is important because a construct like event[field] << v will not work # in the current Java event implementation. see https://github.com/elastic/logstash/issues/4140 - a = Array(event[field]) + a = Array(event.get(field)) a << v - event[field] = a + event.set(field, a) else - event[field] = v + event.set(field, v) end @logger.debug? and @logger.debug("#{pluginname}: adding value to field", :field => field, :value => value) end @@ -41,9 +41,9 @@ def add_tags(tags, event, pluginname) # note below that the tags array field needs to be updated then reassigned to the event. # this is important because a construct like event["tags"] << tag will not work # in the current Java event implementation. see https://github.com/elastic/logstash/issues/4140 - tags = event["tags"] || [] + tags = event.get("tags") || [] tags << tag - event["tags"] = tags + event.set("tags", tags) end end diff --git a/logstash-core/spec/conditionals_spec.rb b/logstash-core/spec/conditionals_spec.rb index dab6fc901e3..c4c68ec4c58 100644 --- a/logstash-core/spec/conditionals_spec.rb +++ b/logstash-core/spec/conditionals_spec.rb @@ -64,24 +64,24 @@ def conditional(expression, &block) CONFIG sample({"foo" => "bar"}) do - expect(subject["always"]).to eq("awesome") - expect(subject["hello"]).to eq("world") - expect(subject["fancy"]).to be_nil - expect(subject["free"]).to be_nil + expect(subject.get("always")).to eq("awesome") + expect(subject.get("hello")).to eq("world") + expect(subject.get("fancy")).to be_nil + expect(subject.get("free")).to be_nil end sample({"notfoo" => "bar"}) do - expect(subject["always"]).to eq("awesome") - expect(subject["hello"]).to be_nil - expect(subject["fancy"]).to be_nil - expect(subject["free"]).to eq("hugs") + expect(subject.get("always")).to eq("awesome") + expect(subject.get("hello")).to be_nil + expect(subject.get("fancy")).to be_nil + expect(subject.get("free")).to eq("hugs") end sample({"bar" => "baz"}) do - expect(subject["always"]).to eq("awesome") - expect(subject["hello"]).to be_nil - expect(subject["fancy"]).to eq("pants") - expect(subject["free"]).to be_nil + expect(subject.get("always")).to eq("awesome") + expect(subject.get("hello")).to be_nil + expect(subject.get("fancy")).to eq("pants") + expect(subject.get("free")).to be_nil end end @@ -102,31 +102,31 @@ def conditional(expression, &block) CONFIG sample("foo" => "bar", "nest" => 124) do - expect(subject["always"]).to be_nil - expect(subject["hello"]).to be_nil - expect(subject["fancy"]).to be_nil - expect(subject["free"]).to be_nil + expect(subject.get("always")).to be_nil + expect(subject.get("hello")).to be_nil + expect(subject.get("fancy")).to be_nil + expect(subject.get("free")).to be_nil end sample("foo" => "bar", "nest" => 123) do - expect(subject["always"]).to eq("awesome") - expect(subject["hello"]).to eq("world") - expect(subject["fancy"]).to be_nil - expect(subject["free"]).to be_nil + expect(subject.get("always")).to eq("awesome") + expect(subject.get("hello")).to eq("world") + expect(subject.get("fancy")).to be_nil + expect(subject.get("free")).to be_nil end sample("notfoo" => "bar", "nest" => 123) do - expect(subject["always"]).to eq("awesome") - expect(subject["hello"]).to be_nil - expect(subject["fancy"]).to be_nil - expect(subject["free"]).to eq("hugs") + expect(subject.get("always")).to eq("awesome") + expect(subject.get("hello")).to be_nil + expect(subject.get("fancy")).to be_nil + expect(subject.get("free")).to eq("hugs") end sample("bar" => "baz", "nest" => 123) do - expect(subject["always"]).to eq("awesome") - expect(subject["hello"]).to be_nil - expect(subject["fancy"]).to eq("pants") - expect(subject["free"]).to be_nil + expect(subject.get("always")).to eq("awesome") + expect(subject.get("hello")).to be_nil + expect(subject.get("fancy")).to eq("pants") + expect(subject.get("free")).to be_nil end end @@ -140,7 +140,7 @@ def conditional(expression, &block) CONFIG sample("foo" => 123, "bar" => 123) do - expect(subject["tags"] ).to include("woot") + expect(subject.get("tags") ).to include("woot") end end @@ -169,12 +169,12 @@ def conditional(expression, &block) CONFIG sample("foo" => "foo", "foobar" => "foobar", "greeting" => "hello world") do - expect(subject["tags"]).to include("field in field") - expect(subject["tags"]).to include("field in string") - expect(subject["tags"]).to include("string in field") - expect(subject["tags"]).to include("field in list") - expect(subject["tags"]).not_to include("shouldnotexist") - expect(subject["tags"]).to include("shouldexist") + expect(subject.get("tags")).to include("field in field") + expect(subject.get("tags")).to include("field in string") + expect(subject.get("tags")).to include("string in field") + expect(subject.get("tags")).to include("field in list") + expect(subject.get("tags")).not_to include("shouldnotexist") + expect(subject.get("tags")).to include("shouldexist") end end @@ -192,107 +192,107 @@ def conditional(expression, &block) sample("foo" => "foo", "somelist" => [ "one", "two" ], "foobar" => "foobar", "greeting" => "hello world", "tags" => [ "fancypantsy" ]) do # verify the original exists - expect(subject["tags"]).to include("fancypantsy") + expect(subject.get("tags")).to include("fancypantsy") - expect(subject["tags"]).to include("baz") - expect(subject["tags"]).not_to include("foo") - expect(subject["tags"]).to include("notfoo") - expect(subject["tags"]).to include("notsomelist") - expect(subject["tags"]).not_to include("somelist") - expect(subject["tags"]).to include("no string in missing field") + expect(subject.get("tags")).to include("baz") + expect(subject.get("tags")).not_to include("foo") + expect(subject.get("tags")).to include("notfoo") + expect(subject.get("tags")).to include("notsomelist") + expect(subject.get("tags")).not_to include("somelist") + expect(subject.get("tags")).to include("no string in missing field") end end describe "operators" do conditional "[message] == 'sample'" do - sample("sample") { expect(subject["tags"] ).to include("success") } - sample("different") { expect(subject["tags"] ).to include("failure") } + sample("sample") { expect(subject.get("tags") ).to include("success") } + sample("different") { expect(subject.get("tags") ).to include("failure") } end conditional "[message] != 'sample'" do - sample("sample") { expect(subject["tags"] ).to include("failure") } - sample("different") { expect(subject["tags"] ).to include("success") } + sample("sample") { expect(subject.get("tags") ).to include("failure") } + sample("different") { expect(subject.get("tags") ).to include("success") } end conditional "[message] < 'sample'" do - sample("apple") { expect(subject["tags"] ).to include("success") } - sample("zebra") { expect(subject["tags"] ).to include("failure") } + sample("apple") { expect(subject.get("tags") ).to include("success") } + sample("zebra") { expect(subject.get("tags") ).to include("failure") } end conditional "[message] > 'sample'" do - sample("zebra") { expect(subject["tags"] ).to include("success") } - sample("apple") { expect(subject["tags"] ).to include("failure") } + sample("zebra") { expect(subject.get("tags") ).to include("success") } + sample("apple") { expect(subject.get("tags") ).to include("failure") } end conditional "[message] <= 'sample'" do - sample("apple") { expect(subject["tags"] ).to include("success") } - sample("zebra") { expect(subject["tags"] ).to include("failure") } - sample("sample") { expect(subject["tags"] ).to include("success") } + sample("apple") { expect(subject.get("tags") ).to include("success") } + sample("zebra") { expect(subject.get("tags") ).to include("failure") } + sample("sample") { expect(subject.get("tags") ).to include("success") } end conditional "[message] >= 'sample'" do - sample("zebra") { expect(subject["tags"] ).to include("success") } - sample("sample") { expect(subject["tags"] ).to include("success") } - sample("apple") { expect(subject["tags"] ).to include("failure") } + sample("zebra") { expect(subject.get("tags") ).to include("success") } + sample("sample") { expect(subject.get("tags") ).to include("success") } + sample("apple") { expect(subject.get("tags") ).to include("failure") } end conditional "[message] =~ /sample/" do - sample("apple") { expect(subject["tags"] ).to include("failure") } - sample("sample") { expect(subject["tags"] ).to include("success") } - sample("some sample") { expect(subject["tags"] ).to include("success") } + sample("apple") { expect(subject.get("tags") ).to include("failure") } + sample("sample") { expect(subject.get("tags") ).to include("success") } + sample("some sample") { expect(subject.get("tags") ).to include("success") } end conditional "[message] !~ /sample/" do - sample("apple") { expect(subject["tags"]).to include("success") } - sample("sample") { expect(subject["tags"]).to include("failure") } - sample("some sample") { expect(subject["tags"]).to include("failure") } + sample("apple") { expect(subject.get("tags")).to include("success") } + sample("sample") { expect(subject.get("tags")).to include("failure") } + sample("some sample") { expect(subject.get("tags")).to include("failure") } end end describe "negated expressions" do conditional "!([message] == 'sample')" do - sample("sample") { expect(subject["tags"]).not_to include("success") } - sample("different") { expect(subject["tags"]).not_to include("failure") } + sample("sample") { expect(subject.get("tags")).not_to include("success") } + sample("different") { expect(subject.get("tags")).not_to include("failure") } end conditional "!([message] != 'sample')" do - sample("sample") { expect(subject["tags"]).not_to include("failure") } - sample("different") { expect(subject["tags"]).not_to include("success") } + sample("sample") { expect(subject.get("tags")).not_to include("failure") } + sample("different") { expect(subject.get("tags")).not_to include("success") } end conditional "!([message] < 'sample')" do - sample("apple") { expect(subject["tags"]).not_to include("success") } - sample("zebra") { expect(subject["tags"]).not_to include("failure") } + sample("apple") { expect(subject.get("tags")).not_to include("success") } + sample("zebra") { expect(subject.get("tags")).not_to include("failure") } end conditional "!([message] > 'sample')" do - sample("zebra") { expect(subject["tags"]).not_to include("success") } - sample("apple") { expect(subject["tags"]).not_to include("failure") } + sample("zebra") { expect(subject.get("tags")).not_to include("success") } + sample("apple") { expect(subject.get("tags")).not_to include("failure") } end conditional "!([message] <= 'sample')" do - sample("apple") { expect(subject["tags"]).not_to include("success") } - sample("zebra") { expect(subject["tags"]).not_to include("failure") } - sample("sample") { expect(subject["tags"]).not_to include("success") } + sample("apple") { expect(subject.get("tags")).not_to include("success") } + sample("zebra") { expect(subject.get("tags")).not_to include("failure") } + sample("sample") { expect(subject.get("tags")).not_to include("success") } end conditional "!([message] >= 'sample')" do - sample("zebra") { expect(subject["tags"]).not_to include("success") } - sample("sample") { expect(subject["tags"]).not_to include("success") } - sample("apple") { expect(subject["tags"]).not_to include("failure") } + sample("zebra") { expect(subject.get("tags")).not_to include("success") } + sample("sample") { expect(subject.get("tags")).not_to include("success") } + sample("apple") { expect(subject.get("tags")).not_to include("failure") } end conditional "!([message] =~ /sample/)" do - sample("apple") { expect(subject["tags"]).not_to include("failure") } - sample("sample") { expect(subject["tags"]).not_to include("success") } - sample("some sample") { expect(subject["tags"]).not_to include("success") } + sample("apple") { expect(subject.get("tags")).not_to include("failure") } + sample("sample") { expect(subject.get("tags")).not_to include("success") } + sample("some sample") { expect(subject.get("tags")).not_to include("success") } end conditional "!([message] !~ /sample/)" do - sample("apple") { expect(subject["tags"]).not_to include("success") } - sample("sample") { expect(subject["tags"]).not_to include("failure") } - sample("some sample") { expect(subject["tags"]).not_to include("failure") } + sample("apple") { expect(subject.get("tags")).not_to include("success") } + sample("sample") { expect(subject.get("tags")).not_to include("failure") } + sample("some sample") { expect(subject.get("tags")).not_to include("failure") } end end @@ -300,47 +300,47 @@ def conditional(expression, &block) describe "value as an expression" do # testing that a field has a value should be true. conditional "[message]" do - sample("apple") { expect(subject["tags"]).to include("success") } - sample("sample") { expect(subject["tags"]).to include("success") } - sample("some sample") { expect(subject["tags"]).to include("success") } + sample("apple") { expect(subject.get("tags")).to include("success") } + sample("sample") { expect(subject.get("tags")).to include("success") } + sample("some sample") { expect(subject.get("tags")).to include("success") } end # testing that a missing field has a value should be false. conditional "[missing]" do - sample("apple") { expect(subject["tags"]).to include("failure") } - sample("sample") { expect(subject["tags"]).to include("failure") } - sample("some sample") { expect(subject["tags"]).to include("failure") } + sample("apple") { expect(subject.get("tags")).to include("failure") } + sample("sample") { expect(subject.get("tags")).to include("failure") } + sample("some sample") { expect(subject.get("tags")).to include("failure") } end end describe "logic operators" do describe "and" do conditional "[message] and [message]" do - sample("whatever") { expect(subject["tags"]).to include("success") } + sample("whatever") { expect(subject.get("tags")).to include("success") } end conditional "[message] and ![message]" do - sample("whatever") { expect(subject["tags"]).to include("failure") } + sample("whatever") { expect(subject.get("tags")).to include("failure") } end conditional "![message] and [message]" do - sample("whatever") { expect(subject["tags"]).to include("failure") } + sample("whatever") { expect(subject.get("tags")).to include("failure") } end conditional "![message] and ![message]" do - sample("whatever") { expect(subject["tags"]).to include("failure") } + sample("whatever") { expect(subject.get("tags")).to include("failure") } end end describe "or" do conditional "[message] or [message]" do - sample("whatever") { expect(subject["tags"]).to include("success") } + sample("whatever") { expect(subject.get("tags")).to include("success") } end conditional "[message] or ![message]" do - sample("whatever") { expect(subject["tags"]).to include("success") } + sample("whatever") { expect(subject.get("tags")).to include("success") } end conditional "![message] or [message]" do - sample("whatever") { expect(subject["tags"]).to include("success") } + sample("whatever") { expect(subject.get("tags")).to include("success") } end conditional "![message] or ![message]" do - sample("whatever") { expect(subject["tags"]).to include("failure") } + sample("whatever") { expect(subject.get("tags")).to include("failure") } end end end @@ -348,19 +348,19 @@ def conditional(expression, &block) describe "field references" do conditional "[field with space]" do sample("field with space" => "hurray") do - expect(subject["tags"]).to include("success") + expect(subject.get("tags")).to include("success") end end conditional "[field with space] == 'hurray'" do sample("field with space" => "hurray") do - expect(subject["tags"]).to include("success") + expect(subject.get("tags")).to include("success") end end conditional "[nested field][reference with][some spaces] == 'hurray'" do sample({"nested field" => { "reference with" => { "some spaces" => "hurray" } } }) do - expect(subject["tags"]).to include("success") + expect(subject.get("tags")).to include("success") end end end @@ -385,13 +385,13 @@ def conditional(expression, &block) expect(subject).to be_an(Array) expect(subject.length).to eq(2) - expect(subject[0]["type"]).to eq("original") - expect(subject[0]["cond1"]).to eq("true") - expect(subject[0]["cond2"]).to eq(nil) + expect(subject[0].get("type")).to eq("original") + expect(subject[0].get("cond1")).to eq("true") + expect(subject[0].get("cond2")).to eq(nil) - expect(subject[1]["type"]).to eq("clone") - # expect(subject[1]["cond1"]).to eq(nil) - # expect(subject[1]["cond2"]).to eq("true") + expect(subject[1].get("type")).to eq("clone") + # expect(subject[1].get("cond1")).to eq(nil) + # expect(subject[1].get("cond2")).to eq("true") end end @@ -413,16 +413,16 @@ def conditional(expression, &block) sample({"type" => "original"}) do # puts subject.inspect - expect(subject[0]["cond1"]).to eq(nil) - expect(subject[0]["cond2"]).to eq(nil) + expect(subject[0].get("cond1")).to eq(nil) + expect(subject[0].get("cond2")).to eq(nil) - expect(subject[1]["type"]).to eq("clone1") - expect(subject[1]["cond1"]).to eq("true") - expect(subject[1]["cond2"]).to eq(nil) + expect(subject[1].get("type")).to eq("clone1") + expect(subject[1].get("cond1")).to eq("true") + expect(subject[1].get("cond2")).to eq(nil) - expect(subject[2]["type"]).to eq("clone2") - expect(subject[2]["cond1"]).to eq(nil) - expect(subject[2]["cond2"]).to eq("true") + expect(subject[2].get("type")).to eq("clone2") + expect(subject[2].get("cond1")).to eq(nil) + expect(subject[2].get("cond2")).to eq("true") end end diff --git a/logstash-core/spec/logstash/filters/base_spec.rb b/logstash-core/spec/logstash/filters/base_spec.rb index 177c44dcb8c..26c5d6c5438 100644 --- a/logstash-core/spec/logstash/filters/base_spec.rb +++ b/logstash-core/spec/logstash/filters/base_spec.rb @@ -62,7 +62,7 @@ def filter(event) CONFIG sample "example" do - insist { subject["new_field"] } == ["new_value", "new_value_2"] + insist { subject.get("new_field") } == ["new_value", "new_value_2"] end end @@ -76,7 +76,7 @@ def filter(event) CONFIG sample("type" => "noop") do - insist { subject["tags"] } == ["test"] + insist { subject.get("tags") } == ["test"] end end @@ -90,11 +90,11 @@ def filter(event) CONFIG sample("type" => "noop") do - insist { subject["tags"] } == ["test"] + insist { subject.get("tags") } == ["test"] end sample("type" => "noop", "tags" => ["t1", "t2"]) do - insist { subject["tags"] } == ["t1", "t2", "test"] + insist { subject.get("tags") } == ["t1", "t2", "test"] end end @@ -108,19 +108,19 @@ def filter(event) CONFIG sample("type" => "noop") do - insist { subject["tags"] } == ["test"] + insist { subject.get("tags") } == ["test"] end sample("type" => "noop", "tags" => ["t1"]) do - insist { subject["tags"] } == ["t1", "test"] + insist { subject.get("tags") } == ["t1", "test"] end sample("type" => "noop", "tags" => ["t1", "t2"]) do - insist { subject["tags"] } == ["t1", "t2", "test"] + insist { subject.get("tags") } == ["t1", "t2", "test"] end sample("type" => "noop", "tags" => ["t1", "t2", "t3"]) do - insist { subject["tags"] } == ["t1", "t2", "t3", "test"] + insist { subject.get("tags") } == ["t1", "t2", "t3", "test"] end end @@ -134,27 +134,27 @@ def filter(event) CONFIG sample("type" => "noop", "tags" => ["t4"]) do - insist { subject["tags"] } == ["t4"] + insist { subject.get("tags") } == ["t4"] end sample("type" => "noop", "tags" => ["t1", "t2", "t3"]) do - insist { subject["tags"] } == ["t1"] + insist { subject.get("tags") } == ["t1"] end # also test from Json deserialized data to test the handling of native Java collections by JrJackson # see https://github.com/elastic/logstash/issues/2261 sample(LogStash::Json.load("{\"type\":\"noop\", \"tags\":[\"t1\", \"t2\", \"t3\"]}")) do - insist { subject["tags"] } == ["t1"] + insist { subject.get("tags") } == ["t1"] end sample("type" => "noop", "tags" => ["t1", "t2"]) do - insist { subject["tags"] } == ["t1"] + insist { subject.get("tags") } == ["t1"] end # also test from Json deserialized data to test the handling of native Java collections by JrJackson # see https://github.com/elastic/logstash/issues/2261 sample(LogStash::Json.load("{\"type\":\"noop\", \"tags\":[\"t1\", \"t2\"]}")) do - insist { subject["tags"] } == ["t1"] + insist { subject.get("tags") } == ["t1"] end end @@ -168,13 +168,13 @@ def filter(event) CONFIG sample("type" => "noop", "tags" => ["t1", "goaway", "t3"], "blackhole" => "goaway") do - insist { subject["tags"] } == ["t1", "t3"] + insist { subject.get("tags") } == ["t1", "t3"] end # also test from Json deserialized data to test the handling of native Java collections by JrJackson # see https://github.com/elastic/logstash/issues/2261 sample(LogStash::Json.load("{\"type\":\"noop\", \"tags\":[\"t1\", \"goaway\", \"t3\"], \"blackhole\":\"goaway\"}")) do - insist { subject["tags"] } == ["t1", "t3"] + insist { subject.get("tags") } == ["t1", "t3"] end end @@ -230,7 +230,7 @@ def filter(event) sample("type" => "noop", "t1" => ["t2", "t3"]) do insist { subject }.include?("t1") - insist { subject["[t1][0]"] } == "t3" + insist { subject.get("[t1][0]") } == "t3" end end diff --git a/logstash-core/spec/logstash/inputs/base_spec.rb b/logstash-core/spec/logstash/inputs/base_spec.rb index d87f07b49f6..a3f01fa89e1 100644 --- a/logstash-core/spec/logstash/inputs/base_spec.rb +++ b/logstash-core/spec/logstash/inputs/base_spec.rb @@ -15,50 +15,50 @@ def register; end input = LogStash::Inputs::NOOP.new("tags" => "value") evt = LogStash::Event.new({"type" => "noop"}) input.instance_eval {decorate(evt)} - expect(evt["tags"]).to eq(["value"]) + expect(evt.get("tags")).to eq(["value"]) end it "should add multiple tag" do input = LogStash::Inputs::NOOP.new("tags" => ["value1","value2"]) evt = LogStash::Event.new({"type" => "noop"}) input.instance_eval {decorate(evt)} - expect(evt["tags"]).to eq(["value1","value2"]) + expect(evt.get("tags")).to eq(["value1","value2"]) end it "should allow duplicates tag" do input = LogStash::Inputs::NOOP.new("tags" => ["value","value"]) evt = LogStash::Event.new({"type" => "noop"}) input.instance_eval {decorate(evt)} - expect(evt["tags"]).to eq(["value","value"]) + expect(evt.get("tags")).to eq(["value","value"]) end it "should add tag with sprintf" do input = LogStash::Inputs::NOOP.new("tags" => "%{type}") evt = LogStash::Event.new({"type" => "noop"}) input.instance_eval {decorate(evt)} - expect(evt["tags"]).to eq(["noop"]) + expect(evt.get("tags")).to eq(["noop"]) end it "should add single field" do input = LogStash::Inputs::NOOP.new("add_field" => {"field" => "value"}) evt = LogStash::Event.new({"type" => "noop"}) input.instance_eval {decorate(evt)} - expect(evt["field"]).to eq("value") + expect(evt.get("field")).to eq("value") end it "should add single field with sprintf" do input = LogStash::Inputs::NOOP.new("add_field" => {"%{type}" => "%{type}"}) evt = LogStash::Event.new({"type" => "noop"}) input.instance_eval {decorate(evt)} - expect(evt["noop"]).to eq("noop") + expect(evt.get("noop")).to eq("noop") end it "should add multiple field" do input = LogStash::Inputs::NOOP.new("add_field" => {"field" => ["value1", "value2"], "field2" => "value"}) evt = LogStash::Event.new({"type" => "noop"}) input.instance_eval {decorate(evt)} - expect(evt["field"]).to eq(["value1","value2"]) - expect(evt["field2"]).to eq("value") + expect(evt.get("field")).to eq(["value1","value2"]) + expect(evt.get("field2")).to eq("value") end end diff --git a/logstash-core/spec/logstash/pipeline_spec.rb b/logstash-core/spec/logstash/pipeline_spec.rb index f7ef5c36221..e17ddff719c 100644 --- a/logstash-core/spec/logstash/pipeline_spec.rb +++ b/logstash-core/spec/logstash/pipeline_spec.rb @@ -279,7 +279,7 @@ class TestPipeline < LogStash::Pipeline CONFIG sample("hello") do - expect(subject["message"]).to eq("hello") + expect(subject.get("message")).to eq("hello") end end @@ -299,10 +299,10 @@ class TestPipeline < LogStash::Pipeline sample(["foo", "bar"]) do expect(subject.size).to eq(2) - expect(subject[0]["message"]).to eq("foo\nbar") - expect(subject[0]["type"]).to be_nil - expect(subject[1]["message"]).to eq("foo\nbar") - expect(subject[1]["type"]).to eq("clone1") + expect(subject[0].get("message")).to eq("foo\nbar") + expect(subject[0].get("type")).to be_nil + expect(subject[1].get("message")).to eq("foo\nbar") + expect(subject[1].get("type")).to eq("clone1") end end end @@ -354,17 +354,17 @@ class TestPipeline < LogStash::Pipeline sample("hello") do expect(subject.size).to eq(3) - expect(subject[0]["message"]).to eq("hello") - expect(subject[0]["type"]).to be_nil - expect(subject[0]["foo"]).to eq("bar") + expect(subject[0].get("message")).to eq("hello") + expect(subject[0].get("type")).to be_nil + expect(subject[0].get("foo")).to eq("bar") - expect(subject[1]["message"]).to eq("hello") - expect(subject[1]["type"]).to eq("clone1") - expect(subject[1]["foo"]).to eq("bar") + expect(subject[1].get("message")).to eq("hello") + expect(subject[1].get("type")).to eq("clone1") + expect(subject[1].get("foo")).to eq("bar") - expect(subject[2]["message"]).to eq("hello") - expect(subject[2]["type"]).to eq("clone2") - expect(subject[2]["foo"]).to eq("bar") + expect(subject[2].get("message")).to eq("hello") + expect(subject[2].get("type")).to eq("clone2") + expect(subject[2].get("foo")).to eq("bar") end end end @@ -441,7 +441,7 @@ class TestPipeline < LogStash::Pipeline # give us a bit of time to flush the events wait(5).for do next unless output && output.events && output.events.first - output.events.first["message"].split("\n").count + output.events.first.get("message").split("\n").count end.to eq(number_of_events) pipeline.shutdown end