🚔

モバイルアプリエンジニアのためのNew Relic、NRQL入門

2023/12/14に公開

はじめに

この記事では、モバイルアプリエンジニアが障害対応の際にNew RelicのNew Relic Query Language(NRQL)を使ってデータを確認する方法を紹介します。

New Relicとは

https://newrelic.com/jp/resources/presentations/nru-101

New Relic は、モバイルやブラウザのエンドユーザーモニタリングや、外形監視、バックエンドのアプリケーションとインフラモニタリングなど、オンプレやクラウド、コンテナからサーバレスまであらゆるシステム環境での性能管理を実現するプラットフォームです。

アイスタイルでは、様々なシステムでNew Relicを使用したパフォーマンス監視・エラー監視等を行っています。

モバイルアプリにNew Relicを導入すると、アプリのクラッシュレポート、APIリクエストのパフォーマンス問題など、多岐にわたるデータを監視・分析できます。
しかし、モバイルアプリに関する情報は他(サーバーサイドアプリケーションやインフラなど)と比較して少ないのが実情です。
そのため、New Relicの機能を十分に活かし切れていないケースがあると考えています。
導入したもののイマイチ使いこなせない、という方が少しでも減ればと思い、この記事を書くことにしました。
(この記事は、社内向けの説明ページを公開用に手直ししたものです)

NRQLとは

NRQLはNew Relic Query Languageの略称で、New Relicのデータを抽出するためのクエリを指します。
読みは エヌアールキューエル か、過去に参加したNew Relicの勉強会では ヌルクル と読んでいる人もいました。
と思って改めて検索したところ、New Relicの公式ブログで以下の記述を見つけましたので、 ヌルクル は公式で認められた読み方のようです。

https://newrelic.com/jp/blog/how-to-relic/advanced-nrql

"nerkel"と発音する

チーム内で通じれば何でも良いと思いますが、私は誰にでも伝わるように「New Relicのクエリ」と表現することが多いです。

NRQLの確認手順

New Relicにログイン後、左のメニューにあるQuery Your Dataをクリックしてください。

下記の表示が確認できたら、あとはクエリを書くだけです。
また、右上の Copy permalink ボタンを押すと、共有用のURLがクリップボードにコピーされます。
Slack等で共有する場合はこちらを利用してください。

タイムゾーンの設定

個人設定でタイムゾーンを変更できます。
デフォルトはUTCになっていますので、Asia/Tokyoに変更することをおすすめします。

https://docs.newrelic.com/jp/docs/accounts/accounts-billing/general-account-settings/default-time-zone-setting/

NRQLの基本

基本的には公式ドキュメントを順に読むことを推奨しますが、とっつきにくいところもあるので、障害対応でよく使うものをまとめました。

最低限、SELECT句とFROM句が必要です。

SELECT * FROM MobileRequest

SELECT

SELECT句で指定できる項目名は以下を参照してください。

ドキュメントを見るより、SELECT *で実際にクエリを実行して中身を見た方が早い場合もあります。

また、SELECT句ではcountやpercentileなどの集計関数を使うこともできます。
よく使う集計関数は以下の3つです。

count

件数を取得します。
似たものとして uniqueCountというものもあります(SQLで言うところの count(distinct foo) です)。

-- 直近1分でexample.comへリクエストした総数と、ユニークユーザー数を取得する
SELECT count(*), uniqueCount(uuid) 
FROM MobileRequest
WHERE requestDomain = 'example.com'
SINCE 1 minute ago

percentage

割合を取得します。

-- 直近1日で、とあるエンドポイントが403エラーになった割合を取得する
SELECT percentage(count(*), WHERE statusCode = 403)
FROM MobileRequest, MobileRequestError 
WHERE requestUrl = 'https://example.com/foo'
SINCE 1 day ago

percentile

パーセンタイルを取得します。
95パーセンタイルは「全体の95%のリクエストはこの時間内にレスポンスが返っている」という意味です。

-- 直近1週間の、とあるAPIの95パーセンタイルを取得する
SELECT percentile(duration, 95) FROM MobileRequest 
WHERE requestDomain = 'app-api.cosme.net'
SINCE 1 week ago 

FROM

モバイルアプリにおけるAPI関連の障害調査でよく使うのは以下の2つです。
成功・失敗が別のデータタイプに分かれているため、エラー率を計算する場合はこの2つを組み合わせることになります。

データタイプ 説明
MobileRequest モバイルアプリからのAPI通信のログ。ステータスコードが400未満だとこちらに入る。
MobileRequestError モバイルアプリからのAPI通信のログ。ステータスコードが400以上に加え、ネットワーク通信エラーも含まれる。通常運用で起こりうる400系エラーがある場合、クエリで明示的に除外しないと適切なエラー率が取得できないため注意が必要。

FACET(group by相当)

SQLのgroup byに相当するのがFACET句です。SQLでgroup byを書く場合と同様、SELECT句では集計関数を使う必要があります。

-- リクエストドメイン毎のリクエスト数を取得する
SELECT count(*) FROM MobileRequest FACET requestDomain

FACET句を指定すると、デフォルトの最大件数が10件になります(後述のLIMIT句を参照)。

SINCE, UNTIL

期間指定をするにはSINCEもしくはUNTILを使用します。

〜 agoという相対表記と、年月日時分秒を指定する絶対表記があります。

相対表記

