2015/05/16 23:06 I/F修正
以前、MySQL Casual Talks vol.6に参加したとき、kamipoさんというすごいかた作のMySQLCasualLog.pmというPerlライブラリの発表がありまして、「いーなーいーなー、うらやましーなー。Railsでも使いたいなー」と思っていたのですが、GWで時間に余裕があったのでRubyにそれっぽく移植してみました。
あ、MySQLCasualLog.pmはやばめなexplainの結果に色づけしてわかりやすくしてくれるものです。
Mysql2QueryFilter
https://github.com/winebarrel/mysql2_query_filter
とりあえずDBIx::QueryLogっぽくSQL実行をフックできるライブラリが欲しかったのでMysql2QueryFilterというものを作りました。
以下のような感じでフィルタを登録すると、Mysql2::Client#queryに渡されたSQLをロギングすることができます。
require 'mysql2_query_filter' class MyFilter < Mysql2QueryFilter::Base def filter(sql, client) p sql p client end end Mysql2QueryFilter.configure do |filter| filter.add MyFilter end Mysql2QueryFilter.enable! client = Mysql2::Client.new(host: 'localhost', username: 'root') client.query('show databases')
また、プラグインも使えます。
Mysql2QueryFilter.configure do |filter| filter.plugin :log #, out: $stderr end
プラグインの実装はこんな感じ。
require 'mysql2_query_filter' module Mysql2QueryFilter::Plugin class Log < Mysql2QueryFilter::Base Mysql2QueryFilter::Plugin.register(:log, self) def initialize(options) super @out = @options[:out] || $stderr end def filter(sql, client) @out << "#{sql}\n" end end end
Mysql2QueryFilter::Plugin::CasualLog
https://github.com/winebarrel/mysql2_query_filter-plugin-casual_log
MySQLCasualLog.pmをだいたいそのままポートしたものです。
以下のようなコードを書いておくと
Mysql2QueryFilter.configure do |filter| filter.plugin :casual_log, out: Logger.new('/tmp/explain.log'), # 出力先(デフォルトは $stderr) client: Mysql2::Client.new, # explainを実行するDBコネクション(デフォルトは同じコネクション) match: ->(sql, cli) { cli.query_options[:database] == 'target_db' } # マッチした場合のみexplainを実行 end
こんな感じで出力されます。
その他
一応、Railsでも動くことは確認できました。
これで幸せになれたらいいなぁ…
2015/05/10 9:03 追記
多少、関連事項ですがArproxyにplug-inサポートするプルリクを投げてみました。
マージされたら、にたよーなplug-inを書こうかと思います。
https://github.com/cookpad/arproxy/pull/6
→書きました https://github.com/winebarrel/arproxy-plugin-mysql_casual_log
2015/05/10 20:20 追記
テストはこれから書きます…
→書きました