Logstash【从无到有从有到无】【L23】为Logstash贡献

目录

1.为Logstash贡献

1.1.添加插件

1.1.1.插件关闭API

1.1.2.扩展Logstash核心

1.2.如何编写Logstash输入插件

1.2.1.开始吧

1.2.2.为您的新插件创建GitHub存储库

1.2.3.使用插件生成器工具

1.2.4.复制输入代码

1.2.5.查看您的插件是什么样的

1.2.6.编码输入插件

1.2.7.插件主体

1.2.8.配置参数

1.2.9.插件方法

1.2.10.编译插件

1.2.10.1外部依赖

1.2.10.2.添加Gemfile文件

1.2.11.运行时和开发依赖项

1.2.11.1.Jar依赖

1.2.12.记录您的插件

1.2.13.添加测试

1.2.13.1.克隆并测试!

1.2.13.2.建造和测试

1.2.13.3.测试安装

1.2.14.将您的插件提交到RubyGems.org和logstash-plugins

1.2.14.1.Licensing

1.2.14.2.发布RubyGems.org

1.2.14.3.将您的源代码贡献给 logstash-plugins

1.2.15.验收准则

1.3.如何编写Logstash编解码器插件

1.3.1.开始吧

1.3.2.为您的新插件创建GitHub存储库

1.3.3.使用插件生成器工具

1.3.4.复制编解码器代码

1.3.5.查看您的插件是什么样的

1.3.6.编码编解码器插件

1.3.7.插件主体

1.3.8.配置参数

1.3.9.插件方法

1.3.10.解码方法

1.3.11.编码方法

1.3.12.编译插件

1.3.13.外部依赖

1.3.14.添加gemspec文件

1.3.15.运行时与开发

1.3.15.1.依存关系

1.3.15.2.Jar依赖

1.3.16.记录您的插件

1.3.17.添加测试

1.3.18.克隆并测试!

1.3.19.建造和测试

1.3.20.测试安装

1.3.21.将您的插件提交到RubyGems.org和logstash-plugins

1.3.22.发布到RubyGems.org

1.3.23.将您的源代码贡献给logstash-plugins

1.4.如何编写Logstash过滤器插件

1.4.1.开始吧

1.4.2.使用插件生成器工具

1.4.3.查看您的插件是什么样的

1.4.4.编码过滤器插件

1.4.5.插件主体

1.4.6.配置参数

1.4.7.插件方法

1.4.7.编译插件

1.4.7.1.添加一个Gemfile文件

1.4.8.新增gemspec档案

1.4.9.运行时和开发依赖性

1.4.10.Jar依赖

1.4.11.记录您的插件

1.4.12.添加测试

1.4.13.克隆并测试!

1.4.14.建造和测试

1.4.15.将您的插件提交到RubyGems.org和logstash-plugins

1.4.16.将您的源代码贡献给logstash-plugins

1.5.如何编写Logstash输出插件

1.5.1.开始吧

1.5.2.编码输出插件

1.5.3.插件主体

1.5.4.配置参数

1.5.5.插件方法

1.5.6.编译插件

1.5.6.1.添加一个宝石文件

1.5.7.新增gemspec档案

1.5.7.1.运行时和开发依赖性

1.5.7.2.Jar依赖

1.5.8.记录您的插件

1.5.9.添加测试

1.5.10.克隆并测试!

1.5.11.建造和测试

1.5.12.将您的插件提交到RubyGems.org和logstash-plugins

1.5.13.将您的源代码贡献给logstash-plugins

1.6.记录你的插件

1.6.1.文档文件

1.6.2.标题ID

1.6.3.链接的格式

1.6.4.代码示例

1.6.5.我的文档在哪里?

1.6.6.资源

1.7.贡献补丁到Logstash插件

1.7.1.输入插件

1.7.2.编解码器插件

1.7.3.过滤插件

1.7.4.输出插件

1.7.5.流程

1.7.6.测试方法

1.7.6.1.测试驱动开发

1.7.7.放在一起

1.8.Logstash插件社区维护者指南

1.8.1.贡献准则

1.8.2.文件目标

1.8.3.开发流程

1.8.4.版本插件

1.8.5.记录

1.8.6.贡献者许可协议(CLA)指南

1.8.7.需要帮忙?

1.8.8.社区管理

1.9.提交你的插件RubyGems.org和logstash,插件库

1.9.1.许可

1.9.2.发布到RubyGems.org

1.9.3.将您的源代码贡献给logstash-plugins

1.9.4.好处

1.9.5.验收准则


1.为Logstash贡献

您可以将自己的输入,编解码器,过滤器或输出插件添加到Logstash。

1.1.添加插件

可以独立于Logstash核心开发和部署插件。 以下是一些文档,可指导您完成编码和部署自己的插件的过程:

1.1.1.插件关闭API

您可以通过以下三种方法来关闭插件:stop,stop?和close。

  • 从插件线程外部调用stop方法。 此方法指示插件停止。
  • 停下来吗 当已经为该插件调用stop方法时,method返回true。
  • 插件的run方法和插件的线程均退出后,close方法执行最终的簿记和清理。 close方法是该方法的新名称,在以前的Logstash版本中称为teardown。

shutdownfinishedfinished?running?, and terminating? 方法是多余的,不再存在于Plugin Base类中。

提供了插件关闭API的示例代码(available)。

1.1.2.扩展Logstash核心

我们也欢迎您为Logstash核心功能集做出贡献并修复错误。

请通读我们的贡献指南和Logstash自述文件。

 

1.2.如何编写Logstash输入插件

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

1.2.1.开始吧

让我们逐步使用示例输入插件创建输入插件

1.2.2.为您的新插件创建GitHub存储库

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

  1. 登录到GitHub。
  2. 单击存储库选项卡。 您会看到您分叉或贡献的其他存储库的列表。
  3. 单击右上角的绿色“新建”按钮。
  4. 为您的新仓库指定以下设置:
    • 存储库名称-格式为logstash-input-pluginname的唯一名称。
    • 公共或私有-您可以选择,但是如果您想将其作为正式插件提交,则存储库必须为公共。
    • 使用README初始化此存储库-使您能够立即将存储库克隆到计算机。
  5. 单击创建存储库。

1.2.3.使用插件生成器工具

您现在可以在几秒钟内创建自己的Logstash插件! bin / logstash-plugin的generate子命令为带有模板文件的新Logstash插件创建基础。 它会创建正确的目录结构,gemspec文件和相关性,因此您可以开始添加自定义代码来使用Logstash处理数据。

有关更多信息,请参见Generating Plugins

1.2.4.复制输入代码

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

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

  • git clone https://github.com/GITUSERNAME/logstash-input-MYPLUGINNAME.git
    • 或者通过ssh:git clone git@github.com:GITUSERNAME / logstash-input-MYPLUGINNAME.git
  • cd logstash-input-MYPLUGINNAME

2.克隆{inputtype}插件示例,然后将其复制到您的插件分支。

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

  • cd /tmp
  • git clone https://github.com/logstash-plugins/logstash-input-example.git
  • cd logstash-input-example
  • rm -rf .git
  • cp -R * /path/to/logstash-input-mypluginname/

3.重命名以下文件以匹配您的插件名称。

  • logstash-input-example.gemspec
  • example.rb
  • example_spec.rb

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

您的文件结构应如下所示:

$ tree logstash-input-mypluginname
├── Gemfile
├── LICENSE
├── README.md
├── Rakefile
├── lib
│   └── logstash
│       └── inputs
│           └── mypluginname.rb
├── logstash-input-mypluginname.gemspec
└── spec
    └── inputs

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

1.2.5.查看您的插件是什么样的

在深入探讨细节之前,请在您喜欢的文本编辑器中打开插件文件并进行查看

# encoding: utf-8
require "logstash/inputs/base"
require "logstash/namespace"
require "stud/interval"
require "socket" # for Socket.gethostname

# Add any asciidoc formatted documentation here
# Generate a repeating message.
#
# This plugin is intended only as an example.

class LogStash::Inputs::Example < LogStash::Inputs::Base
  config_name "example"

  # If undefined, Logstash will complain, even if codec is unused.
  default :codec, "plain"

  # The message string to use in the event.
  config :message, :validate => :string, :default => "Hello World!"

  # Set how frequently messages should be sent.
  #
  # The default, `1`, means send a message every second.
  config :interval, :validate => :number, :default => 1

  public
  def register
    @host = Socket.gethostname
  end # def register

  def run(queue)
    Stud.interval(@interval) do
      event = LogStash::Event.new("message" => @message, "host" => @host)
      decorate(event)
      queue << event
    end # loop
  end # def run

end # class LogStash::Inputs::Example

1.2.6.编码输入插件

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

encoding

这似乎是一件小事,但请记住在插件代码的开头指定编码:

