以前このような記事を投稿しました。

https://blog.newrelic.co.jp/new-relic-solutions/transaction-naming-and-mgi/

その後、New Relic APMにおいてMetrics Grouping Issue(MGI)が実際に発生しているケースでどう対応すればわからないというフィードバックを何件か頂いたため、対応方法をより具体的にご案内したいと思います。

MGIが起きていることを確認する

多くの場合、「MGIが起きた」事実を直接確認することよりも、「MGIを検知して自動作成されたDENY_NEW_METRICルールによって引き起こされる」問題に遭遇することでMGIの発生に気づきます。「MGIを検知して自動作成されたDENY_NEW_METRICルールによって引き起こされる」問題はさまざまなものがありますが、例えば「New Relic OneのAPMの一部のチャートのUIが表示されなくなる」といったものがあります。

このような症状に遭遇した場合、以下の「MGIが起きた」事実を直接確認する、もしくはテクニカルサポートに問い合わせることでMGIが起きたことを確認する、あるいは別の原因であることを知ることができます。

MGIが起きたことを確認する方法は2つあります。1つ目は、APMのSettings>Metrics  normalization UIを開き、DENY_NEW_METRICルールが作成されていることを確認する方法です。

もうひとつの方法は、NrIntegrationErrorでDENY_NEW_METRICルールが作成されたイベントを探す方法です。この方法だといつMGIが発生したかまで知ることができます。

FROM NrIntegrationError SELECT * WHERE category = 'Metric Cardinality' SINCE 6 months ago

このいずれかの方法でMGIが発生し、DENY_NEW_METRICルールが作成されていることを確認できたら、次はMGIの原因を探します。

MGIの原因を探す

最終的にはMGIの原因を探し、解消し、DENY_NEW_METRICルールを無効化することで問題を解決することができます。最後のDENY_NEW_METRICルールの無効化はお客様では行うことができずテクニカルサポートにお問い合わせ頂く必要があります。しかし、なにも変更せずにDENY_NEW_METRICルールのみ無効化するお問い合わせには還俗対応できません。それは、一度無効化しても問題を解決していない限り再度同じ状況に陥り、DENY_NEW_METRICルールが有効化されるためです。

MGIの原因を探すためには、どのようなタイプのメトリクスが、種類が多くレポートされているかを調べる必要があります。ポイントはメトリクスの値ではなく、種類(名前)です。過去の事例では、トランザクション名、Datastore関連、外部サービス関連、カスタムメトリクス関連が主な要因です。1つのみが原因である場合もあれば複数原因であることもあります。複数が原因の場合は、すべての原因に対応する必要があるため、以下の具体的な手順を順に実施してください。それぞれの対策については次の項で説明します。また以下で出てくるNRQLではapp_idをMGIの起きているAPMのApplication IDに置き換えて実行してください。

トランザクション名

SELECT uniqueCount(name) FROM Transaction Where appId='<app_id>' SINCE 7 days AGO limit max

MGIの発生に明確な閾値はありませんが、おおよそ数百以上であればMGIの原因となりえます。どこでトランザクションの名前が大量に発生しているか調べるためには、例えば以下のようなFACET casesを使って絞り込んでいきます。

SELECT uniqueCount(name) FROM Transaction Where appId='<app_id>' FACET cases(where name LIKE 'OtherTransaction/xxx/yyy%',where name LIKE 'OtherTransaction/xxx/zzz%' ,where name LIKE 'WebTransaction%') SINCE 7 days AGO limit max

Datastore関連

FROM Metric SELECT count(newrelic.timeslice.value) WHERE appId='<app_id>' and metricTimesliceName LIKE 'Datastore%' FACET metricTimesliceName SINCE 7 days ago LIMIT MAX

トランザクションと異なり直接的に種類の数をクエリする方法が見つからなかったため、種類の数だけcount(newrelic.timeslice.value)を表示します。

Datastore関連が原因の場合、メトリクス名(metricTimesliceName)はAPMの言語とDatastoreの種類によって命名が異なるため実際の名前を見て判断します。たとえば、テーブルを動的に作成しているためSELECT対象となるテーブル名が大量にある場合や、T-SQLやPL/SQLなどのプロシージャを動的に作成しているため対象となる名前が大量にある場合が原因となります。

外部サービス関連

FROM Metric SELECT count(newrelic.timeslice.value) WHERE appId='<app_id>' and metricTimesliceName LIKE 'External%' FACET metricTimesliceName SINCE 7 days ago LIMIT MAX

外部サービスの場合もDatastore関連と同じようにSQLで検索できます。外部サービスが原因となるケースは、そのほとんどが外部サービスの通信先のドメインが多数存在している場合です。

カスタムメトリクス関連(およびその他)

カスタムメトリクス関連の場合は、明示的にカスタムメトリクスを取得しているはずなのでDatastore関連あるいは外部サービス関連で使ったNRQLのLIKEの部分をカスタムメトリクスの名前に変えて調査します。あるいは、いままでのいずれにもあてはまらない場合は、LIKE節を変えながら絞込んでいきます。

MGIに対応する

トランザクション名

トランザクション名の種類が多い場合、対応策としてはアプリケーション側の計装コードを変更するあるいはMetrics normalizationルールを新規に作成する、の2通りが考えられます。まず計装コードの変更で対応できないか検討することをおすすめします。

計装コードの変更をする場合、まずトランザクションの命名についてすでに計装コードを追加していないか(デフォルトから追加していないか)確認します。例えば、パターン数が多数あるクエリ文字列の値をトランザクション名に追加している計装コードがあれば、そのコードの修正を強くおすすめします。

次にAPM Agentのデフォルトのトランザクションの命名を利用しているが、トランザクション名の種類が多くなる場合、計装コードを追加して適切な単位でトランザクションをグルーピングすることを検討してください。計装コードを追加することで最も思い通りにグルーピングすることが可能になります。

これらの方法はAPM Agentの言語ごとに詳細な手順が異なるため、こちらのドキュメントから概要を参照し、言語ごとの手順を確認してください。

計装コードの追加・変更が難しい場合は、Metrics normalizationルールを新規に作成して対応します。次の項を参照してください。

Datastore関連や外部サービス関連

Datastore関連や外部サービス関連の場合、コードの変更による対応が困難であることがほとんどだと思われます。Metrics normalizationルールを新規に作成して対応するために次の項を参照してください。

カスタムメトリクス関連(およびその他)

カスタムメトリクス関連の場合は、カスタムメトリクスでレポートする種類が多くならないように計装コードを修正してください。それ以外の場合は、そのメトリクスがどこからレポートされているか確認するためにテクニカルサポートにお問い合わせください。

Metrics normalizationルールを作成する

例えば、Datastore関連で「Datastore/statement/MySQL/{xxxx}/select」という形式で{xxxx}部分が大量にあるメトリクスがレポートされているとします。その場合Metric normalizationルールを作成することで、{xxxx}を一つにまとめて「Datastore/statement/MySQL/[tables]/select」に置き換えて同じ名前のメトリクスとしてレポートすることができます。まとめる対象は正規表現が利用でき、また置き換えたあとの名前に正規表現でマッチしたグループを参照することができるため、比較的高度なグルーピングが可能になります。

詳細はドキュメントを参照してください。