MySQLCasualLog.pmがうらやましかったのでポート(?)した

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

プラグインの実装はこんな感じ。

https://github.com/winebarrel/mysql2_query_filter-plugin-log/blob/master/lib/mysql2_query_filter/plugin/log.rb

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 追記

テストはこれから書きます…

→書きました