LoginSignup
65
61

More than 5 years have passed since last update.

Norikraで遊んでみた

Last updated at Posted at 2013-06-05

Norikraも0.1になり、この内容もかなり古くなりました。
Norikra0.1にあわせて新しく書き直しているので下記内容をご参照ください!
Norikra 0.1を使ってみた

Norikraで遊んでみた。

RubyKaigiで@tagomorisさんが発表していたNorkraをとりあえず手元で動かしてみた。すごく簡単に説明するとFluentdみたいなデータストリームをSQLライクな言語でごにょごにょできるものである。
NorikraのスライドはSlideShareにあるので是非見ておこう。

この記事はおそらく一瞬で古くなると思うが、環境は次のような感じだ。

product version
CRuby(MRI) 2.0.0-p195
JRuby 1.7.4
Norikra v0.0.4
Norikra::Client v0.0.3

CRuby、JRubyはrbenvとruby-buildを使ってインストールしている。

JRubyとNorikraをインストールする

$ rbenv install jruby-1.7.4
$ rbenv shell jruby-1.7.4 # このシェルだけJRubyに切り替える
$ ruby -v 
jruby 1.7.4 (1.9.3p392) 2013-05-16 2390d3b on Java HotSpot(TM) 64-Bit Server VM 1.6.0_45-b06-451-11M4406 [darwin-x86_64]

$ gem install norikra
# …snip…
Successfully installed norikra-client-jruby-0.0.3-java
Successfully installed norikra-0.0.4-java
15 gems installed

こんなかんじでインストールできた。JRubyはいっこいっこのコマンドがすごくもっさりなので注意だ。

とりあえず起動する

$ rbenv rehash # 一旦rehashを叩く
$ norikra start
log4j:WARN No appenders could be found for logger (com.espertech.esper.core.service.EPServiceProviderImpl).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
"Norikra server started."

norikra-clientを使ってみる

起動したようなので別のシェルからnorikra-clientを叩いてみる。
JRubyだとうまく動かなかったけど、requireが異なるから起こってただけだったのでさくっと書き換えた。

--- .rbenv/versions/jruby-1.7.4/lib/ruby/gems/shared/gems/norikra-client-jruby-0.0.3-java/lib/norikra/client.rb.original        2013-06-04 10:22:08.000000000 +0900
+++ .rbenv/versions/jruby-1.7.4/lib/ruby/gems/shared/gems/norikra-client-jruby-0.0.3-java/lib/norikra/client.rb 2013-06-04 10:12:44.000000000 +0900
@@ -1,6 +1,6 @@
 require "norikra/client/version"

-require 'msgpack-rpc-over-http'
+require 'msgpack-rpc-over-http-jruby'

これで動くようになった。CRubyだとこの問題起こらないし、動作さくさくなので普通にCRubyにnorikra-client入れた方が良い。

$ norikra-client
Commands:
  norikra-client event CMD ...ARGS   # send/fetch events
  norikra-client field CMD ...ARGS   # manage target field/datatype definitions
  norikra-client help [COMMAND]      # Describe available commands or one specific command
  norikra-client query CMD ...ARGS   # manage queries
  norikra-client target CMD ...ARGS  # manage targets

Options:
  [--host=HOST]
                 # Default: localhost
  [--port=N]
                 # Default: 26571

Norikraでは所謂テーブルの事をtarget、テーブルのカラムのことをfield、クエリのことをquery、入力するログや出力される結果のことをeventと呼ぶ。

とりあえずnorikra-clientで、適当なtargetを作ってみる。

$ norikra-client target open access user:string path:string
$ norikra-client target list
TARGET
access
1 targets found.

で、適当なqueryを書いて登録する。NorikraのクエリはEsperのEPLというSQLライクな言語を使って書く。

$ norikra-client query add access_count "SELECT user, count(*) AS access_count FROM access.win:time_batch(10 sec) GROUP BY user"

あとは適当なeventを流す。

$ echo '{"user":"kame", "path":"http://example.com/"}' | norikra-client event send access
$ echo '{"user":"kame", "path":"http://example.com/"}' | norikra-client event send access
$ echo '{"user":"kame", "path":"http://example.com/"}' | norikra-client event send access
$ echo '{"user":"usagi", "path":"http://example.com/"}' | norikra-client event send access
$ echo '{"user":"usagi", "path":"http://example.com/"}' | norikra-client event send access
$ echo '{"user":"usagi", "path":"http://example.com/"}' | norikra-client event send access
$ echo '{"user":"usagi", "path":"http://example.com/"}' | norikra-client event send access

