fluentd pluginを書いてみる。 redis-ranking
rubyあまり書いたこと無いけど、ちょっと書けば動きそうなので
http://docs.fluentd.org/articles/plugin-development#writing-buffered-output-plugins
http://documents.mazgi.com/fluentd/doc/devel.html#buffered-output-plugins
http://fluentd.org/plugin/
を参考に。
event_id
rank_key
を設定するくらい。
* rubyは、あまり何も見たこと無いのですが
はめ込んだだけなので、普通だとは思いますが、枠がしっかりしているので簡単になんでも作れそうです。
* はめ込んで1回で問題なく動いたので、コードを書いたのは5分くらいでしょうか、サンプル色々見て1時間 + ライブラリの設定がわからず1時間と言う感じです。
out_event_rank.rb
Fluent::Plugin.register_output(‘event_rank’, self)
config_param :host, :string
config_param :port, :integer, :default => 30110
config_param :event_id, :string
config_param :rank_key, :string
def initialize
super
require ‘redis’
end
def configure(conf)
super
if @event_id.nil?
raise Fluent::ConfigError, “event_id not found”
if @rank_key.nil?
raise Fluent::ConfigError, “event_id not found”
end
def start
super
@redis = Redis.new(:host => @host, :port => @port, :thread_safe => true)
end
def shutdown
super
@redis.quit
end
def format(tag, time, record)
[record, record.to_msgpack].to_msgpack
end
def write(chunk)
@redis.pipelined {
chunk.msgpack_each { |record, data|
@redis.set @event_id + “:” + record["id"], data
@redis.zadd @event_id + “:” + @rank_key, record[@rank_key], record["id"]
}
}
end
end
end
* id はユーザーid
configは
type copy
<store>
type event_rank
host 127.0.0.1
port 30110
event_id 201303_001
rank_key all
</store>
<store>
type file
path /home/myapp/log/fluentd/event
time_slice_format %Y%m%d
time_slice_wait 10m
time_format %Y%m%dT%H%M%S%z
compress gzip
#utc
</store>
</match>
こんな感じでファイルにログも残しておく。
fluentd関係ありませんが、
ユーザーのランクをstored set, ユーザーのランキングデータを普通に入れます。
取り出す時はsort + get一発で複数取れます。
( ログからの処理は一時的リアルタイムランキング風です。
複数のアプリサーバーからfluentdで集めたデータをredisのmasterに入れて、slaveから読みます。
最終的には、マスターデータから正式なランキングを作ります。
* ruby ではなくて、設定で・・・
from /usr/lib64/fluent/ruby/bin/fluentd:23:in `load’
from /usr/lib64/fluent/ruby/bin/fluentd:23:in `
from /usr/sbin/td-agent:7:in `load’
from /usr/sbin/td-agent:7:in `
全然動かなくて困った。gem で redisを入れる必要があるので、入れたのになんでダメなんだと 1 時間くらい考えてました。。。で、サーバーのrubyではなくて、/usr/lib64/fluent/ruby/bin/のだからなんか違うのかと気付いて、
/usr/lib64/fluent/ruby/bin/fluent-gem install redis
無事起動。。
とりあえず、データもちゃんと入りました。
redisのsort getも問題なくユーザーのイベントデータもmsgpackで登録できました。
githubにあげました。
https://github.com/junichi-otake/fluent-plugin-redis-event-rank