Fluentd on Solaris 10/11
このところ話題のログ収集ソフトウェア Fluentd を Solaris 10/11 で動かしてみたメモです。
Redhat や Debian だと td-agent というパッケージが用意されていて、yum や apt でインストールできますが、Solaris には公式のパッケージがないのでソースからインストールしました。
事前準備
Solaris 11 の場合、gcc をインストールしてください。
$ sudo pkg install gcc-45
Solaris 10 の場合、gcc と make が使えるように PATH を通してください。
$ export PATH=$PATH:/usr/sfw/bin:/usr/ccs/bin
Ruby インストール
Fluentd は Ruby で作られているので、Ruby が必要になります。Fluentd 10.0.42 の時点で、Ruby 1.9 系にしか対応していないので、Ruby 1.9.3 をインストールすることにします。(2014-02-16追記: Ruby 2.1.0 でも動きました。)
td-agent のパッケージには Ruby が含まれているので、それに倣って /opt/fluentd 配下に Fluentd 専用の Ruby をインストールすることにします。
Rubyの公式サイトからtarボールをダウンロードします。
$ wget http://cache.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p484.tar.gz または $ wget http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.0.tar.gz
tarボールを展開します。
$ gtar zxvf ruby-*.tar.gz $ cd ruby-*
インストール先を /opt/fluentd 配下にします。
$ ./configure --prefix=/opt/fluentd # Ruby 1.9.3 の場合 $ ./configure --prefix=/opt/fluentd CFLAGS='-std=gnu90' # Ruby 2.1.0 の場合
コンパイルします。
$ make $ sudo make install
(2014-02-16追記) Ruby 2.1.0 だと、gem で msgpack 0.5.8 がうまくインストールできなかったので、対応してないと勘違いしていましたが、↓の記事を参考に ruby の configure 時に CFLAGS='-std=gnu90' を追加したらインストールできました。
Solaris10上のRuby 2.0.0(というか、OpenCSWのgcc-4.8.0)でmsgpackがインストールに失敗する件 - Qiita
Fluentd インストール
gemを使うので、必要に応じて HTTP Proxy を設定します。
$ export http_proxy=http://proxy:port
(2014-03-08追記) cool.io 1.2.0 が SPARC 版 Solaris でインストールに失敗するので、1.1.1 をインストールします。
$ sudo /opt/fluentd/bin/gem install cool.io --version '=1.1.1'
gemでインストールします。
$ sudo /opt/fluentd/bin/gem install fluentd
必要に応じて、プラグインをインストールします。
$ sudo /opt/fluentd/bin/gem install \ fluent-plugin-file-alternative \ fluent-plugin-parser \ fluent-plugin-rewrite
設定とログ用のディレクトリを作成します。
$ cd /opt/fluentd $ sudo mkdir conf logs
設定
設定ファイルを /opt/fluentd/conf/fluentd.conf として作成します。
type file path /tmp/fluentd_debug.log
起動スクリプト
起動スクリプトを /lib/svc/method/fluentd として作成します。
#!/bin/bash # init script for fluentd . /lib/svc/share/smf_include.sh export PATH=/opt/fluentd/bin:$PATH SERVICE=fluentd BASEDIR=/opt/fluentd INSTANCE=`basename $0` CONFFILE=$BASEDIR/conf/$INSTANCE.conf LOGFILE=$BASEDIR/logs/$INSTANCE.log PIDDIR=/var/run/$SERVICE PIDFILE=$PIDDIR/$INSTANCE.pid RETVAL=0 case "$1" in start) [ ! -d $PIDDIR ] && mkdir -p $PIDDIR $0 configtest && $SERVICE -c $CONFFILE -d $PIDFILE -l $LOGFILE RETVAL=$? ;; stop) if [ -f $PIDFILE ]; then kill `cat $PIDFILE` if [ $? -eq 0 ]; then rm -f $PIDFILE fi else echo "'$PIDFILE' does not exist!" fi ;; refresh) $0 configtest && kill -HUP `cat $PIDFILE` ;; reopen) kill -USR1 `cat $PIDFILE` ;; configtest) $SERVICE -c $CONFFILE --dry-run -q RETVAL=$? ;; *) echo "Usage: $0 {start|stop|refresh|configtest}" RETVAL=1 ;; esac exit $RETVAL
実行権限を付けます。
$ sudo chmod 755 /lib/svc/method/fluentd
Solaris では LIBEV_FLAGS=3 という環境変数を設定しないと起動しないようです。(LIBEV_FLAGS=3 を設定すると、event ports が無効になります。event ports は超バギーらしいです。。。 http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#Event_port_backend)
(2014-02-22追記) cool.io 1.1.0 の対応で、libev のバージョンが4.04になり、LIBEV_FLAGS=3 は不要になったようです。というか、event ports は使われなくなった模様。
SMF登録
SMFのマニフェストファイルを /lib/svc/manifest/site/fluentd.xml として作成します。
<?xml version="1.0"?> <!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> <service_bundle type='manifest' name='fluentd'> <service name='site/fluentd' type='service' version='1'> <instance name='default' enabled='false'> <!-- Wait for network interfaces to be initialized. --> <dependency name='network' grouping='require_all' restart_on='error' type='service'> <service_fmri value='svc:/milestone/network:default'/> </dependency> <!-- Wait for all local filesystems to be mounted. --> <dependency name='filesystem-local' grouping='require_all' restart_on='none' type='service'> <service_fmri value='svc:/system/filesystem/local:default'/> </dependency> <exec_method type='method' name='start' exec='/lib/svc/method/fluentd start' timeout_seconds='60' /> <exec_method type='method' name='stop' exec='/lib/svc/method/fluentd stop' timeout_seconds='60' /> <exec_method type='method' name='refresh' exec='/lib/svc/method/fluentd refresh' timeout_seconds='60' /> <property_group name='startd' type='framework'> <!-- sub-process core dumps shouldn't restart session --> <propval name='ignore_error' type='astring' value='core,signal' /> </property_group> </instance> <stability value='Evolving' /> </service> </service_bundle>
サービスを登録します。
$ sudo svccfg -v import fluentd.xml
サービスを起動します。
$ sudo svcadm enable fluentd
サービスが正常に起動していることを確認します。
$ svcs fluentd STATE STIME FMRI online 12:31:50 svc:/site/fluentd:default
動作確認
fluent-cat コマンドを使って動作確認します。タグを指定して、標準入力からJSONを入力すると Fluentd に送信されます。終了するには Ctrl+D を入力してください。
$ /opt/fluentd/bin/fluent-cat debug.test { "test" : "debug" } Ctrl+D
上記の設定では、↓のようにファイルに出力されていれば成功です。
$ cat /tmp/fluentd_debug.log.* 20XX-XX-XXTXX:XX:XX+09:00 debug.test {"test":"debug"}
Solaris 10 対応
Solaris 10 で out_forward プラグインを使うと、以下のようなエラーが出て送信することができませんでした。
[warn]: temporarily failed to flush the buffer. next_retry=2014-01-16 10:00:38 +0900 error_class="Errno::ENOPROTOOPT" error="Option not supported by protocol" instance=4227828 [warn]: /opt/fluentd/lib/ruby/gems/1.9.1/gems/fluentd-0.10.42/lib/fluent/plugin/out_forward.rb:227:in `setsockopt' [warn]: /opt/fluentd/lib/ruby/gems/1.9.1/gems/fluentd-0.10.42/lib/fluent/plugin/out_forward.rb:227:in `send_data' [warn]: /opt/fluentd/lib/ruby/gems/1.9.1/gems/fluentd-0.10.42/lib/fluent/plugin/out_forward.rb:141:in `block in write_objects' [warn]: /opt/fluentd/lib/ruby/gems/1.9.1/gems/fluentd-0.10.42/lib/fluent/plugin/out_forward.rb:135:in `times' [warn]: /opt/fluentd/lib/ruby/gems/1.9.1/gems/fluentd-0.10.42/lib/fluent/plugin/out_forward.rb:135:in `write_objects' [warn]: /opt/fluentd/lib/ruby/gems/1.9.1/gems/fluentd-0.10.42/lib/fluent/output.rb:445:in `write' [warn]: /opt/fluentd/lib/ruby/gems/1.9.1/gems/fluentd-0.10.42/lib/fluent/buffer.rb:296:in `write_chunk' [warn]: /opt/fluentd/lib/ruby/gems/1.9.1/gems/fluentd-0.10.42/lib/fluent/buffer.rb:276:in `pop' [warn]: /opt/fluentd/lib/ruby/gems/1.9.1/gems/fluentd-0.10.42/lib/fluent/output.rb:306:in `try_flush' [warn]: /opt/fluentd/lib/ruby/gems/1.9.1/gems/fluentd-0.10.42/lib/fluent/output.rb:131:in `run'
調べてみると、Solaris 10 の sockopts が SO_SNDTIMEO をサポートしていないようだったので、該当箇所をコメントアウトしたところ動作するようになりました。Solaris 11 ではこの修正は不要でした。
$ cd /opt/fluentd/lib/ruby/gems/1.9.1/gems/fluentd-0.10.42/lib/fluent/plugin
$ diff out_forward.rb.orig out_forward.rb 227c227,228 < sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, opt)
-
- -