📊
Aurora MySQLのslow queryをNew Relicでいい感じにプロットする方法
概要
- NRQLってSQLライクで書きやすいんですが、ログ周りで取りたい文字列が取れなくてハマったりしませんか?
- そんな時はcapture関数を使えば正規表現で目的の文字列がさくっと取得できます。
- capture関数でAurora MySQLのslow logをクエリ毎に積み上げ棒グラフでプロットする記事です。
スロークエリの転送方法
最初にCloudWatch Logsに出力されたAurora MySQLのスロークエリをNew Relicに転送します。
以下のようにAWSマネージドサービスを繋ぎます。
この記事はNRQLメインなので詳しい設定手順はなしにして、公式ドキュメントのリンクを記載します。昔はlambdaを用意する必要があったのですが、kinesis Firehoseだけで良くなったので構築が楽になりました。
Kinesis Data Firehoseによるログのストリーミング
転送されたスロークエリはどこに?
New Relic Logsに以下の形式で転送されます。
logGroup = '/aws/rds/cluster/{Aurora cluster name}/slowquery'
[message]
# Time: 2023-07-22T02:10:17.177218Z
# User@Host: hoge @ [xx.x.x.xx] Id: 6235867
# Query_time: 12.771031 Lock_time: 0.000095 Rows_sent: 0 Rows_examined: 267739
use fuga;
SET timestamp=1689991817;
update
piyo
set
hoge = 1
where
fuga = 1 and
piyo = 0 and
date < unix_timestamp() and
flg = 0;
ちゃんと転送されてきていますがこのままではちょっとグラフにし辛いです。何とかしてクエリのみにしたい。。
capture関数の出番
NRQLで用意されているcapture関数を使ってクエリのみを抽出します。
正規表現で文字列を抽出できるので、今回のような複数行のログから一部分を抜き出すのに非常に便利です。
今回やりたいことは、
- 一週間でクエリ種別毎に出現した回数を積み上げ棒グラフでプロットする
なのでグルーピングする FACET
句でcapture関数を使えばよさそうです。
SELECT count(*) FROM Log WHERE `logGroup` = '/aws/rds/cluster/my-aurora-cluster/slowquery' FACET {ここでゴニョゴニョする} TIMESERIES SINCE 1 week ago
実際の書き方
messageの構造は以下のようになっています。
# Time: 2023-07-22T02:10:17.177218Z
# User@Host: hoge @ [xx.x.x.xx] Id: 6235867
# Query_time: 12.771031 Lock_time: 0.000095 Rows_sent: 0 Rows_examined: 267739
use fuga;
SET timestamp=1689991817;
update
piyo
set
hoge = 1
where
fuga = 1 and
piyo = 0 and
date < unix_timestamp() and
flg = 0;
書式は cature({ゴニョゴニョする対象}, {正規表現パターン})
なので、まずはこのようになります。
capture(message, {正規表現パターン})
正規表現パターンにちょっと癖があり、名前付きのキャプチャグループを指定する必要があります。
capture(message, r'{正規表現}(?P<{キャプチャグループ名}>{正規表現}){正規表現}')
[例]
capture(request_url, r'.*/accounts/(?P<account>\d+).*')
-> request_urlから、~/accounts/xxxxxxxx/~のxxxxxxxxを抽出する(xxxxxxxxは数字のみで構成)、抽出するキャプチャグループ名はaccount。
今回は SET timestamp=1689991817;
以降の文字列を取得したいので、
- SET timestamp=xxxxxxxxx; までは全部無視
- 以降の文字列を全て取得する
となるので、以下のようになります。
capture(message, r'[\s\S]*SET timestamp=\d+;(?P<sql>.*)')
-> キャプチャグループ名はsql以外でもよい
完成したNRQL
SELECT count(*) FROM Log WHERE `logGroup` = '/aws/rds/cluster/my-aurora-cluster/slowquery' FACET capture(message, r'[\s\S]*SET timestamp=\d+;(?P<sql>.*)') TIMESERIES SINCE 1 week ago
最後に
NRQLは自分の望むようにデータを出力できる、とても強力なツールです。
キャプチャグループのところでちょっと苦労したので参考になればと思い記事にしました。
それでは素敵なNew Relicライフを!
Discussion