で、てきとうに結果のeventを見てみる。

$ norikra-client event fetch access_count
{"time":"2013/06/04 10:50:20","user":"kame","access_count":3}
{"time":"2013/06/04 10:50:20","user":"usagi","access_count":4}
$ norikra-client event fetch access_count
{"time":"2013/06/04 10:50:30","user":"kame","access_count":0}
{"time":"2013/06/04 10:50:30","user":"usagi","access_count":0}

こんな感じで結果が返ってくるのがわかる。こんなかんじでSQLライクなクエリでGROUP BYとかが簡単に行えるのである。

Fluentdからログを流したい

実際に使うのであればFluentdからログを流したい。Norikraはfluent-plugin-norikra
を使うことでFluentdとメッセージのやりとりができる。

$ gem install fluent-plugin-norikra

fluent.confに直接Norikraのクエリを記述することもできるが、直接クエリを書いてしまうと変更する度にFluentdを再起動しなくてはいけなくなる。できるのであればFluentdの設定には、データをNorikraに流して結果を受け取ることだけを書きたい。

これを実現できる機能がEvent sweepingのようだ。<event>セクションを記述することでこれが実現できる。

fluent.conf
<source>
  type forward # listen port 24224
</source>

<match input.*>
  type copy

  <store>
    type stdout # 標準出力で確認できるように
  </store>

  <store>
    type norikra
    norikra localhost:26571 # デフォルト設定

    target_map_tag yes      # tagをtarget名に使う
    remove_tag_prefix input # tagのprefixを除去する

    <event>
      method sweep
      tag    query_name        # query名をタグにする
      tag_prefix norikra.event # tag: norikra.event.QUERYNAME
      sweep_interval 5s        # 出力間隔
    </event>
  </store>
</match>


<match norikra.**>
  type stdout # 結果も標準出力で確認する
</match>

fluent-plugin-norikraにはNorikraを自動起動する設定とかも書けるが、裏側でエラーが出てないか確認したかったので、とりあえず最低限の設定だけ書いている。Norikraは起動したままでFluentdを起動する。

$ fluentd -c fluent.conf
# …snip…
2013-06-04 10:55:22 +0900 [info]: adding source type="forward"
2013-06-04 10:55:22 +0900 [info]: adding match pattern="input.*" type="copy"
2013-06-04 10:55:22 +0900 [info]: adding match pattern="norikra.**" type="stdout"
2013-06-04 10:55:22 +0900 [info]: listening fluent socket on 0.0.0.0:24224

起動したら別のシェルを開いて、fluent-catからデータを流してみる。流すデータは先程と同じだ。

$ echo '{"user":"kame", "path":"http://example.com/"}' | fluent-cat input.access
$ echo '{"user":"kame", "path":"http://example.com/"}' | fluent-cat input.access
$ echo '{"user":"kame", "path":"http://example.com/"}' | fluent-cat input.access
$ echo '{"user":"usagi", "path":"http://example.com/"}' | fluent-cat input.access
$ echo '{"user":"usagi", "path":"http://example.com/"}' | fluent-cat input.access
2013-06-05 10:58:42 +0900 input.access: {"user":"kame","path":"http://example.com/"}
2013-06-05 10:58:46 +0900 input.access: {"user":"kame","path":"http://example.com/"}
2013-06-05 10:58:51 +0900 input.access: {"user":"kame","path":"http://example.com/"}
2013-06-05 10:58:53 +0900 norikra.event.access_count: {"user":"kame","access_count":3}
2013-06-05 10:58:55 +0900 input.access: {"user":"usagi","path":"http://example.com/"}
2013-06-05 10:58:56 +0900 input.access: {"user":"usagi","path":"http://example.com/"}
2013-06-05 10:59:03 +0900 norikra.event.access_count: {"user":"kame","access_count":0}
2013-06-05 10:59:03 +0900 norikra.event.access_count: {"user":"usagi","access_count":2}

こんなかんじで結果セットをFluentdに流すことができた!

まとめ

ということで、出たばかりのNorikraを使ってみた。Norikra使うとSQLライクな感じでログをフィルタできて楽しいし、なにより動的にクエリを追加したり削除したりできるのが嬉しい。

まだまだ、登録したqueryの削除が実装されてないとか、上記以外の動作だと結構エラー出たりとか実用するにはちょっと足りてなさそうだけど、今後に期待である。

65
61
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
65
61