インしたお! マイクラ開始即通知、idobata + fluentd
やりたいこと
TL;DR
Minecraftサーバーにfluentdをいれて以下のような設定ファイルでログイン/ログアウト通知を実装した。
<source> type tail path /home/blockgiven/minecraft/logs/latest.log format /^\[(?<time>.*)\]\s\[(?<caused_at>[^/]*)/(?<level>.*)\]:\s(?<log>.*)$/ time_format %H:%M:%S tag minecraft.log pos_file /home/blockgiven/fluent/pos/minecraft.pos </source> <match minecraft.log.talk> type record_reformer tag reformed.${tag} player ${log.match(/^<(?<player>.*)>\s.*$/)[:player]} message ${log.match(/^<(?<player>.*)>\s(?<message>.*)$/)[:message]} </match> <match minecraft.log.join> type record_reformer tag reformed.${tag} player ${log.match(/^(?<player>.*)\sjoined\sthe\sgame$/)[:player]} </match> <match minecraft.log.left> type record_reformer tag reformed.${tag} player ${log.match(/^(?<player>.*)\sleft\sthe\sgame$/)[:player]} </match> <match minecraft.log> type rewrite_tag_filter rewriterule1 log ^\<.*\>\s.*$ minecraft.log.talk rewriterule2 log ^.*\sjoined\sthe\sgame$ minecraft.log.join rewriterule3 log ^.*\sleft\sthe\sgame$ minecraft.log.left </match> <match debug.**> type stdout </match> <match reformed.minecraft.log.join> type copy <store> type idobata webhook_url https://idobata.io/hook/generic/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx message_template @all <%= record['player'] %>がマイクラはじめたみたい </store> </match> <match reformed.minecraft.log.left> type copy <store> type idobata webhook_url https://idobata.io/hook/generic/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx message_template @all <%= record['player'] %>がマイクラおわったみたい </store> </match>
今まで
定期的に外部からMinecraftサーバーに接続し、ログインを検知するプログラムを、Heroku上で実行していた。
blockgiven/minecraft_logged_in_notifier
このプログラムの利点は、Minecraftサーバーのログファイルを見る権利がなくても、サーバーのIPアドレス/ポート番号さえわかれば動くこと。 今回、サーバーへのアクセス権をゲットしたので、ログファイルを監視する方式に切り替えたい。
Fluentdを導入する
aptで導入
debパッケージからFluentdをインストールする | Fluentdを参考に導入する。
$ sudo apt-get install -y curl $ curl -L http://toolbelt.treasuredata.com/sh/install-debian-wheezy-td-agent2.sh | sh
う、ログファイルは見れるがsudo権限がなかった。つらい。
gemで導入
幸いgemをいれる権限はある。Ruby GemからFluentdをインストールする | Fluentdを参考にgemとして導入する。
$ gem install fluentd --no-ri --no-rdoc $ fluentd --setup ./fluent
Minecraftのログからイベントを収集する
設定ファイルはminecraftのログをIRCに流すfluentdのコンフィグを参考にする
<source> type tail path /home/blockgiven/minecraft/logs/latest.log format /^\[(?<time>.*)\]\s\[(?<caused_at>[^/]*)/(?<level>.*)\]:\s(?<log>.*)$/ time_format %H:%M:%S tag debug.minecraft.log pos_file /home/blockgiven/fluent/pos/minecraft.pos </source> <match debug.**> type stdout </match>
debug.〜
でタグ付けするとstdoutに出て便利。
起動は
$ fluentd -c ./fluent/fluent.conf -vv &
設定ファイルの再読み込みはSIGHUP
を送る。
pidファイルを作る設定後で確認したい。
$ ps aux | grep fluentd $ kill -HUP 19955
マインクラフトでログインしてログアウトしログを確認する
2014-11-08 10:37:00 +0900 debug.minecraft.log: {"caused_at":"User Authenticator #9","level":"INFO","log":"UUID of player blockgiven is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"} 2014-11-08 10:37:00 +0900 debug.minecraft.log: {"caused_at":"Server thread","level":"INFO","log":"blockgiven[/xxx.xxx.xxx.xxx:xxxxx] logged in with entity id 625953 at (241.04323755057334, 70.0, 124.74428504286337)"} 2014-11-08 10:37:00 +0900 debug.minecraft.log: {"caused_at":"Server thread","level":"INFO","log":"blockgiven joined the game"} 2014-11-08 10:37:11 +0900 debug.minecraft.log: {"caused_at":"Server thread","level":"INFO","log":"blockgiven lost connection: TextComponent{text='Disconnected', siblings=[], style=Style{hasParent=false, color=null, bold=null, italic=null, underlined=null, obfuscated=null, clickEvent=null, hoverEvent=null, insertion=null}}"} 2014-11-08 10:37:11 +0900 debug.minecraft.log: {"caused_at":"Server thread","level":"INFO","log":"blockgiven left the game"}
収集できてる。
次はrewriteの設定をして、ログイン/ログアウト/チャットのログを振り分ける。 rewrite tag filterのプラグインを入れる。
$ gem install fluent-plugin-rewrite-tag-filter
設定を追加する。
<source> type tail path /home/blockgiven/minecraft/logs/latest.log format /^\[(?<time>.*)\]\s\[(?<caused_at>[^/]*)/(?<level>.*)\]:\s(?<log>.*)$/ time_format %H:%M:%S tag minecraft.log pos_file /home/blockgiven/fluent/pos/minecraft.pos </source> <match minecraft.log> type rewrite_tag_filter rewriterule1 log ^\<.*\>\s.*$ minecraft.log.talk rewriterule2 log ^.*\sjoined\sthe\sgame$ minecraft.log.join rewriterule3 log ^.*\sleft\sthe\sgame$ minecraft.log.left </match> # rewrite tag filterをいれたので、設定が終わるまで`minecraft.*`を`debug.minecraft.*`にリダイレクト <match minecraft.log.**> type rewrite_tag_filter rewriterule1 log . debug.${tag} </match> <match debug.**> type stdout </match>
再度読み込んでみる
$ ps aux | grep fluentd $ kill -HUP 19955
うまくいったようだ
2014-11-08 11:11:02 +0900 debug.minecraft.log.join: {"caused_at":"Server thread","level":"INFO","log":"blockgiven joined the game"} 2014-11-08 11:11:09 +0900 debug.minecraft.log.talk: {"caused_at":"Server thread","level":"INFO","log":"<blockgiven> a"} 2014-11-08 11:11:12 +0900 debug.minecraft.log.left: {"caused_at":"Server thread","level":"INFO","log":"blockgiven left the game"}
誰が出た/入ったのかも切り取りたい。
$ gem install fluent-plugin-record-reformer
debug.
をつけるrewriteの設定の前に追加
<match minecraft.log.talk> type record_reformer tag reformed.${tag} player ${log.match(/^<(?<player>.*)>\s(?<message>.*)$/)[:player]} message ${log.match(/^<(?<player>.*)>\s(?<message>.*)$/)[:message]} </match> <match minecraft.log.join> type record_reformer tag reformed.${tag} player ${log.match(/^(?<player>.*)\sjoined\sthe\sgame$/)[:player]} </match> <match minecraft.log.left> type record_reformer tag reformed.${tag} player ${log.match(/^(?<player>.*)\sleft\sthe\sgame$/)[:player]} </match>
デバッグの書き換えの後ろにもつけてやる。
<match reformed.minecraft.log.**> type rewrite_tag_filter rewriterule1 log . debug.${tag} </match>
うまく動いているようだ
2014-11-08 11:53:59 +0900 debug.reformed.minecraft.log.join: {"caused_at":"Server thread","level":"INFO","log":"blockgiven joined the game","player":"blockgiven"} 2014-11-08 11:54:06 +0900 debug.reformed.minecraft.log.talk: {"caused_at":"Server thread","level":"INFO","log":"<blockgiven> hi","player":"blockgiven","message":"hi"} 2014-11-08 11:54:08 +0900 debug.reformed.minecraft.log.left: {"caused_at":"Server thread","level":"INFO","log":"blockgiven left the game","player":"blockgiven"}
通知する
今回はidobata.ioになげたい。
$ gem install fluent-plugin-idobata
<match reformed.minecraft.log.join> type copy <store> type idobata webhook_url https://idobata.io/hook/generic/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx message_template @all <%= record['player'] %>がマイクラはじめたみたい </store> </match> <match reformed.minecraft.log.left> type copy <store> type idobata webhook_url https://idobata.io/hook/generic/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx message_template @all <%= record['player'] %>がマイクラおわったみたい </store> </match>
はまったところ
reformで書き換えて同じkeyにdestすると無限ループで死ぬ。
まとめ
マイクラにログイン/ログアウトすると即座にidobata.ioに通知されるようになった。 これまで以上にマイクラをやる頻度があがりそう。
fluentdとidobata.io超便利。
次
- 今回は設定を1ファイルにべた書きした。分割方法を調べたい。
- ログファイルを見れない場合も監視できるようにする
- MinecraftにRubotyを住ませる