【New Relic】New Relicのコストを削減!New Relic APMのチューニング例 

記事タイトルとURLをコピーする

はじめに

こんにちは、サーバーワークスの福田です。

今回は、APMにおける基本的な用語(Transaction, Trace, Span)の違いを整理しつつ、New Relic APM Agent 設定を用いてコスト削減する方法について、具体的な設定例(Python 編)を交えてご紹介します。

実は、去年の今頃もコスト削減についてブログを書いていました。 大きな流れは変わっておらず、基本は以下のサイクルです。

  • 必要な情報のみを収集する(今回のブログはここの内容)
  • コスト情報を可視化してさらに効率化する
  • これを繰り返す

blog.serverworks.co.jp

コスト情報可視化については上記ブログの構成ではなく今年発表された「Cloud Cost Intelligence」機能を使用するのが良いかと思います。
「Cloud Cost Intelligence」機能の詳細は以下のNew Relicさんのブログをご確認ください。

qiita.com

アプリケーション監視に必要となる要素について

まずは用語の簡単な紹介になります。(画像はGemini Nano-Bananaにより生成したものです)

  • Trace (Distributed Trace)
    「リクエストの全体像」になります。分散システム全体を横断する一連の流れを指します。システム全体で一意な traceId を付与して、複数のサービスをまたぐリクエストの経路を可視化します。
  • Span
    「個々の作業工程」 です。Trace や Transaction を構成する最小単位です。「DBへのクエリ実行」「外部APIコール」「内部メソッドの実行」などがこれに当たり、開始時間と終了時間を持ちます。
  • Transaction
    「アプリケーション(サービス)単位での処理のまとまり」 です。New Relic APM のメイン画面で見る単位がこれです。例えば WebTransaction/Function/views.order_create のように記録され、この単位でスループットや応答時間、エラー率が計測されます。1つの Transaction の中に、複数の Span が含まれます。

ECサイトの例

データの取捨選択とコスト削減

ここからが本題です。 「とにかく全部送る」設定のままだと、不要なデータでコストが膨れ上がってしまいます。

コスト削減のアプローチとして、今回はPython Agent 設定ファイル(newrelic.ini)によるチューニングにフォーカスします。
公式ドキュメントからコスト削減に効果的な項目をピックアップしました。

docs.newrelic.com

具体的な設定チューニング例 9選

⚠️ 前提条件

設定を変更して必要な情報まで欠落すると、いざという時の調査に支障が出ます。 本番環境へ適用する前に、必ず開発環境等で検証を行うことを推奨します。

1. スパンイベントの最大数制限

分散トレーシングの「Span」送信数を、1分間あたりでキャップする設定です。 意図しない実装(N+1問題や無限ループ等)による課金を防ぐことができます。またはテスト時にある程度性能を把握し、この設定を最適化することでコスト効率的な監視運用設計が実現可能になります。

  • マイクロサービスやDBアクセスが多い環境では、1リクエストで数百〜数千のSpanが生成されることがあります。
  • これらがアクセス集中時にそのまま送信されると、データ転送量が跳ね上がります。ここに上限を設けることで、データ転送量の上限のガードレールとして機能します。
# デフォルト(2000)よりも減らしてコストを抑制する
span_events.max_samples_stored = 1000

2. Code Level Metrics の停止

Code Level Metrics は、各 Span に「ソースコードのファイルパス」や「行番号」といった詳細なメタデータを付与する機能です。本来は New Relic CodeStream(IDE連携) を使い、New Relic の画面からエディタの該当行へ直接ジャンプするために活用する機能かと思います。

IDE連携をしていない場合でも画面上で「views.py の 42行目」といった情報は確認できますが、トランザクション名(例: views.order_create)さえ分かれば、開発者は「どのファイルのどの辺か」はおおよそ見当がつくかと思います。

  • 「手元のエディタで検索すれば済む」情報のためにコストを増やすのはもったいないため、IDE連携機能を使っていないのであれば、無効化することを検討してもいいかもしれません。
code_level_metrics.enabled = false

3. ログ転送の無効化

APM エージェントには、アプリケーションが出力したログを自動的に New Relic へ転送する機能(Logs in Context の一部)があり、デフォルトで true になっています。

エラーとログを紐付けられるのは便利ですが、すでに Fluentd, CloudWatch Logs などでログ基盤を構築している場合、APM エージェントからもログを送ると「全く同じログデータに対して二重にコストが発生」することになります。
また、アプリケーションプロセス内でログ送信処理を行うため、わずかながら CPU/メモリのオーバーヘッドも発生します。

  • 「ログは既存のログ収集基盤(Fluent Bit 等)に任せる」という構成であれば、APM 側の転送は迷わずオフにして、コストとリソースを節約しましょう。
application_logging.forwarding.enabled = false

4. トランザクション・トレースの調整

「何秒以上かかったら『遅い』とみなして詳細を記録するか」という設定です。
デフォルトは apdex_f(Apdex T の4倍)という相対値なのですが、これだと「今の設定だと何秒で記録されるんだっけ?」と直感的に分かりづらいのが難点です。

  • 「2秒以上かかったら調査対象」といった明確な基準があるなら、具体的な秒数を指定することも検討してもいいと思います。
  • こうすることで「本当に調査が必要な遅延リクエスト」だけが記録されるようになり、分析するためのノイズ情報やコストの削減につながります。