# encoding: utf-8

Logstash取决于UTF-8中的内容,因此我们将其放在此处以告诉Ruby解释器我们将使用UTF-8编码。

 

require Statements

Logstash输入插件需要在logstash / inputs / base和logstash /命名空间中定义的父类:

require "logstash/inputs/base"
require "logstash/namespace"

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

 

1.2.7.插件主体

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

class Declaration

输入插件类应该是LogStash :: Inputs :: Base的子类:

class LogStash::Inputs::Example < LogStash::Inputs::Base

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

LogStash::Inputs::Example

 

config_name

config_name "example"

这是您的插件将在输入配置块中调用的名称。

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

input {
  example {...}
}

 

1.2.8.配置参数

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

配置或配置部分允许您定义使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-此值是否应为值列表。将对列表成员进行类型检查,并将标量转换为一个元素列表。请注意,尽管如果您需要更适合的复杂对象列表,这在很大程度上消除了数组类型。假)
  • :deprecated-信息性(也为布尔值true或false)
  • :obsolete-用于声明给定的设置已被删除并且不再起作用。这样做的目的是为仍在使用现已删除的设置的用户提供明智的升级途径。

1.2.9.插件方法

Logstash输入必须实现两种主要方法:注册和运行。

register Method

  public
  def register
  end # def register

Logstash注册方法类似于初始化方法。 它最初是为了强制执行超级调用而创建的,以防止新手头痛。 (注意:它可能不支持初始化,而是结合一些强制测试以确保调用了super。)

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

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

 

run Method

输入插件示例具有以下运行方法:

def run(queue)
    Stud.interval(@interval) do
      event = LogStash::Event.new("message" => @message, "host" => @host)
      decorate(event)
      queue << event
    end # loop
  end # def run

运行方法是来自输入的数据流成为事件的地方。

流可以是简单的,也可以像 heartbeat输入插件一样生成。 在这些情况下,尽管未使用任何编解码器,但必须在代码中设置默认编解码器以避免错误。

这是另一个示例运行方法:

def run(queue)
    while true
      begin
        # Based on some testing, there is no way to interrupt an IO.sysread nor
        # IO.select call in JRuby.
        data = $stdin.sysread(16384)
        @codec.decode(data) do |event|
          decorate(event)
          event.set("host", @host) if !event.include?("host")
          queue << event
        end
      rescue IOError, EOFError, LogStash::ShutdownSignal
        # stdin closed or a requested shutdown
        break
      end
    end # while true
    finished
  end # def run

在此示例中,数据被发送到配置块中定义的编解码器,以解码数据流并返回事件。

在两个示例中,结果事件都传递给decorate方法:

  decorate(event)

这将应用您可能在输入配置块中设置的所有标签。 例如,标签=> [“” tag1“,” tag2“]。

同样在两个示例中,将事件“装饰”后附加到队列:

  queue << event

这会将事件插入到管道中。

由于输入插件的范围可以从简单到复杂,因此查看更多有关如何创建插件的示例很有帮助:


 logstash-plugin github repository中还有更多示例。

1.2.10.编译插件

至此,您已经对插件进行了编码,并准备从中构建Ruby Gem。 以下信息将帮助您完成该过程。

1.2.10.1外部依赖

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

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

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

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

下载这些依赖项的过程是致电rake供应商。 这将在本文档的测试部分中进一步讨论。

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

1.2.10.2.添加Gemfile文件

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

可以在Rubygems Specification page上找到更多信息。

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

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

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

s.licenses和s.version也很重要,当您准备发布插件时它们就会起作用。

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

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

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

1.2.11.运行时和开发依赖项

gempec文件的底部是一个带有注释的部分: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具有开发依赖性。

1.2.11.1.Jar依赖

在某些情况下,例如Elasticsearch输出插件,您的代码可能取决于jar文件。 在这种情况下,依赖项将以这种方式添加到gemspec文件中:

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

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

1.2.12.记录您的插件

文档是插件的重要组成部分。 所有插件文档都已呈现并放置在 Logstash ReferenceVersioned plugin docs中。

有关提示和准则,请参阅 Documenting your plugin

1.2.13.添加测试

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

关于RSpec的完整论述不在本文档范围之内。 在http://rspec.info上了解有关RSpec的更多信息

为了帮助您了解测试和测试,请查看其他几个类似插件的spec / inputs /目录。

1.2.13.1.克隆并测试!

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

  • 将您的插件克隆到一个临时位置将GITUSERNAME替换为您的github用户名,将MYPLUGINNAME替换为您的插件名。
  • git clone https://github.com/GITUSERNAME/logstash-input-MYPLUGINNAME.git
    • 或者通过ssh:git clone git@github.com:GITUSERNAME / logstash-input-MYPLUGINNAME.git
  • cd logstash-input-MYPLUGINNAME

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

bundle install

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

rake vendor

最后,运行测试:

bundle exec rspec

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

Finished in 0.034 seconds
1 example, 0 failures

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

1.2.13.2.建造和测试

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

Build

您已经具备了所有必要的要素,所以让我们继续运行build命令:

gem build logstash-input-example.gemspec

而已! 您的gem 应该被制造出来,并且与名称相同

logstash-input-mypluginname-0.1.0.gem

gemspec文件中的s.version号将提供gem版本,在这种情况下为0.1.0。

1.2.13.3.测试安装

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

1.解压并进入目录:

curl -O https://download.elastic.co/logstash/logstash/logstash-7.4.1.tar.gz
tar xzvf logstash-7.4.1.tar.gz
cd logstash-7.4.1

2.使用插件工具,我们可以安装刚刚构建的gem。

  • 将/ my / logstash / plugins替换为适合您环境的gem路径,并将0.1.0替换为gemspec文件中的正确版本号。
bin/logstash-plugin install /my/logstash/plugins/logstash-input-example/logstash-input-example-0.1.0.gem
  • 运行此命令后,您应该看到Logstash已成功安装的反馈:
validating /my/logstash/plugins/logstash-input-example/logstash-input-example-0.1.0.gem >= 0
Valid logstash plugin. Continuing...
Successfully installed 'logstash-input-example' with version '0.1.0'

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

bin/logstash-plugin list

根据安装的内容,您可能会看到一小段或一长段插件:输入,编解码器,过滤器和输出。

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

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

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

输入插件示例将每秒发送一次消息内容(默认消息为“ Hello World!”)。

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

随时通过更改message和interval参数来进行实验和测试:

bin/logstash -e 'input { example{ message => "A different message" interval => 5 } } output {stdout { codec => rubydebug }}'

恭喜你! 您已经构建,部署并成功运行了Logstash输入。

1.2.14.将您的插件提交到RubyGems.orglogstash-plugins

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

1.2.14.1.Licensing

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

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

1.2.14.2.发布RubyGems.org

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

创建帐户后,请从RubyGems.org获取API密钥。 默认情况下,RubyGems使用〜/ .gem / credentials文件存储您的API密钥。 这些凭证将用于发布gem。 用您在RubyGems.org创建的凭据替换用户名和密码:

curl -u username:password https://rubygems.org/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

执行publish_gem:

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

而已! 您的插件已发布! Logstash用户现在可以通过运行以下命令来安装您的插件:

bin/logstash-plugin install logstash-input-mypluginname

1.2.14.3.将您的源代码贡献给 logstash-plugins

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

好处

将插件放在logstash-plugins存储库中的许多好处包括:

  • 发现。 您的插件将显示在Logstash参考中,Logstash用户将在其中首先查看插件和文档。
  • 文档。 您的插件文档将自动添加到Logstash参考。
  • 测试。 利用我们的测试基础架构,您的插件将针对当前和将来的Logstash版本进行持续测试。 结果,用户将保证,如果出现不兼容问题,将迅速发现并纠正它们。

1.2.15.验收准则

  • 代码审查。 您的插件必须由社区成员进行审查,以确保其一致性,质量,可读性,稳定性和安全性。
  • 测试。 您的插件必须包含要接受的测试。 这些测试也要接受代码审查的范围和完整性。 如果您不知道如何编写测试也可以。—我们将指导您。 我们正在发布有关为Logstash创建测试的指南,这将使它变得更加容易。 同时,您可以参考http://betterspecs.org/以获取示例。

要开始将插件迁移到Logstash插件,只需在Logstash存储库中创建一个新问题。 接受指南完成后,我们将使用推荐的github process来促进迁移到logstash-plugins组织。

1.3.如何编写Logstash编解码器插件

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

1.3.1.开始吧

让我们逐步使用示例编解码器插件创建编解码器插件。

