New Relicをフルに活用するためにデータ量とコストに気を配る

こんにちは、TVerの加我です。
こちらは TVer Advent Calendar 2023New Relic 使ってみた情報をシェアしよう! by New Relic Advent Calendar 2023 の8日目の記事です。

みなさまNew Relicを活用していますか?サービスの信頼性を担保していますか?オブザーバビリティの導入・実現に向けてNew Relicを使い倒していますか?

New Relicは非常に高機能なオブザーバビリティプラットフォームです。TVerではフロントエンドからバックエンドまでNew Relicを活用した横断的な観測を行っています。しかしNew Relicを導入し活用していくにつれて気になってくるのがコストです。

ということで、New Relicを活用しつつコストを最適化するためのポイントについて考えていきます。

New Relicのコスト計算についておさらい

まずはNew Relicの価格設定について理解していきましょう。
New Relicでは「有償のユーザー数」と「取り込むデータ量」の2点が請求対象となります。

ユーザー数による請求については後述する有償のユーザー追加がなければ変動がない部分なのでほぼ固定費、取り込むデータ量についてはアクセス数やイベント数により大きく変動することがあるため変動費と考えることができます。つまり取り込むデータ量を最適化することが重要です。

docs.newrelic.com

こちらについてはAdministrationのPlan & usageにて利用状況を確認することができます。

Plan & usage

Plan & usageのUsage breakdownからView detailsを選択することでデータソース毎の取り込むデータ量を確認することができます。

Data ingested (GB) per day by data source

1. 有償のユーザー数

New Relicには「Full Platform User」「Core User」「Basic User」という3つのユーザー種別があります。このうち有償のユーザーとして請求対象になるのは「Full Platform User」と「Core User」です。TVerではFull Platform UserとBasic Userを利用した権限管理を行っています。Core Userはユースケースがマッチしなかったので利用していません。

ユーザー区分 利用者 利用目的
Full Platform User エンジニア
カスタマーサポート
バックエンドAPIのTransaction調査
モバイルアプリのクラッシュ調査
クラウドインフラのリソース調査
Core User - -
Basic User ディレクター
エンジニア
ダッシュボードを通じたデータ確認

ユーザー毎の権限については下記ドキュメントを参照ください。

docs.newrelic.com

2. 取り込むデータ量

イベントやメトリクスやログといったテレメトリーデータをNew Relic (NRDB) に取り込む際に請求対象となります。TVerではフロントエンドからバックエンドまでNew Relicを利用しているため、各所で発生したテレメトリーデータがNew Relic (NRDB) に取り込まれ請求対象となります。

主なデータの発生元 New Relicへの取り込み方法 主なデータソース (NRDB)
Webブラウザ New Relic Browser Browser events
Mobileアプリ New Relic Mobile Mobile events
バックエンドAPI New Relic APM APM events
クラウドインフラ
(AWSGoogle Cloud)
New Relic Infrastructure Metrics
Infrastructure integrations
各種ログ New Relic Logs Logging

docs.newrelic.com

今回はこちらの「取り込むデータ量」についてのお話です。

何が起こったのか

2022年4月のサービスリニューアル以降、定期的なNew Relic Agentのアップデートを行えていませんでした。New Relic Agentには定期的なバグフィックスやセキュリティアップデートや機能追加が行われているため、2023年3月12日頃に諸々のAgentのアップデートを行いました。しかしアップデートを実施した結果、New Relic Browser Agent (Web) の更新によりBrowser eventsで取り込むデータ量が10倍程度に膨れ上がってしまいました。

Browser eventsのデータ量が急増

New Relicのサポートにもアップデート内容の確認や原因の調査についてご相談したのですが、残念ながらこれという決定的な証拠を見つけることができませんでした。可能性としては「当初の設定の不備により必要なデータを取得できていなかった」もしくは「分散トレーシング周りのアップデートがあり取得できるイベントが増えた」かと考えています。

フロントエンド系のデータを扱うNew Relicアカウントで急激なデータ増加

BrowserEventsBytesで急激なデータ増加

当時はNew Relicを駆使してサービスの信頼性を可視化・担保するというミッションを推進していたため「今はどんどん可視化を進めていきたい」「何はともあれオブザーバビリティ」といった流れで進めていった結果、データ量やコストの意識が二の次になってしまいました。New Relicにかかるコストのオブザーバビリティは後回しになってしまい恥ずかしい限りです。

