From 098f48e756deefd6d16df01c35dd87debc673db5 Mon Sep 17 00:00:00 2001 From: Philippe Weber Date: Thu, 2 Jun 2016 20:24:05 +0200 Subject: [PATCH] Allow to 'yield' events (#10) * allow to 'yield' events * fix spec to new plugin api --- lib/logstash/filters/ruby.rb | 17 +++++++++++++---- spec/filters/ruby_spec.rb | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/lib/logstash/filters/ruby.rb b/lib/logstash/filters/ruby.rb index b56aad1..beda40c 100644 --- a/lib/logstash/filters/ruby.rb +++ b/lib/logstash/filters/ruby.rb @@ -13,6 +13,15 @@ # } # } # +# If you need to create additional events, it cannot be done as in other filters where you would use `yield`, +# you must use a specific syntax `new_event_block.call(event)` like in this example duplicating the input event +# [source,ruby] +# filter { +# ruby { +# code => "new_event_block.call(event.clone)" +# } +# } +# class LogStash::Filters::Ruby < LogStash::Filters::Base config_name "ruby" @@ -26,12 +35,12 @@ class LogStash::Filters::Ruby < LogStash::Filters::Base def register # TODO(sissel): Compile the ruby code eval(@init, binding, "(ruby filter init)") if @init - eval("@codeblock = lambda { |event| #{@code} }", binding, "(ruby filter code)") - end + eval("@codeblock = lambda { |event, &new_event_block| #{@code} }", binding, "(ruby filter code)") + end # def register - def filter(event) + def filter(event,&block) begin - @codeblock.call(event) + @codeblock.call(event,&block) filter_matched(event) rescue Exception => e @logger.error("Ruby exception occurred: #{e}") diff --git a/spec/filters/ruby_spec.rb b/spec/filters/ruby_spec.rb index 08d75ea..c8c8d27 100644 --- a/spec/filters/ruby_spec.rb +++ b/spec/filters/ruby_spec.rb @@ -85,5 +85,37 @@ end end + describe "allow to create new event inside the ruby filter" do + config <<-CONFIG + filter { + ruby { + code => "new_event_block.call(event.clone)" + } + } + CONFIG + + sample("message" => "hello world", "mydate" => "2014-09-23T00:00:00-0800") do + expect(subject).to be_a Array + expect(subject[0]).not_to eq(subject[1]) + expect(subject[0].to_hash).to eq(subject[1].to_hash) + end + end + + describe "allow to replace event by another one" do + config <<-CONFIG + filter { + ruby { + code => "new_event_block.call(event.clone); + event.cancel;" + add_tag => ["ok"] + } + } + CONFIG + + sample("message" => "hello world", "mydate" => "2014-09-23T00:00:00-0800") do + expect(subject.get("message")).to eq("hello world"); + expect(subject.get("mydate")).to eq("2014-09-23T00:00:00-0800"); + end + end end