# 2.0秒以上かかったトランザクションのみトレース詳細を記録
transaction_tracer.transaction_threshold = 2.0

5. スタックトレースの調整

「どのコードからそのSQLが呼ばれたか」等を特定するスタックトレースはデバッグに必須ですが、データ構造としては大量のテキスト情報です。これが全クエリに付くとデータ量は馬鹿になりません。

  • デフォルトでも 0.5 秒という閾値が設定されていますが、環境によってはこれでもデータ量が多くなる場合があります。よりコストを厳しく管理したい場合は、この値を 1.0 秒などに引き上げることを検討してください
# 1.0秒以上かかった処理(SQL等)のみスタックトレースを記録
transaction_tracer.stack_trace_threshold = 1.0

6. SQL実行計画(EXPLAIN)の自動取得停止

遅いクエリに対して Agent が自動的に EXPLAIN を発行してくれる機能です。
パフォーマンス分析には便利なのですが、「高負荷なDBに対して、さらに追加クエリを投げる」ということも考慮する必要があります。

  • AWS RDS Performance Insights など、DB側で分析ができる環境なら、APM側で二重に取得する必要性はあまりないです。DB負荷への影響やデータ量(実行計画もテキスト量が多いです)を懸念する場合は、オフにする選択肢も検討してみてください。
transaction_tracer.explain_enabled = false

7. SQLクエリ記録の無効化・Slow SQLの停止

SQLの記録は便利ですが、「最も情報漏洩につながりやすい箇所」でもあります。

  • Agent もマスク処理(難読化)をしてくれますが、特殊なクエリなどで個人情報がログに残るリスクをゼロにはできません。金融・医療系などコンプライアンス要件が厳しい場合は、リスク回避のために off でもいいかもしれません。
  • slow_sql(スロークエリ記録)についても、遅いクエリほどSQLが長大になりがちなので、ここを止めるだけでもコスト削減効果は大きいです。「スロークエリの分析はDB側のログでやる」と割り切れるなら、無効化してしまいましょう。
# SQL文を記録しない
transaction_tracer.record_sql = off

# スロークエリの個別記録も停止する
slow_sql.enabled = false

8. ブラウザ監視の自動挿入を停止

New Relic APM はデフォルトで、HTMLレスポンスに自動的に JavaScript(Browser Agent)を注入しようとします。 Browser 監視を導入しない等の場合はこの自動注入をオフにすることで、HTML生成時のオーバーヘッドと余計なトラフィックを削減できます。

browser_monitoring.auto_instrument = false

9. 不要な属性情報(Attributes)の除外設定

見落としがちですが、Span や Transaction に付与される「属性データ(Attributes)」も課金対象のデータ量に含まれます。

特に、Webリクエストの request.headers(Cookie や User-Agent など)や、自動収集されるパラメータの中に、分析に不要かつデータサイズが大きいものが含まれている場合は、明示的に除外設定を行うことをお勧めします。

# 除外したい属性をスペース区切りで指定
# 例: Cookie, Authorizationヘッダー, および特定のパラメータを除外
attributes.exclude = request.headers.cookie request.headers.authorization request.parameters.huge_data_param

気になった点

設定を見直していて、いくつか気になった点もありました。

  • 閾値のさじ加減
    transaction_tracer.transaction_threshold を上げすぎると、ユーザーが「ちょっと重いな」と感じているレベルの遅延(例えば1.5秒)がトレースとして記録されないので注意が必要です。
  • プロセスの再起動
    newrelic.ini の変更を適用するには、アプリケーションサーバー(Gunicorn, uWSGI, Daphne 等)の再起動が必要です。Docker コンテナで運用している場合は、イメージのビルドまたはコンテナの再起動を行うタイミングに注意してください。
  • 設定方法の優先順位
    Python Agent は newrelic.ini よりも 環境変数(NEW_RELIC_... の設定が優先されます。iniファイルを書き換えても反映されない場合は、環境変数側で上書きされていないかを確認する必要があります。

まとめ

今まで自分の頭の中にはあるものの上手く整理されていなかったのでTransaction、Trace、Span の違いを整理し、さらに Python Agent 側の設定ファイルでの具体的なコスト削減策について記載してみました。

デフォルト設定のままでも動くのが New Relic の良いところですが、少し踏み込んで必要なデータは残しつつ、コスト効率的な運用を実現していきたいですね。(オブザーバビリティは上手に実現しないとお金かかるだけなので)

「可観測性は高めたいけれど、コストは抑えたい」。
このバランスを取るために、まずは設定ファイルを見直してみることから始めてみてはいかがでしょうか。

・福田 圭(記事一覧)

・マネージドサービス部 所属
・X(Twitter):@soundsoon25

2023 New Relic Partner Trailblazer。New Relic Trailblazer of the Year 2025受賞。New Relic User Group運営。