Ruby 过滤器插件

编辑
  • 插件版本:v3.1.8
  • 发布日期:2022-01-24
  • 更新日志

对于其他版本,请参阅版本化插件文档

获取帮助

编辑

有关插件的问题,请在Discuss论坛中开一个主题。对于错误或功能请求,请在Github中打开一个 issue。有关 Elastic 支持的插件列表,请查阅Elastic 支持矩阵

描述

编辑

执行 Ruby 代码。此过滤器接受内联 Ruby 代码或 Ruby 文件。这两个选项是互斥的,并且工作方式略有不同,将在下面进行描述。

此插件的并发安全性取决于您的代码。请务必阅读如何避免并发问题

使用内联 Ruby 代码

编辑

要在过滤器中添加内联 Ruby 代码,请将所有代码放在 code 选项中。此代码将针对过滤器接收的每个事件执行。您也可以将 Ruby 代码放在 init 选项中。它只会在插件的注册阶段执行一次。

例如,要取消 90% 的事件,您可以这样做

    filter {
      ruby {
        # Cancel 90% of events
        code => "event.cancel if rand <= 0.90"
      }
    }

如果您需要创建其他事件,则必须使用特定的语法 new_event_block.call(event),如下例所示,复制输入事件

filter {
  ruby {
    code => "new_event_block.call(event.clone)"
  }
}

code 选项中定义方法会显著降低吞吐量。请改用 init 选项

使用 Ruby 脚本文件

编辑

由于内联代码在 code 中的文本字符串内可能会变得复杂且难以组织,因此最好将 Ruby 代码放在 .rb 文件中,使用 path 选项。

    filter {
      ruby {
        # Cancel 90% of events
        path => "/etc/logstash/drop_percentage.rb"
        script_params => { "percentage" => 0.9 }
      }
    }

Ruby 脚本文件应定义以下方法

  • register(params):一个可选的注册方法,接收在 script_params 配置选项中传递的键/值哈希
  • filter(event):一个强制的 Ruby 方法,它接受一个 Logstash 事件,并且必须返回一个事件数组

下面是一个 drop_percentage.rb Ruby 脚本的示例实现,该脚本会丢弃可配置百分比的事件

# the value of `params` is the value of the hash passed to `script_params`
# in the logstash configuration
def register(params)
	@drop_percentage = params["percentage"]
end

# the filter method receives an event and must return a list of events.
# Dropping an event means not including it in the return array,
# while creating new ones only requires you to add a new instance of
# LogStash::Event to the returned array
def filter(event)
	if rand >= @drop_percentage
		return [event]
	else
		return [] # return empty array to cancel event
	end
end

测试 Ruby 脚本

编辑

为了验证您实现的 filter 方法的行为,Ruby 过滤器插件提供了一个内联测试框架,您可以在其中断言期望。您定义的测试将在创建管道时运行,如果测试失败,将阻止管道启动。

您还可以使用 logstash -t 标志来验证测试是否通过。

例如,在上面,您可以在 drop_percentage.rb Ruby 脚本的底部编写以下测试

def register(params)
  # ..
end

def filter(event)
  # ..
end

test "drop percentage 100%" do
  parameters do
    { "percentage" => 1 }
  end

  in_event { { "message" => "hello" } }

  expect("drops the event") do |events|
    events.size == 0
  end
end

我们现在可以测试我们正在使用的 Ruby 脚本是否已正确实现

% bin/logstash -e "filter { ruby { path => '/etc/logstash/drop_percentage.rb' script_params => { 'drop_percentage' => 0.5 } } }" -t
[2017-10-13T13:44:29,723][INFO ][logstash.filters.ruby.script] Test run complete {:script_path=>"/etc/logstash/drop_percentage.rb", :results=>{:passed=>1, :failed=>0, :errored=>0}}
Configuration OK
[2017-10-13T13:44:29,887][INFO ][logstash.runner          ] Using config.test_and_exit mode. Config Validation Result: OK. Exiting Logstash

避免并发问题

编辑

当事件流经具有多个工作线程的管道时,此过滤器的单个共享实例可能会同时处理多个事件。这意味着您的脚本需要编写为避免修改共享状态,除非以线程安全的方式进行。

在 Ruby 中,变量的名称决定了其作用域。以下指导可能有助于您避免意外修改共享状态

  • 可以随意使用局部变量,其名称以小写字母或下划线 (_) 开头。

    • 局部变量仅对正在处理的单个事件可用,并且会自动清理。
  • 修改实例变量时要小心,其名称以 @ 开头,后跟小写字母或下划线 (_)。

    • 实例变量在此管道中的所有工作线程之间共享,这些线程可能同时处理多个事件。
    • 脚本定义的 register 函数中或使用init 设置实例变量是安全的,但不应在处理事件时修改它们,除非受互斥的保护。
    • 实例变量不会在管道重启或插件崩溃时持久化。
  • 避免使用作用域不限于插件实例的变量,因为它们会导致难以调试的问题,这些问题会超出单个插件或管道的范围

    • 类变量:以 @@ 开头。
    • 全局变量:以 $ 开头。
    • 常量:以大写字母开头。

