使用過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 ='xinghalo@163.com'
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_tags
、remove_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時,輸入任意字符,回車~~~大功告成!
是不是,沒有想象中的那么難?要想要熟練的編寫更復雜的插件,還需要多看官方插件的源碼!