以下の指定が可能です。DAYSのように複数形にもできますが、単数形・複数形どちらでも動作します。

  • SECOND
  • MINUTE
  • HOUR
  • DAY
  • WEEK
  • MONTH
  • QUARTER
  • YEAR
    THIS WEEK, LAST MONTHなど、THIS, LASTと組み合わせることもできます。

また、yesterdayやtoday、SUNDAYなどの曜日指定もできます。

-- 過去1日間で、リクエストドメイン毎のエラー数を取得する
SELECT count(*) FROM MobileRequestError FACET requestDomain SINCE 1 day ago

絶対表記

問い合わせの調査など、日時が判明している場合は絶対表記を使うと効果的です。

-- 特定の日時指定で、リクエストドメイン毎のエラー数を取得する
SELECT count(*) FROM MobileRequestError FACET requestDomain 
SINCE '2023-12-01 11:00:00 +0900' 
UNTIL '2023-12-01 13:00:00 +0900'

LIMIT

SELECT *で一覧を取得したり、FACETでグルーピングした場合、デフォルトでは出力される件数が決まっています。
LIMIT句を使うことで件数を指定できます。

  • LIMIT 5:5件まで取得
  • LIMIT MAX:全件取得

デフォルト値は、SELECT *の場合は100、FACET句付きの場合は10になります。最大値は2000です。
https://docs.newrelic.com/jp/docs/query-your-data/nrql-new-relic-query-language/get-started/nrql-syntax-clauses-functions/#sel-limit

WHERE

条件を絞り込む際に使用します。MobileRequest・MobileRequestErrorでよく使う条件は以下のとおりです。

項目名 説明 クエリ例 備考
appName アプリ名 WHERE appName IN ('Example iOS', 'Example Android')
requestDomain リクエストドメイン WHERE requestDomain = 'example.com'
requestPath リクエストパス WHERE requestDomain = 'example.com' AND requestPath = '/products'
requestUrl リクエストURL WHERE requestUrl = 'https://example.com/products' ≒ requestDomain + requestPath
requestMethod リクエストメソッド WHERE requestDomain = 'example.com' AND requestPath LIKE '/products/%' AND requestMethod = 'POST' 省略しても良いが、同じパスでGET/POSTが存在するような場合には指定することがある
userId ユーザーID WHERE userId = '12345' ユーザーIDとしてSDKで設定したもの

TIMESERIES

集計関数とセットで使用し、時系列のグラフを出力します。
主にFACETと組み合わせ使います。

クエリ 結果 備考
TIMESERIES 1 minute 1分ごとに集計 SINCEのところで挙げたsecond等でも集計できます。
TIMESERIES MAX 集計期間に応じて、可能な限り短い期間で集計
TIMESERIES AUTO 集計期間に応じて、いい感じに集計 AUTOは省略しても動作します。

なお、SINCE 1 day ago TIMESERIES 1 second のような指定をしてしまうと、分割数が多すぎるためエラーになります。

-- 「直近1日・リクエストドメイン毎のリクエスト数を取得する」を、1時間ごとの時系列でグラフ化する
SELECT count(*) FROM MobileRequest FACET requestDomain SINCE 1 day ago TIMESERIES 1 hour

Tips

  • SELECT, FROMなどの句は大文字・小文字どちらでも問題ありません。
select * from MobileRequest
  • FROM MobileRequest SELECT のように、FROMを先頭に入力することで、SELECT句の補完がMobileRequestの値になるため、この順序を好む方もいます。

2023年の障害対応で実際に使用したクエリ例

今年1年を振り返ってみて、実際に障害対応で使用したクエリ例をまとめました。
(クエリと結果画像はサンプルで、実際のクエリとは異なります)

特定エンドポイントのリクエスト数調査

あるAPIの特定エンドポイントで速度劣化が発生していました。対応方針を決定するため、モバイルアプリからのリクエスト数を確認しました。

SELECT count(*) FROM MobileRequest, MobileRequestError WHERE -- リクエスト総数
requestUrl = 'https://example.com/products'
SINCE '2023-12-05 11:00:00+0900' UNTIL '2023-12-05 13:00:00+0900' -- 問題が発生した時刻の前後1時間
TIMESERIES 1 minutes -- 1分おき

これにより、分間アクセス数の最大値が特定できました。
例示したキャプチャであれば、この期間の最大リクエスト数は分間100回ということが分かります。

特定エンドポイントのエラー調査

とある機能のリリース後、New RelicでAPIエラーを監視していたところ、ステータスコード400のエラーが多く発生していることに気づきました。
原因を特定するため、MobileRequestErrorの値を確認しました。

SELECT * FROM MobileRequestError 
WHERE appName IN ('Example iOS', 'Example Android') 
AND requestUrl = 'https://example.com/foo'
AND statusCode = 400 
SINCE '2023-11-30 11:00:00 +09:00' UNTIL '2023-11-30 23:00:00 +09:00'

このクエリにより、以下の情報が確認できました。

  • appNameから、iOS, Androidどちらでも発生していることが分かる
  • responseBodyから、このエンドポイントで必須のパラメータが不足していることが分かる

まとめ

New Relicを活用することで、モバイルアプリのパフォーマンス監視や障害対応が効率的に行えるようになります。

今後もNew Relicを活用して、モバイルアプリの品質向上を目指していきます。
@cosmeアプリに関わってみたいという方がいましたら、お気軽にご連絡ください。
https://open.talentio.com/r/1/c/isytyle_career/pages/43022
https://open.talentio.com/r/1/c/isytyle_career/pages/43019

株式会社アイスタイル

Discussion