以前、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::Plugin::Filter def filter(sql, query_options) p sql p query_options 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 < Filter Mysql2QueryFilter::Plugin.register(:log, self) def initialize(options) super @out = @options[:out] || $stderr end def filter(sql, query_options) @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) database: 'mysql', # explainを実行するDBの接続情報(hostとかusernameとか) match: ->(sql, opts) { opts[:database] == 'target_db' } # マッチした場合のみexplainを実行 end
こんな感じで出力されます。
その他
一応、Railsでも動くことは確認できました。
これで幸せになれたらいいなぁ…
2015/05/10 9:03 追記
多少、関連事項ですがArproxyにplug-inサポートするプルリクを投げてみました