ziguzagu.org

fluent-plugin-ganglia

fluentd を使い始めて2日目。結局 ganglia に metric 送れないことには….、ということで plugin 書いてみた。

仕組み的には @sfujiwara さんの zabbix のやつとおんなじやろ、と思い https://github.com/fujiwara/fluent-plugin-zabbix からコピペしていくつかもにょもにょしただけ (・∀・)

LTSV なアクセスログをみて datacounter でステータスコード別に集計して ganglia に metric おくる、というのをやってみた。

<source>
  type tail_labeled_tsv
  path /var/log/users_access_log
  tag web.access
  pos_file /tmp/td-agent/users_access_log.pos
</source>

<match users.access>
  type copy

  <store>
    type datacounter
    tag web.access.status_count
    count_interval 60s
    count_key status
    pattern1 2xx ^2\d\d$
    pattern2 3xx ^3\d\d$
    pattern3 4xx ^4\d\d$
    pattern4 5xx ^5\d\d$
  </store>
</match>

<match users.access.status_count>
  type copy
  <store>
    type stdout
  </store>
  <store>
    type             ganglia
    gmond_port       8701
    name_key_pattern [2345]xx_count
    value_type       uint32
    units            views/min
    group            users_access
    spoof            192..0.2.100:web01
    dmax             30
  </store>
</match>

設定値は gmetric コマンドのロングオプション名とほぼ同じ。fluentd とかぶる名前が幾つかあるので

  • port = gmond_port
  • type = value_type

となっている。

ganglia に metric おくるのには gmetric というそのまんまの名前の gem があったのでそれを使ってぺっと送る。が、td-agent で使っている ruby 1.9.3 に対応していないのか以下のようなエラーがでる…。

2013-02-15 18:38:59 +0900: fluent/engine.rb:115:rescue in emit_stream: emit transaction failed  error="undefined method `reactor_running?' for EventMachine:Module"

とりあえず以下パッチをあてたらうごいた。

--- gmetric.rb.org  2013-02-15 18:41:17.000000000 +0900
+++ gmetric.rb        2013-02-15 18:41:05.000000000 +0900
@@ -1,5 +1,6 @@
 require "stringio"
 require "socket"
+require "eventmachine"

 module Ganglia
   class GMetric

が、こんなことでよいのか ruby 的なところがわからない…。問題なのはここの if 文。

if defined?(EventMachine) and EventMachine.reactor_running?        # open an ephemereal UDP socket since
  # we do not plan on recieving any data
  conn = EM.open_datagram_socket('', 0)

  conn.send_datagram gmetric[0], host, port
  conn.send_datagram gmetric[1], host, port
  conn.close_connection_after_writing
else
  conn = UDPSocket.new
  conn.connect(host, port)

  conn.send gmetric[0], 0
  conn.send gmetric[1], 0
  conn.close
end

だれかなおしてー (´・ω・`)

とりあえず、ganglia にいろいろ送れるようになったけど、設定的になんかいろいろもうすこし良いデフォルトがあるかなぁ(spoof のあたりとか title とか)と思うのでもう少しいじって安定したら gem 化などやってみる。

fluentd++