見出し画像

New Relicで発生したMGIの対応について

はじめに

私の関わるサービスでNew Relicを利用しているのですが、そこでMGI(Metrics Grouping Issue)が発生し、その対応を行うことがあったので、その時の事をお伝えしようと思います。

MGIとは?

以下、New Relicの公式ブログから抜粋となります。

New Relic APM、Browser、Mobile機能を使っていると、メトリクスの名前のパターン(種類)を大量に生成してしまうことがあります。メトリクスの名前のパターンが増えると、チャート、レポート、テーブルの項目が増え、その有用性が下がってしまいます。New RelicではこれをMetrics Grouping Issue (MGI)と呼んでいます。

MGIが発生すると、Metrics normalization に自動的に拒否ルールが作成されてしまい、新しいメトリクスが登録されなくなってしまいます。
このため、定期的にMGIの発生を監視し、発生時は対応する必要があります。

MGIの対応の流れ

対応方法はいろいろありますが、今回はアプリの修正などは行わずに、収集されたメトリクスを調整する方法をとりました。
ざっくりとした流れは以下のようになります。

  • Metrics normalizationでMGIが発生しているかを確認

    • MGIが検知されると、「DENY_NEW_METRICS」という新規メトリクスをリジェクトするルールが作成されます

    • 詳細を確認すると noteの部分に下記のようなに自動作成された旨が記録されています

Autogenerated metric normalization deny-new-metrics rule : deny_new_metrics
  • MGI detailで詳細を確認し、問題と思われるメトリクスを特定する

  • 見つけたメトリクスに対するMetrics normalization Ruleを作成し、集約(replace)または拒否(reject)を設定する

実際の対応例

上記だけではわかりずらいと思うので、実際の画面を加えながら今回実施した事を説明していきます。
なお、今回はAPMが収集しているメトリクスでMGIが発生していました。

Metrics normalization を選択

MGI details で詳細を確認

MGI troubleshooting で対象のメトリクスを確認

今回の例ではThreads/Stateが他に比べて多いことがわかります

メトリクスの詳細を確認

より詳細な状態を確認するためにNRQLを使います。
今回はAPMが対象なので、以下のようにappNameで絞り込みました。

FROM Metric SELECT metricTimesliceName
WHERE appName = 'xxxxxxx'
AND metricTimesliceName LIKE 'Threads/State%' 
AND newrelic.timeslice.value IS NOT NULL 
SINCE 60 MINUTES AGO LIMIT MAX

この結果から全体像の雰囲気を掴んでください。

集約するための正規表現を検証

まずはcaputreを利用してグルーピングして状況を確認してみます
発行したSOQLはこちらになります。

WHERE appName = 'xxxxx'
AND metricTimesliceName LIKE 'Threads/State%' 
AND newrelic.timeslice.value IS NOT NULL 
SINCE 60 MINUTES AGO LIMIT MAX
facet capture(metricTimesliceName, '(?P<metricName>Threads/[^/]+/[^- /]+).*')

他に比べて多いものがなんとく見えてきますね。

次は最も件数が多いThreads/State/MVStoreに絞って確認してみます

FROM Metric SELECT count(metricName)
WHERE appName = 'xxxxx'
AND metricTimesliceName LIKE 'Threads/State/MVStore%' 
AND newrelic.timeslice.value IS NOT NULL 
SINCE 60 MINUTES AGO LIMIT MAX
facet capture(metricTimesliceName, '(?P<metricName>Threads/[^/]+/[^/]+).*')

末尾に乱数が含まれていることがわかります。
なお、# となっている部分がありますが、これは数値の部分がNew Relic側で自動的に # に置き換えられているためです

乱数部分は情報として不要なので、以下のように置き換えてみます

# 元データ
MVStore background writer nio:-opt-xxxxxxxxxxxx-work-tmp-tmpslatdqg.... 

# 置換後データ
MVStore background writer nio

発行したNRQLはこちら

FROM Metric SELECT count(metricName)
WHERE appName = 'xxxxx'
AND metricTimesliceName LIKE 'Threads/State/MVStore%' 
AND newrelic.timeslice.value IS NOT NULL 
SINCE 60 MINUTES AGO LIMIT MAX
facet capture(metricTimesliceName, '(?P<metricName>Threads/State/MVStore [a-zA-Z ]+).*')

想定通りに集約されたことが確認できます

上記以外にも件数が多いものがありましたが、集約条件を探すまでの条件は同じであるため割愛します。

置換ルールを設定

これまでに確認した結果を元に、メトリクスを置換・集約するためのルールを登録します
今回は以下の内容で登録しました

  • Regular expression  : (Threads/[^/]+/[/a-zA-Z]*MVStore [a-zA-Z ]+).*

  • What do you want to do with the matches? : Replace

  • Replacement : \1

MGIで作成されたルールを無効化する

新しいメトリクスを登録できるようにするため、自動作成されたルールを無効化します
MGI detailsを表示する際のメニューの中に Deactivate というものがあるので、それを選択することでルールを無効できます

結果を確認

新しいルールが適応された状態で暫く動作させたのち、集約されているかを下記のようなNRQLを実行して確認します。

FROM Metric SELECT uniqueCount(metricTimesliceName)
WHERE entity.guid = 'xxxxxxxx'
AND metricTimesliceName LIKE 'MVStore background writer %' 
AND newrelic.timeslice.value IS NOT NULL 
SINCE '2024-03-03 00:00:00 UTC' UNTIL NOW LIMIT 20 FACET host.displayName TIMESERIES 

なお、発行するNRQLでmetricTimesliceNameのみを指定された場合は、1日程度はルール適用前のメトリクスが取得されてしまうという仕様があるそうなので注意してください。(現在は改善されている可能性もあります)

 SELECT metricTimesliceName FROM Metric

最後に

今回は実際に行なった手順に沿って説明したつもりですので、まだMGIに遭遇したことがない方にも、うっすらとでも対応のイメージが湧いたのではないでしょうか。

今回の記事が皆様の関わっているシステムの安定運用の助けになれば幸いです。

参考リンク


いいなと思ったら応援しよう!