1.3.2.为您的新插件创建GitHub存储库

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

  1. 登录到GitHub。
  2. 单击Repositories 选项卡。 您会看到您分叉或贡献的其他存储库的列表。
  3. 单击右上角的绿色“New”按钮。
  4. 为您的新仓库指定以下设置:
    1. Repository name-格式为logstash-codec-pluginname的唯一名称。
    2. Public or Private-您可以选择,但是如果您想将其作为正式插件提交,则存储库必须为公共。
    3. Initialize this repository with a README-使您能够立即将存储库克隆到计算机。
  5. 单击创建存储库。

1.3.3.使用插件生成器工具

您现在可以在几秒钟内创建自己的Logstash插件bin/logstash-plugin的generate子命令为带有模板文件的新Logstash插件创建基础。 它会创建正确的目录结构,gemspec文件和相关性,因此您可以开始添加自定义代码来使用Logstash处理数据。

有关更多信息,请参见Generating Plugins

1.3.4.复制编解码器代码

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

  1. 克隆您的插件。 将GITUSERNAME替换为您的github用户名,并将MYPLUGINNAME替换为您的插件名称。
    1. git clone https://github.com/GITUSERNAME/logstash-codec-MYPLUGINNAME.git
      1. 或者通过ssh:git clone git@github.com:GITUSERNAME / logstash-codec-MYPLUGINNAME.git
    2. cd logstash-codec-MYPLUGINNAME
  2. 克隆{inputtype}插件示例,然后将其复制到您的插件分支。
    1. 您不想包含示例.git目录或其内容,因此请在复制示例之前将其删除。
      1. cd / tmp
      2. git clone https://github.com/logstash-plugins/logstash-codec-example.git
      3. cd logstash-codec-example
      4. rm -rf .git
      5. cp -R * / path / to / logstash-codec-mypluginname /
  3. 重命名以下文件以匹配您的插件名称。
    1. logstash-codec-example.gemspec
    2. example.rb
    3. example_spec.rb
cd /path/to/logstash-codec-mypluginname
mv logstash-codec-example.gemspec logstash-codec-mypluginname.gemspec
mv lib/logstash/codecs/example.rb lib/logstash/codecs/mypluginname.rb
mv spec/codecs/example_spec.rb spec/codecs/mypluginname_spec.rb

您的文件结构应如下所示:

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

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

1.3.5.查看您的插件是什么样的

在深入探讨细节之前,请在您喜欢的文本编辑器中打开插件文件并进行查看。

# encoding: utf-8
require "logstash/codecs/base"
require "logstash/codecs/line"

# Add any asciidoc formatted documentation here
class LogStash::Codecs::Example < LogStash::Codecs::Base

  # This example codec will append a string to the message field
  # of an event, either in the decoding or encoding methods
  #
  # This is only intended to be used as an example.
  #
  # input {
  #   stdin { codec => example }
  # }
  #
  # or
  #
  # output {
  #   stdout { codec => example }
  # }
  config_name "example"

  # Append a string to the message
  config :append, :validate => :string, :default => ', Hello World!'

  public
  def register
    @lines = LogStash::Codecs::Line.new
    @lines.charset = "UTF-8"
  end

  public
  def decode(data)
    @lines.decode(data) do |line|
      replace = { "message" => line["message"].to_s + @append }
      yield LogStash::Event.new(replace)
    end
  end # def decode

  public
  def encode(event)
    @on_event.call(event, event.get("message").to_s + @append + NL)
  end # def encode

end # class LogStash::Codecs::Example

1.3.6.编码编解码器插件

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

encoding

这似乎是一件小事,但请记住在插件代码的开头指定编码:

# encoding: utf-8

Logstash取决于UTF-8中的内容,因此我们将其放在此处以告诉Ruby解释器我们将使用UTF-8编码。

 

require Statements

Logstash编解码器插件需要在logstash / codecs / base和logstash /命名空间中定义的父类:

require "logstash/codecs/base"
require "logstash/namespace"

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

1.3.7.插件主体

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

class Declaration

编解码器插件类应该是LogStash :: Codecs :: Base的子类:

class LogStash::Codecs::Example < LogStash::Codecs::Base

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

LogStash::Codecs::Example

 

config_name

config_name "example"

这是您的插件将在编解码器配置块中调用的名称。

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

 

1.3.8.配置参数

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

配置或配置部分允许您定义使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-此值是否应为值列表。将对列表成员进行类型检查,并将标量转换为一个元素列表。请注意,尽管如果您需要更适合的复杂对象列表,这在很大程度上消除了数组类型。假)
  • :deprecated-信息性(也为布尔值true或false)
  • :obsolete-用于声明给定的设置已被删除并且不再起作用。这样做的目的是为仍在使用现已删除的设置的用户提供明智的升级途径。

1.3.9.插件方法

Logstash编解码器必须实现register方法,decode方法或encode方法(或两者)。

register Method

  public
  def register
  end # def register

Logstash注册方法类似于初始化方法。 它最初是为了强制执行超级调用而创建的,以防止新手头痛。 (注意:它可能不支持初始化,而是结合一些强制测试以确保调用了super。)

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

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

 

1.3.10.解码方法

  public
  def decode(data)
    @lines.decode(data) do |line|
      replace = { "message" => line["message"].to_s + @append }
      yield LogStash::Event.new(replace)
    end
  end # def decode

编解码器的解码方法是将来自输入的数据转换为事件。 有诸如收集的编解码器之类的复杂示例,而诸如假脱机编解码器之类的较简单示例。

作为解码方法的一部分,必须有一个yield语句,该语句将已解码的事件返回到管道。

 

1.3.11.编码方法

  public
  def encode(event)
    @on_event.call(event, event.get("message").to_s + @append + NL)
  end # def encode

encode方法采用一个事件,并将其序列化(编码)为另一种格式。 编码方法的好例子包括简单的普通编解码器,涉及更多的msgpack编解码器,甚至是avro编解码器。

在大多数情况下,您的encode方法应具有@ on_event.call()语句。 该调用将以所述方式为每个事件输出数据。

 

1.3.12.编译插件

至此,您已经对插件进行了编码,并准备从中构建Ruby Gem。 以下信息将帮助您完成该过程。

 

1.3.13.外部依赖

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

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

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

vendor.json文件的另一个示例是geoip filter

下载这些依赖项的过程是致电rake供应商。 这将在本文档的测试部分中进一步讨论。

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

1.3.14.添加一个Gemfile文件

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

有关更多详细信息,请参见 Bundler’s Gemfile page

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

1.3.14.添加gemspec文件

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

可以在 Rubygems Specification page.上找到更多信息。

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

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

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

s.licenses和s.version也很重要,当您准备发布插件时它们就会起作用。

Logstash及其所有插件均根据 Apache License, version 2 ("ALv2")获得许可。 如果您通过RubyGems.org公开提供插件,请确保在gemspec中包含以下行:

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

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

1.3.15.运行时与开发

1.3.15.1.依存关系

gemspec文件的底部是带有注释的部分: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具有开发依赖性。

 

1.3.15.2.Jar依赖

在某些情况下,例如 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文件并下载指定的版本。

1.3.16.记录您的插件

文档是插件的重要组成部分。 所有插件文档都已呈现并放置在Logstash ReferenceVersioned plugin docs中。

有关提示和准则,请参阅Documenting your plugin

1.3.17.添加测试

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

关于RSpec的完整论述不在本文档范围之内。 在http://rspec.info上了解有关RSpec的更多信息

为了帮助您了解测试和测试,请查看其他几个类似插件的spec / codecs /目录。

1.3.18.克隆并测试!

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

  • 将您的插件克隆到一个临时位置将GITUSERNAME替换为您的github用户名,将MYPLUGINNAME替换为您的插件名。
    • git clone https://github.com/GITUSERNAME/logstash-codec-MYPLUGINNAME.git
      • 或者通过ssh:git clone git@github.com:GITUSERNAME / logstash-codec-MYPLUGINNAME.git
    • cd logstash-codec-MYPLUGINNAME

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

bundle install

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

rake vendor

最后,运行测试:

bundle exec rspec

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

Finished in 0.034 seconds
1 example, 0 failures

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

1.3.19.建造和测试

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

Build

您已经具备了所有必要的要素,所以让我们继续运行build命令:

gem build logstash-codec-example.gemspec

而已! 您的gem 应该被制造出来,并且与名称相同

logstash-codec-mypluginname-0.1.0.gem

gemspec文件中的s.version号将提供gem版本,在这种情况下为0.1.0。

1.3.20.测试安装

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

1.解压并进入目录:

curl -O https://download.elastic.co/logstash/logstash/logstash-7.4.1.tar.gz
tar xzvf logstash-7.4.1.tar.gz
cd logstash-7.4.1

2.使用插件工具,我们可以安装刚刚构建的gem。

  • 将/ my / logstash / plugins替换为适合您环境的gem路径,并将0.1.0替换为gemspec文件中的正确版本号。
