fluent-plugin-mysqlslowquerylog を書いた
MySQLのスロークエリログ(複数行)を一つのメッセージとしてemitするOutputプラグインを書きました。
同じようなことをしてくれるInputプラグイン*1がすでにあって、がっつり使っていたのですが、入力にfluent-agent-liteを使いたかったために作成しました。
fluent-plugin-mysqlslowquerylog | RubyGems.org | your community gem host
studio3104/fluent-plugin-mysqlslowquerylog · GitHub
ユースケース
こんな感じのスロークエリログが、
# Time: 130107 11:36:21 # User@Host: root[root] @ localhost [] # Query_time: 0.000378 Lock_time: 0.000111 Rows_sent: 7 Rows_examined: 7 SET timestamp=1357526181; select * from user; # Time: 130107 11:38:47 # User@Host: root[root] @ localhost [] # Query_time: 0.002142 Lock_time: 0.000166 Rows_sent: 142 Rows_examined: 142 use information_schema; SET timestamp=1357526327; select * from INNODB_BUFFER_PAGE_LRU;
このように一つのメッセージとしてパースされて出力します。
2013-01-07T11:36:21+09:00 cocatenated.mysql.slowlog {"user":"root[root]","host":"localhost","query_time":0.000378,"lock_time":0.000111,"rows_sent":7,"rows_examined":7,"sql":"SET timestamp=1357526181; select * from user;"} 2013-01-07T11:38:47+09:00 cocatenated.mysql.slowlog {"user":"root[root]","host":"localhost","query_time":0.002142,"lock_time":0.000166,"rows_sent":142,"rows_examined":142,"sql":"use information_schema; SET timestamp=1357526327; select * from INNODB_BUFFER_PAGE_LRU;"}
設定例
基本的に入力側はfluent-agent-liteを想定していますので、パースされていないデータを送ってあげる必要があります。
td-agentで送ってあげる場合でも例のようにしてあげればokです。
送信側設定例 (fluent-agent-lite)
TAG_PREFIX="mysql" LOGS=$(cat <<"EOF" slowlog.db01 /var/log/mysql/mysql-slow.log EOF ) PRIMARY_SERVER="log_server:24224"
送信側設定例 (td-agent)
<source> type tail path /var/log/mysql/mysql-slow.log format /^(?<message>.+)$/ tag mysql.slowlog.db01 </source> <match> type forward host log_server </match>
受信側設定例
<source> type forward </source> <match mysql.slowlog.*> type mysqlslowquerylog add_tag_prefix cocatenated. </match> <match cocatenated.mysql.slowlog.*> type file path /tmp/slowtest </match>
v.11では要らない子になるかも
古橋さんがn行を1メッセージにまとめてemitするような実装をお考えのようですので短命なプラグインになりそうですが、本家の実装次第では使い続けられるような気もしています。
古橋さんにコメントいただきました。
『v11で入る(入りそう)なのは、複数のレコードを受け取って1つのレコードを書き出すプラグインを「使いやすくするための仕組み」です。なので、このプラグインが短命と言うよりは、v11になるともっと使いやすくなると言うことになるでしょう。具体的には、add_tag_prefix をしなくても良くなります。』
とのことです。
これも色々できるのだけども、複数のメッセージを受け取って、1つのメッセージを書き出すタイプの加工を行いたいケースも結構ある。具体的には、平均値の算出や最大値の抽出などのストリーミング集計は、大抵このタイプ。
設定ファイルの順序を保存するemitを実装してみた。filter よりこれの方がいいかも。どうだろう。注意するべき点は、<source> より前に書いた <match> にはマッチしないという点。順番が重要。 URL
TODO?
フェッチされる行数がn以上、実行にn秒以上など、閾値を超えたらEXPLAINして、結果を一緒にemitするようなオプションを実装しようかなとか思ってますけど、
・出力されるデータのフォーマットが一定でなくなる
・MySQLサーバへのコネクション管理なども考えなくてはならない
など色々アレなのでやらないかも知れません。
おわりに
レビュやpull-req、アドバイスなどお待ちしております!