特定のURLが高頻度で閲覧されていたりスクレイピングされている可能性も疑いましたが、全体的なイベント数が増加していることを確認して改善案を考えました。

改善

取り込むデータ量の可視化と通知、そしてデータ量の削減という二軸で対応しました。

1. 取り込むデータ量の可視化 & 定期的な通知

まずは「現状どのような取り込みデータ量になっているのか」「いつからデータ量が増加したのか」「どのデータソースで増加があったのか」を判断できるようなデータおよびダッシュボードを整備しました。そのためにNew Relicアカウント別のグラフとデータソース別のグラフを用意しました。

NRQLだとこんな感じです。24時間のグラフだと増減がわかりにくかったので3日間のデータを毎日見るようにしています。

# [前日比] アカウント別のデータ量
SELECT rate(sum(GigabytesIngested), 1 day) AS avgGbIngestTimeseriesByAccount FROM NrConsumption WHERE productLine = 'DataPlatform' FACET consumingAccountName TIMESERIES AUTO SINCE 3 days AGO COMPARE WITH 1 day ago
# [前日比] データソース別のデータ量
SELECT rate(sum(GigabytesIngested), 1 day) AS avgGbIngestTimeseries FROM NrConsumption WHERE productLine = 'DataPlatform' FACET usageMetric LIMIT MAX TIMESERIES AUTO SINCE 3 days AGO COMPARE WITH 1 day ago

上記のNRQLをグラフにしたのが下記のスクリーンショットです。

New Relic全体のデータ量推移 (アカウント別とデータソース別)

また、バックエンド (New Relic APM, New Relic Infrastructure) に比べるとフロントエンド (New Relic Browser, New Relic Mobile) の方がデータ量にばらつきが大きいことがわかっているため、主要なイベント数の推移を把握できるグラフを用意しました。こちらも24時間のグラフだと増減がわかりにくかったので3日間のデータを毎日見るようにしています。

# とあるBrowserアプリケーションのグラフをイベントごとに作成
SELECT count(*) FROM AjaxRequest WHERE appName = '<ブラウザアプリ>' TIMESERIES SINCE 3 days ago
SELECT count(*) FROM BrowserInteraction WHERE appName = '<ブラウザアプリ>' TIMESERIES SINCE 3 days ago
SELECT count(*) FROM JavaScriptError WHERE appName = '<ブラウザアプリ>' TIMESERIES SINCE 3 days ago
SELECT count(*) FROM PageView WHERE appName = '<ブラウザアプリ>' TIMESERIES SINCE 3 days ago
SELECT count(*) FROM PageViewTiming WHERE appName = '<ブラウザアプリ>' TIMESERIES SINCE 3 days ago
# とあるMobileアプリケーションのグラフをイベントごとに作成
SELECT count(*) FROM Mobile WHERE appName = '<モバイルアプリ>' TIMESERIES SINCE 3 days ago
SELECT count(*) FROM MobileCrash WHERE appName = '<モバイルアプリ>' TIMESERIES SINCE 3 days ago
SELECT count(*) FROM MobileRequest WHERE appName = '<モバイルアプリ>' TIMESERIES SINCE 3 days ago
SELECT count(*) FROM MobileRequestError WHERE appName = '<モバイルアプリ>' TIMESERIES SINCE 3 days ago
SELECT count(*) FROM MobileSession WHERE appName = '<モバイルアプリ>' TIMESERIES SINCE 3 days ago
SELECT count(*) FROM MobileVideo WHERE appName = '<モバイルアプリ>' TIMESERIES SINCE 3 days ago
SELECT count(*) FROM Span WHERE appName = '<モバイルアプリ>' TIMESERIES

上記のNRQLをグラフにしたのが下記のスクリーンショットです。各グラフをStacked Bar形式にして積み上げて確認しています。

Browser系のイベント数推移

Mobile系のイベント数推移

推移を見るグラフが整備できたのであればあとは通知です。クラスメソッド株式会社の新井成一さんがNew RelicのダッシュボードをSlackへ定期的に投稿するためのツールを公開してくれていたため、こちらを利用させていただきました。

github.com

dev.classmethod.jp

実際にSlackに送られるとこのような感じになります。

Slack通知

これにより、データ量の推移と異常を見逃すことがなくなりました。Anomalyでデータ容量に対してアラートを設定するのもアリかもしれません。

2. 取り込みデータ量の削減