Ruby 过滤器配置选项

编辑

此插件支持以下配置选项以及稍后描述的通用选项

设置 输入类型 必需

code

字符串

init

字符串

path

字符串

script_params

哈希,{}

tag_on_exception

字符串,_rubyexception

tag_with_exception_message

布尔值,_false

另请参阅通用选项,了解所有过滤器插件支持的选项列表。

 

code

编辑
  • 值类型为字符串
  • 此设置没有默认值。
  • 此设置不能与 path 一起使用。

为每个事件执行的代码。您将有一个可用的 event 变量,它是事件本身。有关更多信息,请参阅事件 API

init

编辑
  • 值类型为字符串
  • 此设置没有默认值。

在 Logstash 启动时执行的任何代码

path

编辑
  • 值类型为字符串
  • 此设置没有默认值。
  • 此设置不能与 code 一起使用。

实现 filter 方法的 Ruby 脚本文件的路径。

script_params

编辑
  • 值类型为哈希
  • 默认值为 {}

一个键/值哈希,其中包含传递给 path 中定义的 Ruby 脚本文件的注册方法的参数。

tag_on_exception

编辑
  • 值类型为字符串
  • 默认值为 _rubyexception

如果 Ruby 代码(内联或基于文件)导致异常,则添加到事件的标记。

tag_with_exception_message

编辑

如果为 true,则向事件添加一个标记,该标记是 tag_with_exception_message 和异常消息的串联。

通用选项

编辑

所有过滤器插件都支持这些配置选项

add_field

编辑
  • 值类型为哈希
  • 默认值为 {}

如果此过滤器成功,则向此事件添加任何任意字段。字段名称可以是动态的,并使用 %{field} 包含事件的部分内容。

示例

    filter {
      ruby {
        add_field => { "foo_%{somefield}" => "Hello world, from %{host}" }
      }
    }
    # You can also add multiple fields at once:
    filter {
      ruby {
        add_field => {
          "foo_%{somefield}" => "Hello world, from %{host}"
          "new_field" => "new_static_value"
        }
      }
    }

如果事件具有字段 "somefield" == "hello",则此过滤器在成功时会添加字段 foo_hello(如果存在),其中包含以上值,并且 %{host} 部分替换为事件中的该值。第二个示例还会添加一个硬编码字段。

add_tag

编辑
  • 值类型为数组
  • 默认值为 []

如果此过滤器成功,则向事件添加任意标记。标记可以是动态的,并使用 %{field} 语法包含事件的部分内容。

示例

    filter {
      ruby {
        add_tag => [ "foo_%{somefield}" ]
      }
    }
    # You can also add multiple tags at once:
    filter {
      ruby {
        add_tag => [ "foo_%{somefield}", "taggedy_tag"]
      }
    }

如果事件具有字段 "somefield" == "hello",则此过滤器在成功时会添加一个标记 foo_hello(第二个示例当然会添加一个 taggedy_tag 标记)。

enable_metric

编辑

禁用或启用此特定插件实例的指标日志记录。默认情况下,我们记录所有可以记录的指标,但您可以禁用特定插件的指标收集。

  • 值类型为字符串
  • 此设置没有默认值。

为插件配置添加一个唯一的 ID。如果未指定 ID,Logstash 将生成一个。强烈建议在配置中设置此 ID。当您有两个或多个相同类型的插件时,这尤其有用,例如,如果您有 2 个 ruby 过滤器。在这种情况下,添加一个命名的 ID 将在使用监控 API 时帮助监控 Logstash。

    filter {
      ruby {
        id => "ABC"
      }
    }

id 字段中的变量替换仅支持环境变量,不支持使用 secret store 中的值。

periodic_flush

编辑

以固定的时间间隔调用过滤器刷新方法。可选。

remove_field

编辑
  • 值类型为数组
  • 默认值为 []

如果此过滤器成功,则从此事件中删除任意字段。字段名称可以是动态的,并使用 %{field} 示例包含事件的部分内容

    filter {
      ruby {
        remove_field => [ "foo_%{somefield}" ]
      }
    }
    # You can also remove multiple fields at once:
    filter {
      ruby {
        remove_field => [ "foo_%{somefield}", "my_extraneous_field" ]
      }
    }

如果事件具有字段 "somefield" == "hello",则此过滤器在成功后,如果存在,将删除名为 foo_hello 的字段。第二个示例将删除一个额外的非动态字段。

remove_tag

编辑
  • 值类型为数组
  • 默认值为 []

如果此过滤器成功,则从此事件中删除任意标签。标签可以是动态的,并使用 %{field} 语法包含事件的部分内容。

示例

    filter {
      ruby {
        remove_tag => [ "foo_%{somefield}" ]
      }
    }
    # You can also remove multiple tags at once:
    filter {
      ruby {
        remove_tag => [ "foo_%{somefield}", "sad_unwanted_tag"]
      }
    }

如果事件具有字段 "somefield" == "hello",则此过滤器在成功后,如果存在,将删除标签 foo_hello。第二个示例也将删除一个悲伤且不需要的标签。