bin/logstash-plugin install /my/logstash/plugins/logstash-codec-example/logstash-codec-example-0.1.0.gem
  • 运行此命令后,您应该看到Logstash已成功安装的反馈:
validating /my/logstash/plugins/logstash-codec-example/logstash-codec-example-0.1.0.gem >= 0
Valid logstash plugin. Continuing...
Successfully installed 'logstash-codec-example' with version '0.1.0'

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

bin/logstash-plugin list

根据安装的内容,您可能会看到一小段或一长段插件:输入,编解码器,过滤器和输出。

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

您的结果将取决于编解码器插件的功能。

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

示例编解码器插件将附加内容的附加内容(默认情况下会附加“,Hello World!”)

启动Logstash后,键入一些内容,例如“ Random output string”。 结果输出消息字段的内容应为“随机输出字符串,Hello World!”:

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

随时通过更改append参数进行实验和测试:

bin/logstash -e 'input { stdin{ codec => example{ append => ", I am appending this! }} } output {stdout { codec => rubydebug }}'

恭喜你! 您已经构建,部署并成功运行了Logstash编解码器。

 

1.3.21.将您的插件提交到RubyGems.org和logstash-plugins

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

Licensing

Logstash及其所有插件均根据Apache License, version 2 ("ALv2")获得许可。如果您通过RubyGems.org公开提供插件,请确保在gemspec中包含以下行:

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

1.3.22.发布到RubyGems.org

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

创建帐户后,请从RubyGems.org获取API密钥。 默认情况下,RubyGems使用〜/ .gem / credentials文件存储您的API密钥。 这些凭证将用于发布gem。 用您在RubyGems.org创建的凭据替换用户名和密码:

curl -u username:password https://rubygems.org/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

执行耙publish_gem:

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

而已! 您的插件已发布! Logstash用户现在可以通过运行以下命令来安装您的插件:

bin/logstash-plugin install logstash-codec-mypluginname

1.3.23.将您的源代码贡献给logstash-plugins

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

Benefits

将插件放在logstash-plugins存储库中的许多好处包括:

  • 发现。 您的插件将显示在Logstash参考中,Logstash用户将在其中首先查看插件和文档。
  • 文档。 您的插件文档将自动添加到Logstash参考。
  • 测试。 利用我们的测试基础架构,您的插件将针对当前和将来的Logstash版本进行持续测试。 结果,用户将保证,如果出现不兼容问题,将迅速发现并纠正它们。

1.3.24.验收准则

  • 代码审查。 您的插件必须由社区成员进行审查,以确保其一致性,质量,可读性,稳定性和安全性。
  • 测试。 您的插件必须包含要接受的测试。 这些测试也要接受代码审查的范围和完整性。 如果您不知道如何编写测试也可以。—我们将指导您。 我们正在发布有关为Logstash创建测试的指南,这将使它变得更加容易。 同时,您可以参考http://betterspecs.org/以获取示例。

要开始将插件迁移到Logstash插件,只需在Logstash存储库中创建一个新问题。 接受指南完成后,我们将使用推荐的github process来促进迁移到logstash-plugins组织。

1.4.如何编写Logstash过滤器插件

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

1.4.1.开始吧

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

为您的新插件创建GitHub存储库

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

  1. 登录到GitHub。
  2. 单击Repositories选项卡。您将看到您分叉或贡献的其他存储库的列表。
  3. 单击右上角的绿色“ New 按钮。
  4. 为您的新仓库指定以下设置:

    • 储存库名称  -表单的唯一名称logstash-filter-pluginname
    • 公共或私有  -您可以选择,但是如果您想将其作为正式插件提交,则存储库必须为公共。
    • 使用自述文件初始化此存储库  -使您可以立即将存储库克隆到计算机。
  5. 单击创建存储库

1.4.2.使用插件生成器工具

您现在可以在几秒钟内创建自己的Logstash插件!的generate子命令为bin/logstash-plugin具有模板文件的新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. 克隆{inputtype}插件示例,然后将其复制到您的插件分支。

    您不想包括示例.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

1.4.3.查看您的插件是什么样的

在深入探讨细节之前,请在您喜欢的文本编辑器中打开插件文件并进行查看。

# encoding: utf-8
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 # def register

  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 # def filter

end # class LogStash::Filters::Example

1.4.4.编码过滤器插件

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

encoding

这似乎是一件小事,但请记住在插件代码的开头指定编码:

# encoding: utf-8

Logstash取决于UTF-8中的内容,因此我们将其放在此处以告诉Ruby解释器我们将使用UTF-8编码。

require 陈述

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

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

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

1.4.5.插件主体

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

class 宣言

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

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

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

LogStash::Filters::Example

config_name

 config_name "example"

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

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

