正在加载

如何编写 Logstash 输出插件

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

让我们逐步完成使用 示例输出插件 创建输出插件的过程。

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

  1. 登录到 GitHub。

  2. 单击仓库选项卡。 您将看到您已经 fork 或贡献的其他仓库的列表。

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

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

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

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

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

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

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

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

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

  2. 克隆输出插件示例并将其复制到您的插件分支。

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

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

    • logstash-output-example.gemspec

    • example.rb

    • example_spec.rb

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

您的文件结构应如下所示

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

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

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

require "logstash/outputs/base"
require "logstash/namespace"

# Add any asciidoc formatted documentation here
# An example output that does nothing.
class LogStash::Outputs::Example < LogStash::Outputs::Base
  config_name "example"

  # This sets the concurrency behavior of this plugin. By default it is :legacy, which was the standard
  # way concurrency worked before Logstash 2.4
  #
  # You should explicitly set it to either :single or :shared as :legacy will be removed in Logstash 6.0
  #
  # When configured as :single a single instance of the Output will be shared among the
  # pipeline worker threads. Access to the `#multi_receive/#multi_receive_encoded/#receive` method will be synchronized
  # i.e. only one thread will be active at a time making threadsafety much simpler.
  #
  # You can set this to :shared if your output is threadsafe. This will maximize
  # concurrency but you will need to make appropriate uses of mutexes in `#multi_receive/#receive`.
  #
  # Only the `#multi_receive/#multi_receive_encoded` methods need to actually be threadsafe, the other methods
  # will only be executed in a single thread
  concurrency :single

  public
  def register
  end

  public
  # Takes an array of events
  # Must be threadsafe if `concurrency :shared` is set
  def multi_receive(events)
  end
end
  1. def register
  2. def multi_receive
  3. class LogStash::Outputs::Example

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

Logstash 输出插件需要 logstash/outputs/base 和 logstash/namespace 中定义的父类

require "logstash/outputs/base"
require "logstash/namespace"

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

让我们浏览一下插件的各种元素。

输出插件类应该是 LogStash::Outputs::Base 的子类

class LogStash::Outputs::Example < LogStash::Outputs::Base

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

LogStash::Outputs::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 输出必须实现 registermulti_receive 方法。

public
def register
end
  1. def register

Logstash register 方法类似于 initialize 方法。 它最初创建的目的是强制调用 super,以避免新手出现问题。(注意:它可能会被 initialize 取代,同时进行一些强制测试以确保调用 super。)

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

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

在此过程的这一点上,您已经编写了插件的代码,并准备从中构建 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 是 sha1 签名,用于验证 url 引用的文件的完整性。
  • url 是 Logstash 将从中下载文件的地址。
  • files 是一个可选的文件数组,用于从下载的文件中提取。 请注意,虽然 tar 存档可以使用绝对或相对路径,但在此数组中将其视为绝对路径。 如果 files 不存在,则所有文件将被解压缩并提取到 vendor 目录中。

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

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

另一种外部依赖项是 jar 文件。 这将在“添加 gemspec 文件”部分中描述。

随着插件的发展,某个选项或功能可能不再达到预期目的,开发人员可能希望弃用其用法。 弃用会警告用户该选项的状态,以便他们不会在以后的版本中删除该选项时感到意外。

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

弃用记录在 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"

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

提示

更多信息可以在 Rubygems 规范页面 上找到。

Gem::Specification.new do |s|
  s.name = 'logstash-output-example'
  s.version = '0.1.0'
  s.licenses = ['Apache License (2.0)']
  s.summary = "This output 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" => "output" }

  # 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, version 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 输出插件,您的代码可能依赖于一个 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/outputs/ 目录。

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

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

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

      • 或者,通过 ssh:git clone git@github.com:GITUSERNAME/logstash-``output-MYPLUGINNAME.git
    • cd logstash-output-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-output-example.gemspec

就是这样!您的 gem 应该已构建并位于与名称相同的路径中

logstash-output-mypluginname-0.1.0.gem

来自 gemspec 文件的 s.version 号码将提供 gem 版本,在本例中为 0.1.0

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

  1. 解压并进入目录

    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-output-example/logstash-output-example-0.1.0.gem
      
    • 运行此命令后,您应该会看到来自 Logstash 的反馈,表明它已成功安装

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

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

      bin/logstash-plugin list
      

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

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

    注意

    您的结果将取决于您的输出插件的设计用途。

恭喜!您已经构建、部署并成功运行了 Logstash 输出。

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

Logstash 及其所有插件均在 Apache License, version 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-output-mypluginname

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

在 logstash-plugins 存储库中拥有您的插件的一些好处是

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

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

© . All rights reserved.