メインコンテンツへスキップ
  1. Blogs/

NewRelicでMySQL2::Clientのクエリを計測する

ISUCON等でNewRelic等のサービスを利用してRubyのAPMを仕込む時、
エンドポイントの計測と同時にSQLも計測したいということが多いと思います。

ActiveRecordを利用していれば、NewRelicで上手いこと拾ってくれるのですが Mysql2::Clientを直接使う場合は自前で少し手直しする必要があります。

具体的には、Mysql2::Clientを拡張すると上手いこと行きます。

ISUCON9 予選の過去問でNew Relicを使う及び 該当コード を参考とさせて頂きました。

コード例 #

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class NRMysql2Client < Mysql2::Client
  def initialize(*args)
    super
  end

  def query(sql, *args)
    operation = sql[/^(\w+)/i] || "uncategorized_operation"
    table = sql[/FROM\s+(\w+)/i, 1] || sql[/INTO\s+(\w+)/i, 1] || sql[/UPDATE\s+(\w+)/i, 1] || "uncategorized_table"

    callback = -> (_, metrics, elapsed) do
      NewRelic::Agent::Datastores.notice_sql(sql, metrics, elapsed)
    end

    NewRelic::Agent::Datastores.wrap("MySQL", operation, table, callback) do
      super
    end
  end
end

7,8行目が肝心です。

以下のようなクエリから

SELECT * FROM users
  • operation = 操作(ex SELECT)
  • table = テーブル名(ex users)

を引っこ抜いて来ます。
後はNewRelicの用意しているクラスでラップすれば良いですね。

上記のRegexだと複雑なクエリには対応できないですが、おおよそ計測したいものは拾えてると思います。

結果 #

ISUCON12 予選 にてベンチを回すと以下のように計測されます。

見やすいですね。良い

Rubyだとこの辺りの拡張がしやすくて便利ですね。