1. 程式人生 > >手把手教你編寫Logstash外掛

手把手教你編寫Logstash外掛

使用過Logstash的朋友都知道,它強大的外掛生態幾乎覆蓋了所有的開源框架。從基本的http、tcp、udp、file,到強大的kafa、redis、ganglia,還有豐富的解析工具,比如date、json、grok、kv等等,有了它再也不用擔心資料不好蒐集了!

不過需求是無限的,如果這些框架都不滿足怎麼辦呢?

沒關係,十分佩服Logstash的作者,他以外掛的方式組織每個部分,使得logstash本身具有超強的擴充套件性。

Logstash基本組成

有過使用經驗的都知道Logstash主要由輸入、過濾器、輸出三部分組成。
每一部分的外掛都符合統一的標準,因此擴充套件起來也十分容易。

自定義過濾器外掛

由於需求大多都是集中在過濾部分,因此這裡就簡單的介紹下過濾器的自定義寫法。

官網上面的過程太過繁瑣,比如:

  • 1 建立github開源工程
  • 2 拷貝樣例工程
  • 3 替換樣例工程基本資訊
  • 4 編寫業務程式碼
  • 5 安裝外掛
  • 6 分享與貢獻

但是如果自己用的話,上面做了很多的無用功。我這裡提供一個極簡的樣例工程,外掛的目錄大致如下:

$ tree logstash-filter-example
├──lib
│   └── logstash
│       └── filters
│           └── mypluginname.rb
├── logstash-filter-example.gemspec

其實只需要這兩個檔案即可!

先看看logstash-filter-example.gemspec都做了什麼吧!

Gem::Specification.new do|s|
  s.name ='logstash-filter-example'
  s.version ='1.0.0'
  s.licenses =['Apache License (2.0)']
  s.summary =" "
  s.description =" "
  s.authors =["xingoo"]
  s.email ='[email protected]'
  s.homepage ="http://www.elastic.co/guide/en/logstash/current/index.html"
  s.require_paths =["lib"]# Files
  s.metadata ={"logstash_plugin"=>"true","logstash_group"=>"filter"}# Gem dependencies
  s.add_runtime_dependency 'logstash-core','>= 2.0.0','< 3.0.0'
  s.add_development_dependency 'logstash-devutils'
end

上面的資訊,只要改改版本和名字,其他的資訊基本不需要動。

關鍵的資訊還有:

  • s.require_paths定義了外掛核心檔案的位置
  • s.add_runtime_dependency 定義了外掛執行的環境

然後再看看logstash-filter-example.rb

這個檔案就需要詳細說說了,基本的框架如下,

# encoding: utf-8
require "logstash/filters/base"
require "logstash/namespace"

class LogStash::Filters::Example < LogStash::Filters::Base
  config_name "example"
  config :name,:validate =>:string,:default =>"xingoo!"

  public
  def register
  end

  public
  def filter(event)
    event["name"] = @name
    filter_matched(event)
  end 
end 

挨行看看!

首先第一行的# encoding: utf-8,不要以為是註釋就沒什麼作用。它定義了外掛的編碼方式。

下面兩行:

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

引入了外掛必備的包。

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

外掛繼承自Base基類,並配置外掛的使用名稱。

下面的一行對引數做了配置,引數有很多的配置屬性,完整的如下:

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

其中

  • variable_name就是引數的名稱了。
  • validate 定義是否進行校驗,如果不是指定的型別,在logstash -f xxx --configtest的時候就會報錯。它支援多種資料型別,比如:string, :password, :boolean, :number, :array, :hash, :path (a file-system path), :codec (since 1.2.0), :bytes.
  • default 定義引數的預設值
  • required 定義引數是否是必須值
  • deprecated 定義引數的額外資訊,比如一個引數不再推薦使用了,就可以通過它給出提示!典型的就是es-output裡面的Index_type,當使用這個引數時,就會給出提示:
config :index_type, :validate => :string, :deprecated => "Please use the 'document_type' setting instead. It has the same effect, but is more appropriately named."

下面的兩個方法是外掛的核心了!

register方法相當於初始化的構造方法,可以在裡面進行外掛的初始化工作。

filter中則是過濾器的核心程式碼。

其中event是從input外掛中傳入的事件物件,它是Logstash::Event的物件,在logstashj-core包中,有興趣的可以瞭解一下!

然後在這個方法中可以使用幾個預設的方法;

  • filter_matched(),該方法會把事件傳入下一個過濾器
  • add_field、`remove_field 新增或者移除一個欄位
  • add_tagsremove_tags 新增或者移除一個標籤
  • event.cancel 取消當前的事件,即不在繼續向下走。(在split外掛中有典型的使用場景)

在上面的例子中,定義了一個name引數,在register中使用@name例項變數,把引數賦值給event物件。

這個外掛的目的就是給每條事件都加上一個name屬性。

至此一個外掛就算編寫完成了!

安裝外掛

第一步,首先把這個外掛資料夾拷貝到下面的目錄中

logstash-2.1.0\vendor\bundle\jruby\1.9\gems

第二步,修改logstash根目錄下的Gemfile,新增如下的內容:

gem "logstash-filter-example", :path => "vendor/bundle/jruby/1.9/gems/logstash-filter-example-1.0.0"

第三步,編寫配置檔案,test.conf

input{
    stdin{

    }
}
filter{
    example{
        name => "test name:xingoo"
    }
}
output{
    stdout{
        codec => rubydebug
    }
}

第四步,輸入logstash -f test.conf時,輸入任意字元,回車~~~大功告成!

是不是,沒有想象中的那麼難?要想要熟練的編寫更復雜的外掛,還需要多看官方外掛的原始碼!

參考