1.4.6.配置参数

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-信息性(也是Boolean truefalse
  • :obsolete-用于声明给定的设置已被删除并且不再起作用。这样做的目的是为仍在使用现已删除的设置的用户提供明智的升级途径。

1.4.7.插件方法

Logstash筛选器必须实现registerfilter方法。

register 方法

  public
  def register
  end # def register

Logstash register方法就像一种initialize方法。它最初是为了强制super打电话而创建的,可以防止新手头痛。(注意:initialize结合使用某些强制测试以确保super被调用,它可能不赞成。)

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

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

filter 方法

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 # def filter

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

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

field_foo = event.sprintf(field)

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

filter_matched(event)

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

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

1.4.7.编译插件

至此,您已经对插件进行了编码,并准备从中构建Ruby Gem。以下信息将帮助您完成该过程。

外部依赖

requireRuby中的语句用于包含必要的代码。在某些情况下,您的插件可能需要其他文件。例如,collected插件 使用types.db collectd提供 的文件。在插件的主目录中,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.json文件的另一个示例是 geoip过滤器

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

另一种外部依赖关系是对jar文件的依赖。这将在“添加gemspec文件”部分中进行描述。

1.4.7.1.添加一个Gemfile文件

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

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

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

1.4.8.新增gemspec档案

Gemspec定义了将要构建并包含您的插件的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 = "http://www.elastic.co/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.name并且s.summary应该反映您插件的名称和行为。

s.licenses并且s.version也很重要,当您准备发布插件时,它将发挥作用。

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

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

由指定的gem版本s.version有助于跟踪一段时间内对插件的更改。您应该将semver版本控制策略用于版本号。

1.4.9.运行时和开发依赖性

gemspec文件底部是带有注释的部分: Gem dependencies。这是必须提及任何其他需要的宝石的地方。如果您的插件正常运行需要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-apigem 有运行时依赖性,而对则具有开发依赖性logstash-devutils

1.4.10.Jar依赖

在某些情况下,例如 Elasticsearch输出插件,您的代码可能取决于jar文件。在这种情况下,依赖项将以这种方式添加到gemspec文件中:

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

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

1.4.11.记录您的插件

文档是插件的重要组成部分。所有插件文档均已呈现并放置在 Logstash参考Versioned插件文档中

有关提示和准则,请参阅记录插件

1.4.12.添加测试

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

关于RSpec的完整论述不在本文档范围之内。在http://rspec.info上了解有关RSpec的更多信息

为了帮助您了解测试和测试,请查看spec/filters/其他几个类似插件的 目录。

1.4.13.克隆并测试!

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

  • 将您的插件克隆到一个临时位置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

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

1.4.14.建造和测试

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

建立

您已经拥有所有必需的要素,因此让我们继续运行build命令:

gem build logstash-filter-example.gemspec

而已!您的宝石应该被制造出来,并且与名称相同

logstash-filter-mypluginname-0.1.0.gem

s.versiongemspec文件中的数字将提供gem版本,在这种情况下为0.1.0

测试安装

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

  1. 解压并进入目录:

    curl -O https://download.elastic.co/logstash/logstash/logstash-7.4.1.tar.gz
    tar xzvf logstash-7.4.1.tar.gz
    cd logstash-7.4.1
  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. 现在尝试使用带有通过-e标志通过命令行传递的简单配置来运行Logstash 。

    您的结果将取决于您的过滤器插件的功能。

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

stdin通过stdout使用rubydebug编解码器发送输入和输出(过滤后)来测试过滤器,从而提高了可读性。

对于示例过滤器插件,您发送的所有文本都将被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筛选器。

1.4.15.将您的插件提交到RubyGems.orglogstash-plugins

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

发牌

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

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

发布到RubyGems.org

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

创建帐户后,请 从RubyGems.org 获取 API密钥。默认情况下,RubyGems使用该文件~/.gem/credentials 存储您的API密钥。这些凭证将用于发布gem。更换usernamepassword与该凭证你RubyGems.org创建:

curl -u username:password https://rubygems.org/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. 建造宝石
  4. 将宝石发布到RubyGems.org

而已!您的插件已发布!Logstash用户现在可以通过运行以下命令来安装您的插件:

bin/logstash-plugin install logstash-filter-mypluginname

1.4.16.将您的源代码贡献给logstash-plugins

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

好处

将插件放在logstash-plugins存储库中的许多好处包括:

  • 发现。您的插件将显示在 Logstash参考中,Logstash用户将在其中首先查看插件和文档。
  • 文档。您的插件文档将自动添加到 Logstash参考中
  • 测试。利用我们的测试基础架构,您的插件将针对当前和将来的Logstash版本进行持续测试。结果,用户将保证,如果出现不兼容问题,将迅速发现并纠正它们。

验收准则

  • 代码审查。您的插件必须由社区成员进行审查,以确保其一致性,质量,可读性,稳定性和安全性。
  • 测试。您的插件必须包含要接受的测试。这些测试也要接受代码审查的范围和完整性。如果您不知道如何编写测试也可以,我们会为您提供指导。我们正在发布有关为Logstash创建测试的指南,这将使它变得更加容易。同时,您可以参考 http://betterspecs.org/以获取示例。

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


1.5.如何编写Logstash输出插件

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

1.5.1.开始吧

让我们逐步使用示例输出插件创建输出插件

为您的新插件创建GitHub存储库

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

  1. 登录到GitHub。
  2. 单击Repositories 选项卡。您将看到您分叉或贡献的其他存储库的列表。
  3. 单击右上角的绿色“ New按钮。
  4. 为您的新仓库指定以下设置:

    • 储存库名称  -表单的唯一名称logstash-output-pluginname
    • 公共或私有  -您可以选择,但是如果您想将其作为正式插件提交,则存储库必须为公共。
    • 使用自述文件初始化此存储库  -使您可以立即将存储库克隆到计算机。
  5. 单击创建存储库

使用插件生成器工具

您现在可以在几秒钟内创建自己的Logstash插件!的generate子命令为bin/logstash-plugin具有模板文件的新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. 克隆{inputtype}插件示例,然后将其复制到您的插件分支。

    您不想包括示例.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

查看您的插件是什么样的

在深入探讨细节之前,请在您喜欢的文本编辑器中打开插件文件并进行查看。

# encoding: utf-8
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 # def register

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

1.5.2.编码输出插件

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

encoding

这似乎是一件小事,但请记住在插件代码的开头指定编码:

# encoding: utf-8

Logstash取决于UTF-8中的内容,因此我们将其放在此处以告诉Ruby解释器我们将使用UTF-8编码。

require 陈述

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

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

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

1.5.3.插件主体

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

class 宣言

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

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

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

LogStash::Outputs::Example

config_name

 config_name "example"

这是您的插件将在输出配置块中调用的名称。

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

1.5.4.配置参数

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-信息性(也是Boolean truefalse
  • :obsolete-用于声明给定的设置已被删除并且不再起作用。这样做的目的是为仍在使用现已删除的设置的用户提供明智的升级途径。

1.5.5.插件方法

Logstash输出必须实现registermulti_receive方法。

register 方法

  public
  def register
  end # def register

Logstash register方法就像一种initialize方法。它最初是为了强制super打电话而创建的,可以防止新手头痛。(注意:initialize结合使用某些强制测试以确保super被调用,它可能不赞成。)

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

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

1.5.6.编译插件

至此,您已经对插件进行了编码,并准备从中构建Ruby Gem。以下信息将帮助您完成该过程。

外部依赖

requireRuby中的语句用于包含必要的代码。在某些情况下,您的插件可能需要其他文件。例如,collected插件 使用types.db collectd提供 的文件。在插件的主目录中,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.json文件的另一个示例是 geoip过滤器

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

另一种外部依赖关系是对jar文件的依赖。这将在“添加gemspec文件”部分中进行描述。

1.5.6.1.添加一个宝石文件

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

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

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

1.5.7.新增gemspec档案

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 = "http://www.elastic.co/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.name并且s.summary应该反映您插件的名称和行为。

s.licenses并且s.version也很重要,当您准备发布插件时,它将发挥作用。

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

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

由指定的gem版本s.version有助于跟踪一段时间内对插件的更改。您应该将semver版本控制策略用于版本号。

1.5.7.1.运行时和开发依赖性

gemspec文件底部是带有注释的部分: Gem dependencies。这是必须提及任何其他需要的宝石的地方。如果您的插件正常运行需要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-apigem 有运行时依赖性,而对则具有开发依赖性logstash-devutils

1.5.7.2.Jar依赖

在某些情况下,例如 Elasticsearch输出插件,您的代码可能取决于jar文件。在这种情况下,依赖项将以这种方式添加到gemspec文件中:

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

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

1.5.8.记录您的插件

文档是插件的重要组成部分。所有插件文档均已呈现并放置在 Logstash参考Versioned插件文档中

有关提示和准则,请参阅记录插件

1.5.9.添加测试

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

关于RSpec的完整论述不在本文档范围之内。在http://rspec.info上了解有关RSpec的更多信息

为了帮助您了解测试和测试,请查看spec/outputs/其他几个类似插件的 目录。

1.5.10.克隆并测试!

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

  • 将您的插件克隆到一个临时位置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

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

1.5.11.建造和测试

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

建立

您已经拥有所有必需的要素,因此让我们继续运行build命令:

gem build logstash-output-example.gemspec

而已!您的宝石应该被制造出来,并且与名称相同

logstash-output-mypluginname-0.1.0.gem

s.versiongemspec文件中的数字将提供gem版本,在这种情况下为0.1.0

测试安装

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

  1. 解压并进入目录:

    curl -O https://download.elastic.co/logstash/logstash/logstash-7.4.1.tar.gz
    tar xzvf logstash-7.4.1.tar.gz
    cd logstash-7.4.1
  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. 现在尝试使用带有通过-e标志通过命令行传递的简单配置来运行Logstash 。

    您的结果将取决于您的输出插件的功能。

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

1.5.12.将您的插件提交到RubyGems.orglogstash-plugins

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

发牌

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

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

发布到RubyGems.org

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

创建帐户后,请 从RubyGems.org 获取 API密钥。默认情况下,RubyGems使用该文件~/.gem/credentials 存储您的API密钥。这些凭证将用于发布gem。更换usernamepassword与该凭证你RubyGems.org创建:

curl -u username:password https://rubygems.org/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. 建造宝石
  4. 将宝石发布到RubyGems.org

而已!您的插件已发布!Logstash用户现在可以通过运行以下命令来安装您的插件:

bin/logstash-plugin install logstash-output-mypluginname

1.5.13.将您的源代码贡献给logstash-plugins

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

好处

将插件放在logstash-plugins存储库中的许多好处包括:

  • 发现。您的插件将显示在 Logstash参考中,Logstash用户将在其中首先查看插件和文档。
  • 文档。您的插件文档将自动添加到 Logstash参考中
  • 测试。利用我们的测试基础架构,您的插件将针对当前和将来的Logstash版本进行持续测试。结果,用户将保证,如果出现不兼容问题,将迅速发现并纠正它们。

验收准则

  • 代码审查。您的插件必须由社区成员进行审查,以确保其一致性,质量,可读性,稳定性和安全性。
  • 测试。您的插件必须包含要接受的测试。这些测试也要接受代码审查的范围和完整性。如果您不知道如何编写测试也可以,我们会为您提供指导。我们正在发布有关为Logstash创建测试的指南,这将使它变得更加容易。同时,您可以参考 http://betterspecs.org/以获取示例。

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

1.6.记录你的插件

带有良好示例的质量文档有助于您使用插件。

您为插件编写的文档将在Logstash参考和 Logstash版本化插件参考中生成并发布。

1.6.1.文档文件

文档是插件的必需组件。它属于一个名为docs / index.asciidoc的文件。该插件生成实用程序为您创建一个启动文件。

1.6.2.标题ID

使用可以支持生成的ID的变量格式化标题锚。 构建Logstash版本控制插件参考时,此方法将创建唯一的ID 。需要唯一的标题ID,以避免在多个版本的插件上重复。

不要像这样硬编码标题ID: [[config_models]]

而是使用变量来定义它:

[id="plugins-{type}s-{plugin}-config_models"]
==== Configuration models

如果您对ID进行硬编码,则“ Logstash版本控制插件参考” 将在第一次正确构建。第二次运行文档构建时,该ID被标记为重复,并且构建失败。

1.6.3.链接的格式

正确的链接格式对于将用户定向到您希望他们看到的内容至关重要。错误的链接格式或重复的链接可能会破坏文档版本。我们不要那样做。

链接到内容在同一个文件

使用尖括号将链接的格式设置为同一asciidoc文件中的内容。

该链接:

<<plugins-{type}s-{plugin}-config_models>>

指向同一文件中的此标题:

[id="plugins-{type}s-{plugin}-config_models"]
==== Configuration models

链接到内容的Logstash参考指南

使用外部链接语法获取指向《 Logstash参考指南》中其他插件或内容的文档的链接。

例子

{logstash-ref}/plugins-codecs-multiline.html[Multiline codec plugin]
{logstash-ref}/getting-started-with-logstash.html

链接文字

如果不指定链接文本,则将URL用作链接文本。

例子

如果您希望链接显示为https://www.elastic.co/guide/en/logstash/7.4/getting-started-with-logstash.html,请使用以下格式:

{logstash-ref}/getting-started-with-logstash.html

如果您希望链接显示为Logstash入门,请使用以下格式:

{logstash-ref}/getting-started-with-logstash.html[Getting Started with Logstash]

链接到数据类型描述

对于指向诸如的数据类型描述的链接,我们将其作为例外<<boolean,boolean>>,因为它们是如此频繁地使用。我们在转换脚本中有一个清理步骤,可以将链接转换为正确的语法。

1.6.4.代码示例

我们都喜欢代码示例。Asciidoc支持代码块和配置示例。要包含Ruby代码,请使用asciidoc [source,ruby]指令。

请注意,使用井号(#)可以使示例正确呈现。不要在asciidoc文件中包含井号。

# [source,ruby]
# -----
# match => {
#  "field1" => "value1"
#  "field2" => "value2"
#  ...
# }
# -----

上面的示例(除去了井号)在文档中的呈现方式如下:

match => {
  "field1" => "value1"
  "field2" => "value2"
  ...
}

1.6.5.我的文档在哪里?

在《Logstash版本控制插件参考》和《Logstash参考》中发布插件文档之前,需要经过几个步骤 。

以下是工作流程的概述:

  • 确保已签署CLI,并获得所有必要的批准和签字。
  • 合并对插件的拉取请求(包括index.asciidoc文件,changelog.md文件和gemspec)。
  • 等待持续集成构建成功完成。
  • 将插件发布到https://rubygems.org
  • 脚本会检测到新版本或更改的版本,并选择index.asciidoc要包含在文档版本中的文件。
  • 您的新插件的文档发布在Logstash Versioned Plugin Reference中

我们还没有完成。

  • 对于每个版本,我们将新的和更改的文档文件打包到请求请求中,以添加或更新内容。(如果我们对插件文档进行了重大更改或添加了新插件,有时会在发行版之间打包插件文档。)
  • 该脚本将检测新版本或更改的版本,并选择index.asciidoc要包含在doc版本中的文件。
  • 我们创建一个拉取请求,并将新的和更改的内容合并到适当的版本分支中。
  • 对于新插件,我们在Logstash参考中添加了指向插件列表的链接。
  • 您的新(或更改)插件的文档发布在Logstash参考中

文档或插件更新

在更新插件或文档时,请考虑在变更日志和gemspec(或版本文件)中增加版本号。版本更改会触发文档构建,以选择要发布的更改。

1.6.6.资源

有关更多asciidoc格式化技巧,请参阅https://github.com/elastic/docs#asciidoc-guide上的出色参考。

有关贡献和变更日志指南的提示,请参阅 CONTRIBUTING.md

有关贡献的一般信息,请参阅 贡献给Logstash

1.7.贡献补丁到Logstash插件

本节讨论了成功向Logstash插件贡献补丁所需的信息。

每个插件定义了自己的配置选项。这些在某种程度上控制了插件的行为。配置选项定义通常包括:

  • 资料验证
  • 默认值
  • 任何必需的标志

插件是Logstash基类的子类。插件的基类定义了常见的配置和方法。

1.7.1.输入插件

输入插件从外部源获取数据。输入插件始终与编解码器关联。输入插件始终具有关联的编解码器插件。输入和编解码器插件一起运行以创建Logstash事件并将该事件添加到处理队列中。输入编解码器是LogStash::Inputs::Base该类的子类。

表2.输入API

#register() -> nil

需要。该API为插件设置资源,通常是与外部源的连接。

#run(queue) -> nil

需要。该API获取或侦听源数据,通常循环播放直到停止。必须处理循环内的错误。将所有创建的事件推送到方法参数中指定的队列对象。某些输入可能会接收批量数据,以最大程度地减少外部呼叫开销。

#stop() -> nil

可选的。停止外部连接并进行清理。

1.7.2.编解码器插件

编解码器插件解码具有特定结构的输入数据,例如JSON输入数据。编解码器插件是的子类LogStash::Codecs::Base

表3.编解码器API

#register() -> nil

与输入插件的同名API相同。

#decode(data){|event| block} -> nil

必须执行。用于根据方法参数中给出的原始数据创建事件。必须处理错误。调用者必须提供一个Ruby块。使用创建的事件调用该块。

#encode(event) -> nil

需要。用于根据给定事件创建结构化数据对象。可能会处理错误。此方法调用一个先前存储为@on_event的块,带有两个参数:原始事件和数据对象。

1.7.3.过滤插件

一种更改,变异或合并一个或多个事件的机制。过滤器插件是LogStash::Filters::Base 该类的子类。

表4.过滤器API

#register() -> nil

与输入插件的同名API相同。

#filter(event) -> nil

需要。可能会处理错误。用于将突变函数应用于给定事件。

1.7.4.输出插件

一种将事件发送到外部目标的机制。此过程可能需要序列化。输出插件是LogStash::Outputs::Base该类的子类。

表5.输出API

#register() -> nil

与输入插件的同名API相同。

#receive(event) -> nil

需要。必须处理错误。用于准备给定事件以传输到外部目标。一些输出可以缓冲准备好的事件以批量传输到目的地。

1.7.5.流程

确定了错误或功能。在插件存储库中创建了一个问题。创建补丁并提交拉取请求(PR)。经过审查和可能的返工后,PR被合并并发布了插件。

社区维护者指南》更详细地说明了接受,合并和发布补丁的过程。《社区维护者指南》还详细说明了贡献者和维护者应扮演的角色。

1.7.6.测试方法

1.7.6.1.测试驱动开发

测试驱动开发,俗称TDD,描述了一种使用测试来指导源代码演变的方法。就我们的目的而言,我们只打算使用其中的一部分,即在编写修复程序之前-我们创建测试来通过失败来说明错误。当我们编写了足够的代码以使测试通过并提交修补程序和测试作为补丁时,我们停止。不必在修复之前编写测试,但是在事后编写通过测试很容易,因为通过测试可能无法真正验证故障是否已真正修复,特别是如果可以通过多个执行路径或变化的输入数据触发故障的话。

RSpec框架

Logstash使用Ruby测试框架Rspec来定义和运行测试套件。以下是各种来源的摘要。

  1. Rspec示例

     1 # encoding: utf-8
     2 require "logstash/devutils/rspec/spec_helper"
     3 require "logstash/plugin"
     4
     5 describe "outputs/riemann" do
     6   describe "#register" do
     7     let(:output) do
     8       LogStash::Plugin.lookup("output", "riemann").new(configuration)
     9     end
    10
    11     context "when no protocol is specified" do
    12       let(:configuration) { Hash.new }
    13
    14       it "the method completes without error" do
    15         expect {output.register}.not_to raise_error
    16       end
    17     end
    18
    19     context "when a bad protocol is specified" do
    20       let(:configuration) { {"protocol" => "fake"} }
    21
    22       it "the method fails with error" do
    23         expect {output.register}.to raise_error
    24       end
    25     end
    26
    27     context "when the tcp protocol is specified" do
    28       let(:configuration) { {"protocol" => "tcp"} }
    29
    30       it "the method completes without error" do
    31         expect {output.register}.not_to raise_error
    32       end
    33     end
    34   end
    35
    36   describe "#receive" do
    37     let(:output) do
    38       LogStash::Plugin.lookup("output", "riemann").new(configuration)
    39     end
    40
    41     context "when operating normally" do
    42       let(:configuration) { Hash.new }
    43       let(:event) do
    44         data = {"message"=>"hello", "@version"=>"1",
    45                 "@timestamp"=>"2015-06-03T23:34:54.076Z",
    46                 "host"=>"vagrant-ubuntu-trusty-64"}
    47         LogStash::Event.new(data)
    48       end
    49
    50       before(:example) do
    51         output.register
    52       end
    53
    54       it "should accept the event" do
    55         expect { output.receive event }.not_to raise_error
    56       end
    57     end
    58   end
    59 end

描述块(示例1中的第5、6和36行)。 

describe(string){block} -> nil
describe(Class){block} -> nil

 

使用RSpec,我们总是在描述插件方法的行为。describe块添加在逻辑部分中,并且可以接受现有的类名或字符串。第5行中使用的字符串是插件名称。第6行是寄存器方法,第36行是接收方法。RSpec约定是在实例方法上添加一个哈希值,在类方法上添加一个点前缀。

上下文块(第11、19、27和41行)。 

context(string){block} -> nil

 

在RSpec中,上下文块定义了按变体对测试进行分组的部分。字符串应以单词开头when ,然后详细说明变体。参见第11行。内容块中的测试应仅适用于该版本。

让块(第7、12、20、28、37、42和43行)。 

let(symbol){block} -> nil

 

在RSpec中,let块定义用于测试块的资源。对于每个测试块,将重新初始化这些资源。它们可用作测试块中的方法调用。letdescribecontext块中定义块,以限定该let块和任何其他嵌套块的范围。您可以使用let稍后在let块体内定义的其他方法。请参阅第7-9行,它们定义了输出资源并使用配置方法,在第12、20和28行中定义了不同的变体。

在块之前(第50行)。 

before(symbol){block} -> nil - symbol is one of :suite, :context, :example, but :all and :each are synonyms for :suite and :example respectively.

 

在RSpec中,before块用于进一步设置将在let块中初始化的任何资源。您不能在let块内定义before块。

您还可以定义after块,这些块通常用于清除由before块执行的任何设置活动。

它会阻塞(第14、22、30和54行)。 

it(string){block} -> nil

 

在RSpec中,it块设置了期望,以验证所测试代码的行为。该字符串不应以开头 或应该以,但需要表达期望的结果。当放在一起从封闭的文本描述,contextit块应该形成一个相当可读语句,如在线路5,6,11和14:

outputs/riemann
#register when no protocol is specified the method completes without error

这样的可读代码使测试目标易于理解。

预期方法(第15、23、31、55行)。 

expect(object){block} -> nil

 

在RSpec中,Expect方法验证一条语句,该语句将实际结果与预期结果进行比较。该expect方法通常与对toor not_to方法的调用配对。预期错误或观察更改时,请使用块形式。该tonot_to方法需要一个matcher封装了该预期值对象。该expect方法的参数形式封装了实际值。当放在一起时,整条线将实际值与预期值进行测试。

匹配器方法(第15、23、31、55行)。 

raise_error(error class|nil) -> matcher instance
be(object) -> matcher instance
eq(object) -> matcher instance
eql(object) -> matcher instance
  for more see http://www.relishapp.com/rspec/rspec-expectations/docs/built-in-matchers

 

在RSpec中,匹配器是由等效方法调用(即eq)生成的对象,该对象将用于根据实际值评估期望值。

1.7.7.放在一起

这个例子修复的问题在ZeroMQ输出插件。该问题不需要ZeroMQ的知识。

本示例中的活动具有以下先决条件:

  • 对Git和Github的基本了解。参见Github新兵训练营
  • 文本编辑器。
  • 一个JRuby 运行时 环境。该chruby工具管理Ruby版本。
  • JRuby 1.7.22或更高版本。
  • bundlerrake宝石安装。
  • 已安装 ZeroMQ 。
  1. 在Github中,派生ZeroMQ 输出插件存储库
  2. 在本地计算机上,将fork 克隆到一个已知文件夹,例如 logstash/
  3. 在文本编辑器中打开以下文件:

    • logstash-output-zeromq/lib/logstash/outputs/zeromq.rb
    • logstash-output-zeromq/lib/logstash/util/zeromq.rb
    • logstash-output-zeromq/spec/outputs/zeromq_spec.rb
  4. 根据该问题,服务器模式下的日志输出必须指示bound。此外,测试文件不包含任何测试。

    util/zeromq.rb读取的第21行@logger.info("0mq: #{server? ? 'connected' : 'bound'}", :address => address)

  5. 在文本编辑器,设置文件编码,并要求zeromq.rb该文件zeromq_spec.rb中加入以下几行:

    # encoding: utf-8
    require "logstash/outputs/zeromq"
    require "logstash/devutils/rspec/spec_helper"
  6. 所需的错误消息应显示为:

    LogStash::Outputs::ZeroMQ when in server mode a 'bound' info line is logged

    要正确生成此消息,请添加一个describe以完全限定的类名作为参数的块,一个上下文块和一个it块。

    describe LogStash::Outputs::ZeroMQ do
      context "when in server mode" do
        it "a 'bound' info line is logged" do
        end
      end
    end
  7. 要添加缺少的测试,请使用ZeroMQ输出的实例和替代的记录器。本示例使用称为测试双打的RSpec功能作为替代记录器。

    添加以下行zeromq_spec.rb,之后describe LogStash::Outputs::ZeroMQ do和之前context "when in server mode" do

     let(:output) { described_class.new("mode" => "server", "topology" => "pushpull" }
      let(:tracer) { double("logger") }
  8. 将主体添加到it块中。在该行之后添加以下五行context "when in server mode" do

     allow(tracer).to receive(:debug)
          output.logger = logger
          expect(tracer).to receive(:info).with("0mq: bound", {:address=>"tcp://127.0.0.1:2120"})
          output.register
          output.do_close

 

允许double接收debug方法调用。

 

使输出使用测试的两倍。

 

对测试设置期望以接收info方法调用。

 

调用register输出。

 

调用do_close输出,以便测试不会挂起。

在修改结束时,相关代码部分显示为:

# encoding: utf-8
require "logstash/outputs/zeromq"
require "logstash/devutils/rspec/spec_helper"

describe LogStash::Outputs::ZeroMQ do
  let(:output) { described_class.new("mode" => "server", "topology" => "pushpull") }
  let(:tracer) { double("logger") }

  context "when in server mode" do
    it "a ‘bound’ info line is logged" do
      allow(tracer).to receive(:debug)
      output.logger = tracer
      expect(tracer).to receive(:info).with("0mq: bound", {:address=>"tcp://127.0.0.1:2120"})
      output.register
      output.do_close
    end
  end
end

要运行此测试:

  1. 打开终端窗口
  2. 导航到克隆的插件文件夹
  3. 第一次运行测试时,运行命令 bundle install
  4. 运行命令 bundle exec rspec

假设所有先决条件均已正确安装,则测试失败,输出类似于:

Using Accessor#strict_set for specs
Run options: exclude {:redis=>true, :socket=>true, :performance=>true, :couchdb=>true, :elasticsearch=>true,
:elasticsearch_secure=>true, :export_cypher=>true, :integration=>true, :windows=>true}

LogStash::Outputs::ZeroMQ
  when in server mode
    a ‘bound’ info line is logged (FAILED - 1)

Failures:

  1) LogStash::Outputs::ZeroMQ when in server mode a ‘bound’ info line is logged
     Failure/Error: output.register
       Double "logger" received :info with unexpected arguments
         expected: ("0mq: bound", {:address=>"tcp://127.0.0.1:2120"})
              got: ("0mq: connected", {:address=>"tcp://127.0.0.1:2120"})
     # ./lib/logstash/util/zeromq.rb:21:in `setup'
     # ./lib/logstash/outputs/zeromq.rb:92:in `register'
     # ./lib/logstash/outputs/zeromq.rb:91:in `register'
     # ./spec/outputs/zeromq_spec.rb:13:in `(root)'
     # /Users/guy/.gem/jruby/1.9.3/gems/rspec-wait-0.0.7/lib/rspec/wait.rb:46:in `(root)'

Finished in 0.133 seconds (files took 1.28 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/outputs/zeromq_spec.rb:10 # LogStash::Outputs::ZeroMQ when in server mode a ‘bound’ info line is logged

Randomized with seed 2568

要更正错误,请util/zeromq.rb在文本编辑器中打开文件,connected 并bound在第21行交换单词的位置。第21行现在显示为:

@logger.info("0mq: #{server? ? 'bound' : 'connected'}", :address => address)

使用bundle exec rspec命令再次运行测试。

测试通过,输出类似于:

Using Accessor#strict_set for specs
Run options: exclude {:redis=>true, :socket=>true, :performance=>true, :couchdb=>true, :elasticsearch=>true, :elasticsearch_secure=>true, :export_cypher=>true, :integration=>true, :windows=>true}

LogStash::Outputs::ZeroMQ
  when in server mode
    a ‘bound’ info line is logged

Finished in 0.114 seconds (files took 1.22 seconds to load)
1 example, 0 failures

Randomized with seed 45887

将更改提交到git和Github。

您的拉取请求从 原始Github存储库的“ 拉取请求”部分可见。插件维护者会审查您的工作,在必要时提出更改建议,并合并和发布新版本的插件。

1.8.Logstash插件社区维护者指南

新的维护人员应阅读该文档,并应说明其职责。它的灵感来自ZeroMQ项目的 C4文档。本文档随时可能更改,并通过“拉取请求”提出建议,强烈建议您提出问题。

1.8.1.贡献准则

有关贡献给Logstash插件的一般指导,请参阅 贡献给Logstash一节。

1.8.2.文件目标

为了使Logstash插件社区易于参与并获得积极的反馈。

增加多样性。

为了减少代码审查,通过向社区和维护者提供支持和工具来合并和释放对核心团队的依赖性。

支持插件的自然生命周期。

整理以下人员的角色和职责:维护者和贡献者,特别关注补丁程序测试,代码审查,合并和发布。

1.8.3.开发流程

必须使用Github问题追踪器来追踪所有问题和拉取请求。

该插件使用Apache 2.0许可证。维护人员应检查补丁程序是否引入了许可证不兼容的代码。补丁所有权和版权在弹性 贡献者许可协议(CLA)中定义。

术语

“贡献者”是一个人在提供补丁时承担的角色。贡献者将无权访问存储库。他们需要先签署Elastic Contributor许可协议, 然后才能查看补丁。贡献者可以将自己添加到插件的贡献者列表中。

“维护者”是一个人在维护插件并保持其健康(包括分类问题以及查看和合并补丁程序)时所扮演的角色。

修补程序要求

补丁程序是对已确定并已达成共识的问题的最小且准确的答案。它必须符合 代码样式准则,并且必须包括RSpec测试,以验证解决方案的适用性。

CI系统将自动测试补丁,并报告“拉取请求”状态。

补丁程序CLA将被自动验证,并在请求请求状态中报告。

补丁提交消息的第一行只有一小段(少于50个字符),概述了更改,第二行是空白,并包含更改说明和基本原理所需的任何其他行。

补丁满足以上要求时可以合并,并且至少已由其他人进行了正面评价。

开发过程

用户将在问题跟踪器上记录问题,并尽可能详细地描述他们面临或观察到的问题。

为了解决问题,贡献者分叉了插件存储库,然后在其分叉的存储库上工作,并通过创建向插件的拉回请求来提交补丁。

维护者不得在作者未签署CLA的地方合并补丁。

在接受补丁之前,应先对其进行审核。维护人员应立即合并已接受的补丁。

维护人员不应合并自己的补丁,除非在特殊情况下,例如其他维护人员或核心团队的响应时间过长(超过2周)。

评论者的评论不应基于个人喜好。

维护者应在“问题”和“拉取请求”上加标签。

如果需要帮助以达成共识,维护人员应让核心团队参与。

以与源代码更改相同的方式查看非源代码更改,例如文档。

分公司管理

该插件有一个master分支,该分支始终保存最新的正在进行中的版本,并且应该始终进行构建。主题分支应保持最小。

更新日志管理

每个插件都应该有一个变更日志(CHANGELOG.md)。如果没有,请创建一个。对插件进行更改时,请确保在相应版本下包括一个更改日志条目以记录更改。从用户的角度来看,变更日志应该易于理解。随着我们快速迭代和发布插件,用户将更改日志用作决定是否更新的机制。

不是面向用户的更改应标记为internal:。例如:

- internal: Refactored specs for better testing
- config: Default timeout configuration changed from 10s to 5s

CHANGELOG.md的详细格式

在插件中共享类似格式的CHANGELOG.md可简化用户的可读性。请参阅以下带注释的示例,并在logstash-filter-date中查看具体示例。

## 1.0.x                              
 - change description                 
 - tag: change description            
 - tag1,tag2: change description      
 - tag: Multi-line description        
   must be indented and can use
   additional markdown syntax
                                      
## 1.0.0                              
[...]

最新版本是CHANGELOG.md的第一行。每个版本标识符应为使用以下内容的2级标头##

一个更改描述被描述为列表项,使用-在版本标识符下方对齐的破折号

可以用一个单词标记一个更改,并在其后缀:。常见的标签bugfixfeaturedoctestinternal

一项更改可以使多个标签之间用逗号分隔,并以 :

多行更改描述必须适当缩进

请注意用空行分隔版本

先前版本标识符

持续集成

插件是使用自动连续集成(CI)环境设置的,每个Github页面上都应该有一个相应的标志。如果丢失,请联系Logstash核心团队。

打开的每个“拉取请求”都会自动触发配置项运行。要进行手动运行,请在请求请求中注释“ Jenkins,请对此进行测试。”

1.8.4.版本插件

Logstash核心及其插件具有单独的产品开发生命周期。因此,不必对内核和插件的版本控制和发布策略进行调整。实际上,这是在Logstash 1.5中极大地分离插件工作期间的目标之一。

有时,Logstash中的核心API会发生变化,这需要大量更新插件才能反映出核心的变化。但是,这种情况并不经常发生。

对于插件,我们希望遵循一种版本控制和发布策略,以便更好地向我们的用户通知Logstash配置格式和功能的任何重大更改。

插件发行遵循三位编号方案XYZ,其中X表示主要发行版本,这可能会破坏与现有配置或功能的兼容性。Y表示包含向后兼容功能的发行版。Z表示包含错误修复和修补程序的发行版。

更改版本

可以在Gemspec中更改版本,该版本需要与变更日志条目关联。之后,我们可以将gem手动发布到RubyGem.org。此时,只有核心开发人员才能发布gem。

标签

标签是维护插件的关键方面。GitHub中的所有问题均应正确标记,以便:

  • 向用户/开发人员提供良好的反馈
  • 帮助确定变更的优先级
  • 在发行说明中使用

多数标签是不言自明的,但是以下是一些重要标签的简要介绍:

  • bug:将问题标记为意外缺陷
  • needs details:如果问题报告者的详细信息不完整,请询问他们更多信息,并在需要的地方加上标签。
  • missing cla:缺少“贡献者许可协议”,没有它就无法接受补丁
  • adopt me:请社区寻求帮助以解决此问题
  • enhancement:新功能,不是错误修复
  • needs tests:补丁程序没有测试,没有单元/集成测试就无法接受
  • docs:文档相关问题/ PR

1.8.5.记录

尽管不要因为过多的日志记录而降低性能,这一点很重要,但是在诊断和解决Logstash问题时,调试级别的日志可能会非常有用。请记住,只要有意义,就随意添加调试日志,因为用户将永远友好。

@logger.debug("Logstash loves debug logs!", :actions => actions)

1.8.6.贡献者许可协议(CLA)指南

1.

为什么需要CLA

 

我们要求所有贡献者都这样做,以确保我们的用户知道代码的起源和持续存在。我们并不是在要求贡献者将版权转让给我们,而是让我们有权不受限制地分发贡献者的代码。

2.

在检查PR和提交之前,请确保CLA已由每个贡献者签名。

 

贡献者只需要签署一次CLA,并使用与Github中相同的电子邮件进行签署。如果贡献者在提交PR后签署了CLA,则他们可以在签名5分钟后通过在PR上添加另一条评论来刷新自动CLA检查器。

1.8.7.需要帮忙?

在Github上Ping @ logstash-core,以引起Logstash核心团队的注意。

1.8.8.社区管理

核心团队在那里为插件维护者和整个生态系统提供支持。

维护者应建议贡献者成为维护者。

贡献者和维护者应遵循弹性社区行为准则。核心团队应阻止或禁止“坏演员”。

1.9.提交你的插件RubyGems.org和logstash,插件库

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

1.9.1.许可

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

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

1.9.2.发布到RubyGems.org

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

创建帐户后,请 从RubyGems.org 获取 API密钥。默认情况下,RubyGems使用该文件~/.gem/credentials 存储您的API密钥。这些凭证将用于发布gem。更换usernamepassword与该凭证你RubyGems.org创建:

curl -u username:password https://rubygems.org/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. 建造宝石
  4. 将宝石发布到RubyGems.org

而已!您的插件已发布!Logstash用户现在可以通过运行以下命令来安装您的插件:

bin/plugin install logstash-output-mypluginname

1.9.3.将您的源代码贡献给logstash-plugins

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

1.9.4.好处

将插件放在logstash-plugins存储库中的许多好处包括:

  • 发现您的插件将出现在 Logstash参考中,Logstash用户将在其中首先查看插件和文档。
  • 文档您的插件文档将自动添加到 Logstash参考中
  • 测试使用我们的测试基础架构,您的插件将针对当前和将来的Logstash版本进行持续测试。结果,用户将保证,如果出现不兼容问题,将迅速发现并纠正它们。

1.9.5.验收准则

  • 代码审查必须由社区成员审查您的插件的一致性,质量,可读性,稳定性和安全性。
  • 测试您的插件必须包含要接受的测试。这些测试也要接受代码审查的范围和完整性。如果您不知道如何编写测试也可以,我们会为您提供指导。我们正在发布有关为Logstash创建测试的指南,这将使它变得更加容易。同时,您可以参考 http://betterspecs.org/以获取示例。

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

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值