Ruby 过滤器插件

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

其他版本,请参见 版本化插件文档

获取帮助

编辑

如有任何关于插件的问题,请在 Discuss 论坛中发帖提问。对于 Bug 或功能请求,请在 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 中的文本字符串内进行结构化,因此最好使用 path 选项将 Ruby 代码放在 .rb 文件中。

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

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

  • register(params):一个可选的 register 方法,它接收在 script_params 配置选项中传递的键/值哈希
  • filter(event):一个必须的方法,它接受一个 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 变量,该变量就是事件本身。有关更多信息,请参见 Event API

init

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

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

path

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

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

script_params

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

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

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 字段中的变量替换仅支持环境变量,不支持使用密钥存储中的值。

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。第二个示例还将删除一个令人不快的、不需要的标签。