正在加载

如何编写 Logstash 过滤器插件

要为 Logstash 开发新过滤器,请构建一个独立的 Ruby gem,其源代码位于其自己的 GitHub 存储库中。 然后,Ruby gem 可以在 RubyGems.org 上托管和共享。 您可以使用示例过滤器实现作为起点。(如果您不熟悉 Ruby,可以在 https://ruby-lang.org.cn/en/documentation/quickstart/ 找到一个出色的快速入门指南。)

让我们逐步创建使用 示例过滤器插件 的过滤器插件。

每个 Logstash 插件都位于其自己的 GitHub 存储库中。 要为您的插件创建一个新的存储库

  1. 登录到 GitHub。

  2. 单击存储库选项卡。 您将看到您已派生或贡献的其他存储库的列表。

  3. 单击右上角的绿色新建按钮。

  4. 为您的新存储库指定以下设置

    • 存储库名称 — 具有 logstash-filter-pluginname 形式的唯一名称。
    • 公共或私有 — 您的选择,但如果您想将其作为官方插件提交,则存储库必须为公共。
    • 使用 README 初始化此存储库 — 使您能够立即将存储库克隆到您的计算机。
  5. 单击创建存储库

您可以在几秒钟内创建自己的 Logstash 插件! bin/logstash-plugingenerate 子命令使用模板化文件为新的 Logstash 插件创建基础。 它创建正确的目录结构、gemspec 文件和依赖项,以便您可以开始添加自定义代码来使用 Logstash 处理数据。

有关更多信息,请参见 生成插件

或者,您可以使用我们在 github.com 上托管的示例存储库

  1. 克隆您的插件。GITUSERNAME 替换为您的 github 用户名,并将 MYPLUGINNAME 替换为您的插件名称。

    • git clone https://github.com/GITUSERNAME/logstash-``filter-MYPLUGINNAME.git

      • 或者,通过 ssh:git clone git@github.com:GITUSERNAME/logstash``-filter-MYPLUGINNAME.git
    • cd logstash-filter-MYPLUGINNAME

  2. 克隆过滤器插件示例并将其复制到您的插件分支。

    您不想包含示例 .git 目录或其内容,因此在复制示例之前将其删除。

    • cd /tmp
    • git clone https://github.com/logstash-plugins/logstash``-filter-example.git
    • cd logstash-filter-example
    • rm -rf .git
    • cp -R * /path/to/logstash-filter-mypluginname/
  3. 重命名以下文件以匹配您的插件的名称。

    • logstash-filter-example.gemspec

    • example.rb

    • example_spec.rb

      cd /path/to/logstash-filter-mypluginname
      mv logstash-filter-example.gemspec logstash-filter-mypluginname.gemspec
      mv lib/logstash/filters/example.rb lib/logstash/filters/mypluginname.rb
      mv spec/filters/example_spec.rb spec/filters/mypluginname_spec.rb
      

您的文件结构应如下所示

$ tree logstash-filter-mypluginname
├── Gemfile
├── LICENSE
├── README.md
├── Rakefile
├── lib
│   └── logstash
│       └── filters
│           └── mypluginname.rb
├── logstash-filter-mypluginname.gemspec
└── spec
    └── filters
        └── mypluginname_spec.rb

有关 Ruby gem 文件结构的更多信息以及 Ruby gem 创建过程的出色演练,请参见 http://timelessrepo.com/making-ruby-gems

在我们深入了解细节之前,请在您喜欢的文本编辑器中打开插件文件并查看一下。

require "logstash/filters/base"
require "logstash/namespace"

# Add any asciidoc formatted documentation here
# This example filter will replace the contents of the default
# message field with whatever you specify in the configuration.
#
# It is only intended to be used as an example.
class LogStash::Filters::Example < LogStash::Filters::Base

  # Setting the config_name here is required. This is how you
  # configure this filter from your Logstash config.
  #
  # filter {
  #   example { message => "My message..." }
  # }
  config_name "example"

  # Replace the message with this value.
  config :message, :validate => :string, :default => "Hello World!"


  public
  def register
    # Add instance variables
  end

  public
  def filter(event)

    if @message
      # Replace the event message with our message as configured in the
      # config file.
      event.set("message", @message)
    end

    # filter_matched should go in the last line of our successful code
    filter_matched(event)
  end

end
  1. def register
  2. def filter
  3. class LogStash::Filters::Example

现在,让我们逐行查看示例插件。

Logstash 过滤器插件需要 logstash/filters/base 和 logstash/namespace 中定义的父类

require "logstash/filters/base"
require "logstash/namespace"

当然,您构建的插件可能依赖于其他代码,甚至 gem。 只需将它们与这些 Logstash 依赖项一起放在此处即可。

让我们来看一下插件的各种元素。

过滤器插件类应该是 LogStash::Filters::Base 的子类

class LogStash::Filters::Example < LogStash::Filters::Base

类名应与插件名称紧密对应,例如

LogStash::Filters::Example
config_name "example"

这是您的插件在过滤器配置块中调用的名称。

如果在您的插件代码中设置 config_name "example",则相应的 Logstash 配置块应如下所示

config :variable_name, :validate => :variable_type, :default => "Default value", :required => boolean, :deprecated => boolean, :obsolete => string

配置或 config 部分允许您定义尽可能多(或尽可能少)的参数,以使 Logstash 能够处理事件。

有几个配置属性

  • :validate - 允许您强制将特定数据类型传递给 Logstash 以进行此配置选项,例如 :string:password:boolean:number:array:hash:path(文件系统路径)、uri:codec(自 1.2.0 起)、:bytes。 请注意,这也可以用作强制,因为如果我为布尔值指定“true”(即使从技术上讲是一个字符串),它将在配置中变为有效的布尔值。 这种强制也适用于 :number 类型,其中“1.2”变为浮点数,“22”变为整数。
  • :default - 允许您为参数指定默认值
  • :required - 此参数是否为必需(布尔值 true
  • :list - 此值是否应为值列表。 将对列表成员进行类型检查,并将标量转换为单元素列表。 请注意,这主要消除了数组类型,但如果您需要复杂对象的列表,则更适合使用此类型。 false)
  • :deprecated - 信息性的(也是布尔值 truefalse
  • :obsolete - 用于声明已删除给定的设置且不再起作用。 这样做的目的是为仍在尝试使用现已删除的设置的用户提供知情的升级途径。

Logstash 过滤器必须实现 registerfilter 方法。

public
def register
end
  1. def register

Logstash register 方法类似于 initialize 方法。 它最初创建是为了强制调用 super,以避免新手头疼。(注意:它可能会消失,而支持 initialize,并结合一些强制测试以确保调用 super。)

public 意味着该方法可以在任何地方调用,而不仅仅是在类中。 这是 Ruby 中方法的默认行为,但无论如何在此处明确指定。

您也可以在此处分配实例变量(以 @ 开头的变量)。 配置变量现在在范围内作为实例变量,例如 @message

  public
  def filter(event)

    if @message
      # Replace the event message with our message as configured in the
      # config file.
      event.set("message", @message)
    end

  # filter_matched should go in the last line of our successful code
  filter_matched(event)
end
  1. def filter

插件的 filter 方法是实际进行过滤工作的地方! 在 filter 方法中,您可以使用 Event 对象引用事件数据。 Event 是 Logstash 内部封装数据流的主要对象,并为插件开发人员提供 API 以与事件的内容进行交互。

filter 方法还应该通过显式调用 Event 类中可用的 sprintf 方法来处理任何 事件相关配置。 例如

field_foo = event.sprintf(field)

请注意,配置变量现在在范围内作为实例变量,例如 @message

filter_matched(event)

在成功执行插件后调用 filter_matched 方法将确保通过此过滤器的 Logstash 配置添加的任何字段或标记都将被正确处理。 例如,任何 add_fieldremove_fieldadd_tag 和/或 remove_tag 操作都将在此时执行。

现在可以使用诸如 event.cancel 之类的 Event 方法来控制正在处理的事件的工作流程。

在此过程中的这一点,您已经编写了插件的代码,并且已准备好从中构建 Ruby Gem。 以下信息将帮助您完成该过程。

Ruby 中的 require 语句用于包含必要的代码。 在某些情况下,您的插件可能需要其他文件。 例如,collectd 插件 使用 collectd 提供的 types.db 文件。 在插件的主目录中,一个名为 vendor.json 的文件描述了这些文件。

vendor.json 文件包含一个 JSON 对象数组,每个对象描述一个文件依赖项。 此示例来自 collectd 编解码器插件

[{
        "sha1": "a90fe6cc53b76b7bdd56dc57950d90787cb9c96e",
        "url": "http://collectd.org/files/collectd-5.4.0.tar.gz",
        "files": [ "/src/types.db" ]
}]
  • sha1 是用于验证 url 引用的文件完整性的 sha1 签名。
  • url 是 Logstash 将从中下载文件的地址。
  • files 是从下载的文件中提取的可选文件数组。 请注意,尽管 tar 存档可以使用绝对路径或相对路径,但在该数组中将它们视为绝对路径。 如果不存在 files,则所有文件都将被解压缩并提取到 vendor 目录中。

vendor.json 文件的另一个示例是 geoip 过滤器

下载这些依赖项的过程是调用 rake vendor。这将在本文档的测试部分进一步讨论。

另一种外部依赖项是对 jar 文件的依赖。这将在“添加 gemspec 文件”部分中介绍。

随着插件的演变,某个选项或功能可能不再服务于其预期目的,因此开发人员可能希望弃用它的使用。弃用会警告用户该选项的状态,以便他们不会在以后的版本中删除该选项时措手不及。

Logstash 7.6 引入了一个弃用记录器,以简化处理这些情况。 您可以使用适配器,以确保您的插件可以使用弃用记录器,同时仍然支持旧版本的 Logstash。 有关更多信息以及使用适配器的说明,请参见自述文件

弃用记录在 log 目录中的 logstash-deprecation.log 文件中。

Gemfile 允许 Ruby 的 Bundler 维护插件的依赖项。 目前,我们只需要 Logstash gem 用于测试,但是如果您需要其他 gem,则应在此处添加它们。

提示

有关更多详细信息,请参见 Bundler 的 Gemfile 页面

source 'https://rubygems.org.cn'
gemspec
gem "logstash", :github => "elastic/logstash", :branch => "master"

Gemspecs 定义将要构建的 Ruby gem 并包含您的插件。

提示

有关更多信息,请参见 Rubygems 规范页面

Gem::Specification.new do |s|
  s.name = 'logstash-filter-example'
  s.version = '0.1.0'
  s.licenses = ['Apache License (2.0)']
  s.summary = "This filter does x, y, z in Logstash"
  s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
  s.authors = ["Elastic"]
  s.email = 'info@elastic.co'
  s.homepage = "https://elastic.ac.cn/guide/en/logstash/current/index.html"
  s.require_paths = ["lib"]

  # Files
  s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE','NOTICE.TXT']
   # Tests
  s.test_files = s.files.grep(%r{^(test|spec|features)/})

  # Special flag to let us know this is actually a logstash plugin
  s.metadata = { "logstash_plugin" => "true", "logstash_group" => "filter" }

  # Gem dependencies
  s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
  s.add_development_dependency 'logstash-devutils'
end

可以更改这些值以适合您的插件。 特别是,s.names.summary 应反映插件的名称和行为。

s.licensess.version 也很重要,并且在您准备发布插件时会发挥作用。

Logstash及其所有插件均已获得Apache License版本2(“ALv2”)的许可。 如果您通过RubyGems.org公开提供您的插件,请确保在您的gemspec中包含以下行

  • s.licenses = ['Apache License (2.0)']

s.version 指定的 gem 版本有助于跟踪插件随时间的变化。 您应该使用 semver 版本控制策略作为版本号。

gemspec 文件的底部有一个带有注释的部分:Gem dependencies。 这是必须提及任何其他所需 gem 的地方。 如果 gem 对于您的插件正常运行是必需的,那么它是一个运行时依赖项。 如果 gem 仅用于测试,则它将是一个开发依赖项。

注意

您还可以对依赖项(包括其他 Logstash 插件)具有版本控制要求

# Gem dependencies
s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
s.add_development_dependency 'logstash-devutils'

此 gemspec 具有对 logstash-core-plugin-api 的运行时依赖,并且要求它的版本号大于或等于 1.60 且小于或等于 2.99。

重要

所有插件都具有对 logstash-core-plugin-api gem 的运行时依赖,以及对 logstash-devutils 的开发依赖。

在某些情况下,例如 Elasticsearch output plugin,您的代码可能依赖于 jar 文件。 在这种情况下,依赖项以这种方式添加到 gemspec 文件中

# Jar dependencies
s.requirements << "jar 'org.elasticsearch:elasticsearch', '5.0.0'"
s.add_runtime_dependency 'jar-dependencies'

定义了这两者之后,安装过程将在 http://mvnrepository.com 中搜索所需的 jar 文件,并下载指定的版本。

文档是插件的重要组成部分。 所有插件文档都经过渲染并放置在 Logstash 参考版本化的插件文档中。

有关提示和准则,请参见 记录您的插件

Logstash 喜欢测试。 许多测试。 如果您在生产环境中使用新的过滤器插件,则需要进行一些测试以确保您不会破坏任何现有功能。

注意

对 RSpec 的完整阐述超出了本文档的范围。 在 https://rspec.ruby-lang.org.cn 上了解有关 RSpec 的更多信息

为了帮助学习有关测试和测试的知识,请在其他几个类似插件的 spec/filters/ 目录中查找。

现在,让我们从插件的新克隆开始,构建它并运行测试。

  • 将您的插件克隆到临时位置GITUSERNAME 替换为您的 github 用户名,并将 MYPLUGINNAME 替换为您的插件名称。

    • git clone https://github.com/GITUSERNAME/logstash-``filter-MYPLUGINNAME.git

      • 或者,通过 ssh:git clone git@github.com:GITUSERNAME/logstash-``filter-MYPLUGINNAME.git
    • cd logstash-filter-MYPLUGINNAME

然后,您需要使用 bundler 安装插件的依赖项

bundle install
重要

如果您的插件具有 vendor.json 中描述的外部文件依赖项,则必须在运行或测试之前下载该依赖项。 您可以通过运行

rake vendor

最后,运行测试

bundle exec rspec

您应该看到一条成功消息,看起来像这样

Finished in 0.034 seconds
1 example, 0 failures

万岁! 您快到了!(除非您看到失败……否则您应该先修复这些失败)。

现在,您可以将经过良好测试的插件构建到 Ruby gem 中。

您已经拥有所有必需的成分,因此让我们继续运行构建命令

gem build logstash-filter-example.gemspec

就这样! 您的 gem 应该已构建完毕,并且与路径的名称相同

logstash-filter-mypluginname-0.1.0.gem

gemspec 文件中的 s.version 数字将提供 gem 版本,在本例中为 0.1.0

您应该测试将插件安装到 Logstash 的全新安装中。 从 Logstash 下载页面下载最新版本。

  1. 解压缩并 cd 进入目录

    curl -O https://download.elastic.co/logstash/logstash/logstash-9.0.0.tar.gz
    tar xzvf logstash-9.0.0.tar.gz
    cd logstash-9.0.0
    
  2. 使用插件工具,我们可以安装刚刚构建的 gem。

    • /my/logstash/plugins 替换为适合您环境的 gem 的正确路径,并将 0.1.0 替换为 gemspec 文件中的正确版本号。

      bin/logstash-plugin install /my/logstash/plugins/logstash-filter-example/logstash-filter-example-0.1.0.gem
      
    • 运行此命令后,您应该看到 Logstash 的反馈,表明它已成功安装

      validating /my/logstash/plugins/logstash-filter-example/logstash-filter-example-0.1.0.gem >= 0
      Valid logstash plugin. Continuing...
      Successfully installed 'logstash-filter-example' with version '0.1.0'
      
      提示

      您还可以使用 Logstash 插件工具来确定当前有哪些插件可用

      bin/logstash-plugin list
      

      根据您安装的内容,您可能会看到一个插件的简短或很长的列表:输入,编解码器,过滤器和输出。

  3. 现在,尝试使用命令行传递的简单配置来运行 Logstash,并使用 -e 标志。

    注意

    您的结果将取决于您的过滤器插件的设计目的。

bin/logstash -e 'input { stdin{} } filter { example {} } output {stdout { codec => rubydebug }}'

通过 stdin 发送输入,并通过具有 rubydebug 编解码器的 stdout 发送输出(经过过滤后)来测试您的过滤器,这可以提高可读性。

对于示例过滤器插件,您发送的任何文本都将被 message 配置参数的内容替换,默认值为“ Hello World!”。

Testing 1, 2, 3
{
       "message" => "Hello World!",
      "@version" => "1",
    "@timestamp" => "2015-01-27T19:17:18.932Z",
          "host" => "cadenza"
}

随意通过更改 message 参数进行实验和测试

bin/logstash -e 'input { stdin{} } filter { example { message => "This is a new message!"} } output {stdout { codec => rubydebug }}'

恭喜! 您已经构建,部署并成功运行了 Logstash 过滤器。

Logstash 使用 RubyGems.org 作为所有插件工件的存储库。 开发完新插件后,只需将其发布到 RubyGems.org,即可将其提供给 Logstash 用户。

Logstash及其所有插件均已获得Apache License版本2(“ALv2”)的许可。 如果您通过RubyGems.org公开提供您的插件,请确保在您的gemspec中包含以下行

  • s.licenses = ['Apache License (2.0)']

首先,您需要在 RubyGems.org 上拥有一个帐户

创建帐户后,从 RubyGems.org 获取 API 密钥。 默认情况下,RubyGems 使用文件 ~/.gem/credentials 来存储您的 API 密钥。 这些凭据将用于发布 gem。 将 usernamepassword 替换为您在 RubyGems.org 上创建的凭据

curl -u username:password https://rubygems.org.cn/api/v1/api_key.yaml > ~/.gem/credentials
chmod 0600 ~/.gem/credentials

在继续操作之前,请确保您在 gemspec 文件中具有正确的版本,并提交您的更改。

  • s.version = '0.1.0'

要发布新 logstash gem 的 0.1.0 版本

bundle install
bundle exec rake vendor
bundle exec rspec
bundle exec rake publish_gem
注意

执行 rake publish_gem

  1. 从 gemspec 文件(s.version = '0.1.0')中读取版本
  2. 在您的本地存储库中检查是否存在该版本的标签。 如果标签已经存在,它将中止该过程。 否则,它将在您的本地存储库中创建一个新的版本标签。
  3. 构建 gem
  4. 将 gem 发布到 RubyGems.org

就这样! 您的插件已发布! Logstash 用户现在可以通过运行来安装您的插件

bin/logstash-plugin install logstash-filter-mypluginname

不需要将您的源代码贡献给 logstash-plugins github 组织,但是我们始终欢迎新的插件!

将插件放在 logstash-plugins 存储库中的一些好处是

  • 发现。 您的插件将出现在 Logstash 参考中,Logstash 用户首先在此处查找插件和文档。
  • 文档. 您的插件文档将自动添加到 Logstash 参考中。
  • 测试. 通过我们的测试基础设施,您的插件将针对当前和未来的 Logstash 版本进行持续测试。 因此,用户可以放心,如果出现不兼容情况,它们将被快速发现和纠正。
  • 代码审查. 您的插件必须由社区成员审查,以确保其连贯性、质量、可读性、稳定性和安全性。
  • 测试. 您的插件必须包含测试才能被接受。 这些测试也需要经过代码审查,以确保其范围和完整性。 如果您不知道如何编写测试也没关系 — 我们会指导您。 我们正在编写 Logstash 测试创建指南,这将使其更容易。 同时,您可以参考 http://betterspecs.org/ 获取示例。

要开始将您的插件迁移到 logstash-plugins,只需在 Logstash 存储库中创建一个新的 issue。 完成验收指南后,我们将使用推荐的 github 流程 来帮助您将插件迁移到 logstash-plugins 组织。

© . All rights reserved.