New Relicで取り込みデータ量を削減するには「取り込みデータのサンプリングを実施する」か「Data Drop Ruleを設定してデータの除外設定をする」という2つの方法があります。当時はデータのサンプリングについての検証が行えていなかったため、素直にData Drop Ruleを設定して不要なデータを除外する方向で対応しました。

Data Drop RuleについてはNerdGraphというGraphQLのAPIを利用してデータを除外するためのルールを作成・削除することが可能です。

docs.newrelic.com

NerdGraph API Explorer にアクセスすると下記のような画面が表示されます。

NerdGraph API Explorer

例えばDrop Ruleの一覧を取得したい場合には下記のようなクエリを入力して実行することでDrop Ruleの一覧を取得することが可能です。

{
  actor {
    account(id: <対象となるNew RelicのアカウントID>) {
      nrqlDropRules {
        list {
          rules {
            id
            nrql
            accountId
            action
            createdBy
            createdAt
            description
          }
          error {
            reason
            description
          }
        }
      }
    }
  }
}

また、Drop Ruleを追加したい場合には下記のようなクエリを入力して実行することでDrop Ruleを追加することが可能です。
DROP_DATAは指定したNRQLに該当するデータを除外するもの、DROP_ATTRIBUTESはNRQLに該当する属性・カラムのデータのみを除外することが可能です。

mutation {
  nrqlDropRulesCreate(
    accountId: <対象となるNew RelicのアカウントID>
    rules: {action: <DROP_DATA|DROP_ATTRIBUTES>, description: "<Dropルールの説明>", nrql: "<Dropしたいデータを抽出するためのNRQL>"}
  ) {
    failures {
      error {
        description
        reason
      }
    }
    successes {
      account {
        id
        name
      }
      accountId
      action
      createdAt
      createdBy
      description
      creator {
        id
        name
      }
      id
      source
      nrql
    }
  }
}

しかしNerdGraphはあまり利便性が高いとは言えないため、ここに関してはTerraformで管理することをおすすめします。

# drop_dataの例
resource "newrelic_nrql_drop_rule" "foo" {
  account_id  = 12345
  description = "Drops all data for MyCustomEvent that comes from the LoadGeneratingApp in the dev environment, because there is too much and we don’t look at it."
  action      = "drop_data"
  nrql        = "SELECT * FROM MyCustomEvent WHERE appName='LoadGeneratingApp' AND environment='development'"
}

# drop_attributeの例
resource "newrelic_nrql_drop_rule" "bar" {
  account_id  = 12345
  description = "Removes the user name and email fields from MyCustomEvent"
  action      = "drop_attributes"
  nrql        = "SELECT userEmail, userName FROM MyCustomEvent"
}

Resource: newrelic_nrql_drop_rule registry.terraform.io

Data Drop Ruleの整備により不要なデータを除外することに成功しました。オレンジ色のBrowser eventsの領域が小さくなっていることがわかります。この後に青のMobile eventsを最適化するためにDrop Ruleの調整を行っています。

Plan & usageにてBrowser eventsの減少を確認

フロントエンド系のデータを扱うNew Relicアカウントでデータの減少を確認

BrowserEventsBytesのデータ減少を確認

今後の展望

現在モバイルアプリ開発にて取り込みデータのサンプリングの検証を進めており、Data Drop Ruleとサンプリングの併用でデータ量の最適化を行う予定です。

私達が不要と考えて除外している特定のデータが実はユーザーの体験に関わる問題に関連しており、それを見逃してしまうという可能性を回避したいというのが背景です。本来であれば全てのデータを取得したうえで一律に削減したほうが良いと考えていますが、まだまだ検証中の段階でありリリースは2024年前半の見込みです。

まとめ

TVerにおけるオブザーバビリティの導入・推進の裏側で発生していたデータ量とコストの問題にフォーカスした記事でした。パブリッククラウドSaaSも便利ですが請求に影響するデータのチェックを怠ってはいけません。1つの設定変更で大きな請求が発生してしまう可能性があります。まずはしっかりと状況を可視化したうえで対処していきましょう。

余談ですが、株式会社ヘンリー様のエンジニアブログにある「オブザーバビリティにはお金がかかる」という記事を拝見しまして「私も会社にはNew Relicとオブザーバビリティの重要さについて説明してきたし理解して貰ってると思うけど、とはいえ安くはないし悩ましいよなぁ・・・」という思いから今回の記事の執筆のモチベーションとさせていただきました。

dev.henry.jp