Skip to content

Instantly share code, notes, and snippets.

@yaauie
Created May 3, 2018 18:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yaauie/7e994b10ff538e18c3a363645fedf137 to your computer and use it in GitHub Desktop.
Save yaauie/7e994b10ff538e18c3a363645fedf137 to your computer and use it in GitHub Desktop.
# Copyright 2018 Ry Biesemeyer (@yaauie)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# USAGE:
#
# This ruby script can be used as the source of a [Ruby Filter Plugin[] for
# extracting pattern matches from a String field on an Event.
#
# For example, to extract `ORA-12345` and `ORA-67890` from an event whose
# `message` is `ORA-12345: some text ORA-67890: some other text`, and to
# put all matches into the field `ora`, you would do the following:
#
# ~~~
# filter {
# ruby {
# path => "capture-filter.rb"
# script_params => {
# "pattern"=> "ORA-[0-9]+"
# "source" => "message"
# "target" => "ora"
# }
# }
# }
# ~~~
#
def register(params)
params = params.dup
pattern = params.delete('pattern') || report_configuration_error('required script parameter `pattern` missing')
@pattern = Regexp.new(pattern)
@source = params.delete("source") || report_configuration_error('required script parameter `source` missing')
@target = params.delete("target") || report_configuration_error('required script parameter `target` missing')
params.empty? || report_configuration_error("unknown script parameter(s): #{params.keys}")
end
def filter(event)
source = event.get(@source)
return if source.nil?
captured = source.scan(@pattern)
return if captured.nil? || captured.empty?
event.set(@target, captured)
rescue => e
logger.warn("caught exception in capture script", exception: e.message, backtrace: e.backtrace)
event.tag("_capturefailure")
ensure
return [event]
end
def report_configuration_error(message)
raise LogStash::ConfigurationError, message
end
test 'null value source' do
parameters do
{
"source" => "message",
"target" => "extracted",
"pattern" => "[A-Z]{3,}-[0-9]+"
}
end
in_event do
{ "not_message" => "foo" }
end
expect("extracted") do |events|
event = events.first
next false if event.include?("extracted")
event_tags = event.get("tags") || []
!event_tags.include?("_capturefailure")
end
end
test 'no matches in source' do
parameters do
{
"source" => "message",
"target" => "extracted",
"pattern" => "[A-Z]{3,}-[0-9]+"
}
end
in_event do
{ "message" => "foo" }
end
expect("extracted") do |events|
event = events.first
next false if event.include?("extracted")
event_tags = event.get("tags") || []
!event_tags.include?("_capturefailure")
end
end
test 'single match in source' do
parameters do
{
"source" => "message",
"target" => "extracted",
"pattern" => "[A-Z]{3,}-[0-9]+"
}
end
in_event do
{ "message" => "text ABC-123: some more text" }
end
expect("extracted") do |events|
event = events.first
event.include?("extracted") && event.get("extracted") == ["ABC-123"]
end
end
test 'multiple matches in source' do
parameters do
{
"source" => "message",
"target" => "extracted",
"pattern" => "[A-Z]{3,}-[0-9]+"
}
end
in_event do
{ "message" => "text ABC-123: some more text and DEF-7890: even more" }
end
expect("extracted") do |events|
event = events.first
event.include?("extracted") && event.get("extracted") == ["ABC-123","DEF-7890"]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment