为Java开发人员启动Logstash插件开发

我最近对Logstash感兴趣,在玩了一段时间之后,我决定创建自己的自定义插件以供学习。 我选择从Reddit中提取数据是因为a)我经常使用它并且b)尚无提供此功能的插件。<!-more-→

Elasticsearch站点提供了详尽的文档来创建自己的Logstash插件。 这种努力需要Ruby技术-不仅是语言语法,而且还包括生态系统。 预期该站点假定读者熟悉两者。 不幸的是,这不是我的情况。 我一直在用Java开发很多东西,我在Scala涉猎了一些,我对Kotlin很有兴趣-最后,我只是一个JMV开发人员(这里和那里有一些Javascript)。 长话短说,我从Ruby开始。

在此阶段,有两种可能的方法:

  1. 阅读有关Ruby,Gems,bundler,整个九码的文档和教程,并在几个月(或更长时间)后回来
  2. 或通过潜入开发现场学习

鉴于我没有几个月,而且我所学的都足够好,所以我选择了第二个选项。 这篇文章是我经过的步骤的总结,希望它可以使遇到同样情况的其他人受益。

第一步不是最难的

尽管可以从头开始使用新的Logstash插件,但文档建议从模板开始。 在线过程中对此进行了说明。 这一代产生以下结构:

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

对于Ruby新手而言,并不是很明显,该结构是Ruby Gem之一 。 通常,依赖项在关联的Gemfile中声明:

source 'https://rubygems.org'
gemspec

但是,在这种情况下, gemspec指令添加了一个附加的间接级别。 在关联的gemspec文件中不仅声明依赖项,还声明元数据。 这是Bundler实用工具gem的功能。

要安装依赖项,首先需要安装bundler gem。 是的,有摩擦...

Ruby是极限

尝试安装gem会产生以下结果:

 gem install bundler
Fetching: bundler-1.13.6.gem (100%)
ERROR:  While executing gem ... (TypeError)
    no implicit conversion of nil into String

第一个实现-花费了很多时间(浏览和阅读),是Ruby运行时有不同的风格。 简单的Ruby是不够的,Logstash插件开发:它需要一个专门的运行在JVM上运行又名 JRuby的

第二个认识是,虽然在一台机器上安装多个Ruby运行时很容易,但不可能同时运行它们。 尽管Homebrew使jruby软件包可用,但似乎每个系统只有一个gem仓库,并且它对由不同运行时进行管理的反应非常差。

经过更多浏览后,我找到解决方案: rbenv 。 通过隔离每个运行时,它不仅管理ruby本身,而且管理所有关联的可执行文件( gemirbrake等)。 这样就可以在最新的2.2.3 Ruby运行时环境下运行我的Jekyll站点,并在我的计算机上使用JRuby构建插件。 rbenv可通过Homebrew获得:

它是这样的:

安装rbenv

酿造安装rbenv

配置PATH

echo'eval“ $(rbenv init-)”'>>〜/ .bash_profile

获取bash配置文件脚本

〜/ .bash_profile

列出所有可用的运行时
 rbenv install -l
Available versions:
  1.8.5-p113
  1.8.5-p114
  ...
  ...
  ...
  ree-1.8.7-2012.02
  topaz-dev
安装所需的运行时

rbenv安装jruby-9.1.6.0

配置项目以使用所需的运行时
 cd logstash-input-reddit
rbenv local jruby-9.1.6.0
检查它的配置
 ruby --version
jruby-9.1.6.0

最后,可以安装捆绑器:

 gem install bundler
Successfully installed bundler-1.13.6
1 gem installed

从这一点开始,所有必需的gem也可以安装:

 bundle install
Fetching gem metadata from https://rubygems.org/.........
Fetching version metadata from https://rubygems.org/..
Fetching dependency metadata from https://rubygems.org/.
Resolving dependencies...
Installing rake 12.0.0
Installing public_suffix 2.0.4
...
...
...
Installing rspec-wait 0.0.9
Installing logstash-core-plugin-api 2.1.17
Installing logstash-codec-plain 3.0.2
Installing logstash-devutils 1.1.0
Using logstash-input-reddit 0.1.0 from source at `.`
Bundle complete! 2 Gemfile dependencies, 57 gems now installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.
Post-install message from jar-dependencies:

if you want to use the executable lock_jars then install ruby-maven gem before using lock_jars

   $ gem install ruby-maven -v '~> 3.3.11'

or add it as a development dependency to your Gemfile

   gem 'ruby-maven', '~> 3.3.11'

插件开发适当

最终解决了这些要求之后,便可以开始适当的插件开发。 让我们跳过寻找正确的API来使用Ruby发出HTTP请求或在安装依赖项时解决Bundler警告的问题,最终代码非常简洁:

classLogStash::Inputs::Reddit<LogStash::Inputs::Base

  config_name'reddit'
  default:codec,'plain'
  config:subreddit,:validate=>:string,:default=>'elastic'
  config:interval,:validate=>:number,:default=>10

  public
  defregister
    @host=Socket.gethostname
    @http=Net::HTTP.new('www.reddit.com',443)
    @get=Net::HTTP::Get.new("/r/={@subreddit}/.json")
    @http.use_ssl=true
  end

  defrun(queue)
    =wecanaborttheloopifstop?becomestrue
    while!stop?
      response=@http.request(@get)
      json=JSON.parse(response.body)
      json['data']['children'].eachdo|child|
        event=LogStash::Event.new('message'=>child,'host'=>@host)
        decorate(event)
        queue<<event
      end
      Stud.stoppable_sleep(@interval){stop?}
    end
  end
end

该插件定义了两个配置参数,将解析subrredit以获得数据以及两次调用之间的interval (以秒为单位)。

register方法初始化类属性,而run方法循环遍历:

  • 对Reddit进行HTTP调用
  • 将响应主体解析为JSON
  • 从JSON制作专用片段,每个帖子一个。 这一点特别重要,因为我们要分别索引每个帖子。
  • 将每个片段作为Logstash事件发送以进行索引

当然,它非常粗糙,没有错误处理,它没有保存上次阅读文章的时间戳以防止索引重复等。在当前状态下,该插件有很大的改进空间,但至少可以从MVP的角度来看。

建造和安装

如上所述,该插件是Ruby gem。 它可以像任何其他gem一样构建:

gem build logstash-input-reddit

这将创建一个名为logstash-input-reddit-0.1.0.gem的二进制文件-名称和版本均来自Bundler的gemspec 。 可以使用标准的Logtstash插件安装过程进行安装:

bin/logstash-plugin install logstash-input-reddit-0.1.0.gem

下游处理

Logstash的一项巨大优势是其处理管道的强大功能。 该插件旨在产生原始数据,但索引应分别处理每个字段。 可以使用mutate过滤器从另一个字段中提取字段。

这是一个Logstash配置代码段示例,用于填充一些相关字段(并删除message ):

filter{
  mutate {
    add_field => {
      "kind" => "%{message[kind]}"
      "subreddit" => "%{message[data][subreddit]}"
      "domain" => "%{message[data][domain]}"
      "selftext" => "%{message[data][selftext]}"
      "url" => "%{message[data][url]}"
      "title" => "%{message[data][title]}"
      "id" => "%{message[data][id]}"
      "author" => "%{message[data][author]}"
      "score" => "%{message[data][score]}"
      "created_utc" => "%{message[data][created_utc]}"
    }
    remove_field => [ "message" ]
  }
}

一旦构建并安装了插件,就可以使用包含先前代码段的配置文件运行Logstash。 与rubydebug编解码器结合使用时,它应产生类似于以下内容的东西:

{
       "selftext" => "",
           "kind" => "t3",
         "author" => "nfrankel",
          "title" => "Structuring data with Logstash",
      "subreddit" => "elastic",
            "url" => "https://blog.frankel.ch/structuring-data-with-logstash/",
           "tags" => [],
          "score" => "9",
     "@timestamp" => 2016-12-07T22:32:03.320Z,
         "domain" => "blog.frankel.ch",
           "host" => "LSNM33795267A",
       "@version" => "1",
             "id" => "5f66bk",
    "created_utc" => "1.473948927E9"
}

结论

从关于Ruby生态系统的几乎为零的知识开始,我对结果非常满意。

我不能做到的唯一的事情是添加第三库(比如rest-client ),Logstash不停地抱怨不能够安装,因为缺少相关的插件。 退回标准HTTP调用即可解决此问题。

另外,请注意,默认模板在安装时会有一些警告,但是可以很容易地解决它们:

  • 许可证应读取Apache-2.0而不是Apache License (2.0)
  • 依赖项版本是开放式的( '>= 0' ),而应限制更大, '~> 2'
  • 缺少某些元数据,例如首页

我希望这篇文章对希望开发自己的Logstash插件的其他Java开发人员有用。

这篇文章的完整源代码可以在Github上找到。

翻译自: https://blog.frankel.ch/starting-logstash-plugin-development-for-java-developers/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值