API監視をDatadogからNew Relicに移行して感じたそれぞれの特徴

この記事は New Relic Advent Calendar 2025 の 15 日目の記事です。

はじめに

こんにちは。株式会社フィックスポイントの KI です。

先日、私が所属しているプロダクトデベロップメント部で開発しているKompira cloudAPI監視をDatadogからNew Relicに移行しました。
そこで、以下についてご紹介します。

この記事の前半では実際の移行の背景と、移行を通じて感じたDatadogとNew RelicのAPI監視機能の特徴と比較について紹介します。
後半では、New Relic でのAPI監視(Synthetic API tests)をTerraformで設定する場合のおすすめの書き方を紹介します。

監視SaaSAPI監視をこれから設定する方や、New Relicでより自由度の高いAPI監視を設定していきたいと考えている方の参考になれば幸いです。

目次

移行の背景

Datadogで実現していたAPI監視

DatadogではSynthetic test機能でAPIテストを書いていました。

DatadogのSynthetic testにはSingle API testMultistep API testsの二種類があります。
Kompira cloudでは両方の利用をしており、以下のようなテストをしていました。

Single API test は GET エンドポイントの監視に向いています。

Single API test の例
  • 定期的に /api/<省略> に GET リクエストを実行
  • レスポンスのステータスコードが 200 であることを確認
  • レスポンスタイムが 30 秒以内であることを確認

Multistep API tests は PUTエンドポイントなどの、現在のリソースを変更するようなエンドポイントの監視に向いています。

Multistep API tests の例
  • 定期的に /api/<省略>/items に GET リクエストを実行
  • /api/<省略>/items のレスポンスタイムが 30 秒以内であることを確認
  • /api/<省略>/items のレスポンスボディをパースして特定の要素を持つ配列があることを確認
  • /api/<省略>/items のレスポンスボディをパースして取得した配列のはじめの要素から ID を取得
    • $.items[0].id のような JSON パスで指定して取得が可能
  • /api/<省略>/<id> に決められた内容の PUT リクエストを実行
  • /api/<省略>/<id> のレスポンスタイムが 30 秒以内であることを確認
  • /api/<省略>/<id> のレスポンスのステータスコードが 200 であることを確認

New Relicへの移行理由

New Relicへの移行理由ですが、DatadogでのAPI監視に課題があったわけではありません。

前提として、総合的な判断の結果として既にここ数年のAPI監視以外のKompira cloudの監視はNew Relicで実施していました。
よってAPI監視をNew Relicに移行して利用SaaSを一本化すると、利用料金や認知コストの削減に繋がるため、New Relicへ移行することにしました。

DatadogとNew Relicの比較

API 監視機能の仕様の比較

Datadog

API Testingという機能名で提供されています。

以下のテストに対応しています。

  • HTTP ( Multistep に対応)
  • SSL
  • DNS
  • WebSocket
  • TCP
  • UDP
  • ICMP
  • gRPC ( Multistep に対応)

Datadogの料金体系は「どの機能を」「どれくらいの量」利用したかで決定します。
そのため、API 監視機能についても実行回数で料金が決まっていました。

New Relic

Synthetic API tests ( UI では Scripted API monitor とも)という機能名で提供されています。
Scripted API monitorの名の通り、Node.jsスクリプトを記述することでAPI監視を実現するものです。

以下でサポートされている Node.js ライブラリが利用可能です。

docs.newrelic.com

WebSocket に対応するためのwsライブラリや、gRPC関係のprotocol-buffers, Pingnet-pingなども対応しています。

New Relic自体の料金体系は「転送データ量」「課金ユーザー数」で決定します。
そのため、すでにNewRelicの利用があれば API 監視を追加しても利用料金は変わりません。(※1)
※1 Proプランの場合1,000,000​ (100 万) チェックまでがプラン内に含まれ、超過分は1回ごとに $0.005かかります。100 万​チェックは、 5 分ごとのチェックの外形監視 115 個分に相当します。

ただNew Relicのユーザー区分として「課金ユーザー」と「Basicユーザー」があり、「課金ユーザー」はそこそこの値段がかかります。
そして「課金ユーザー」のみがこの API監視機能のWeb画面での編集権限を持つことに注意が必要です。

使ってみての比較

総合的な特徴

以下のような印象を持ちました。

  • 癖がなく、良い設定ができるよう誘導されやすいDatadog
  • 自由度が高く、どんな需要にも応えられるNew Relic

逆の移行は仕様上も無理なケースもありますし、New Relicの自由度の高さに助けられました。

Web画面操作・GUI
  • Datadog
    • 「ガードレールがしっかりしている」という印象
    • GUI での設定がとにかくやりやすい
    • アサーション(期待するテスト結果)の定義もかゆい所に手が届く、いい設定項目が用意されている
  • New Relic
    • 「圧倒的自由度の代わりに、分かりにくい面もある」という印象
    • ITエンジニア向けに自由度の高い設定が可能
    • Web 画面のエディタはかなり不親切
      • カーソル位置が見にくい
      • コードフォーマット機能が無い
    • 限られたユーザー(課金ユーザー)しか GUI が閲覧できない

GUIに関しては圧倒的にDatadogのほうが体験が良いです。
以下のような画面で「どのURLにアクセスするか」「どのような確認をするか」を設定します。

https://docs.datadoghq.com/ja/synthetics/api_tests/http_tests/ より

開発者や開発スキルがある人が時間をかけてじっくり設定するのではなく「何も監視がないところに、今すぐ監視を入れたい」みたいな場合はDatadogのほうがマッチしているだろうと感じました。

New Relicの画面は実行頻度や実行ロケーションの設定以外はスクリプト入力画面があるのみです。

実際の利用画面よりキャプチャ

Terraform での設定しやすさ

他のIaCの方法もあるのかも知れませんが、すでに開発チーム内ではTerraformを利用しているため、TerraformでのIaCをしました。

Kompira cloudの場合は「GET のテストならこういったことを確認する」「PUTの場合は○○を確認する」といったようにHTTP リクエストメソッドごとに確認していることは同様のものが多かったので、テンプレートモジュールを作成することで事足りました。
もしエンドポイントごとに確認方法が異なる場合は多数のスクリプトを用意する必要があるので、その部分が負担になる可能性はあるかも知れません。

New RelicでのAPI監視をTerraformで書く

このセクションでは、New RelicでのAPI 監視のTerraform定義について具体的なソースコードを挙げ共有いたします。 これからTerraformでの設定をしたい方の役に立てば幸いです。

New RelicのSynthetic API tests機能のおさらい

Synthetic API testsはNewRelic上に設定したNode.jsスクリプトを定期実行するものです。

利用可能な最新のNode.js のバーションは22で、利用可能なサードパーティーライブラリに制限があります。

また、スクリプト内でパスワードなどのセンシティブなデータを読み込みたい場合はsecure credentials機能があります。

以下のように$secure.<name>という記法で変数にクレデンシャル値を格納し、利用が可能です。

const applicationId = $secure.APP_ID;

実際のTerraform定義

newrelic/newrelic provider のnewrelic_synthetics_script_monitor resource は以下のようなリソースです。

resource "newrelic_synthetics_script_monitor" "monitor" {
  status               = "ENABLED"
  name                 = "script_monitor"
  type                 = "SCRIPT_API"
  locations_public     = ["AP_SOUTH_1", "AP_EAST_1"]
  period               = "EVERY_6_HOURS"

  script               = "console.log('it works!')"

  script_language      = "JAVASCRIPT"
  runtime_type         = "NODE_API"
  runtime_type_version = "16.10"

  tag {
    key    = "some_key"
    values = ["some_value"]
  }
}

上記で分かる通り、script 属性にスクリプトを含める必要があります。
このままだとスクリプトが書きにくいので、別ファイルに切り出し等をし、以下のようなテンプレートを作成しました。

terraform {
  required_providers {
    newrelic = {
      source = "newrelic/newrelic"
    }
  }
}

resource "newrelic_synthetics_script_monitor" "main" {
  # DISABLED にした際 diff が少なくなるよう定義を書いておくのがオススメです
  status           = "ENABLED"
  name             = var.monitor_name
  type             = "SCRIPT_API"
  locations_public = var.monitor_locations
  period           = var.monitor_period

  script = var.script

  script_language      = "JAVASCRIPT"
  runtime_type         = "NODE_API"
  runtime_type_version = var.node_version

  dynamic "tag" {
    for_each = var.tags[*]

    content {
      key    = tag.value.key
      values = tag.value.values
    }
  }
}

variable "monitor_name" {
  type = string
}

variable "monitor_locations" {
  type = list(string)
}

variable "monitor_period" {
  type = string

  validation {
    condition     = contains(["EVERY_MINUTE", "EVERY_5_MINUTES", "EVERY_10_MINUTES", "EVERY_15_MINUTES", "EVERY_30_MINUTES", "EVERY_HOUR", "EVERY_6_HOURS", "EVERY_12_HOURS", "EVERY_DAY"], var.monitor_period)
    error_message = "The monitor period must be one of the following: EVERY_MINUTE, EVERY_5_MINUTES, EVERY_10_MINUTES, EVERY_15_MINUTES, EVERY_30_MINUTES, EVERY_HOUR, EVERY_6_HOURS, EVERY_12_HOURS, EVERY_DAY."
  }
}

variable "script" {
  type = string
}

variable "node_version" {
  type = string
  # 2025-11-05 に 22.20.0 が利用可能になりましたたが
  # terraform provider が対応済みかは未確認のため
  # 確認済みの 16.10 をデフォルトにしています
  default = "16.10"
}

variable "tags" {
  type = list(object({
    key    = string
    values = list(string)
  }))
  default = null
}

上記テンプレートモジュールの利用側は以下のように書きます。
この定義は、以下のようなテストを作成しています。

  • 実行間隔: 5分ごと
  • 実行ロケーション: Tokyo
  • https://example.com/api/foo/bar にアクセスして、レスポンスステータスが 200 であることを確認
module "bar_monitor" {
  source = "../../modules/synthetics_script_monitor"

  monitor_name      = "GET /api/foo/bar"
  monitor_locations = ["AP_NORTHEAST_1"]
  monitor_period    = "EVERY_5_MINUTES"

  script = templatefile("${path.module}/scripts/get_test_template.js", {
    # js 内の `${env}` 内を置換
    # New Relic の credential は大文字なので合わせる
    env = "DEV"
    # js 内の `${path}` 内を置換
    path = "api/foo/bar"
    # NOTE: `${clientSecret}` という文字列を残すために `$${...}` としている
    clientSecret = "$${clientSecret}"
  })

  tags = [
    {
      key    = "some_key"
      values = ["some_value"]
    }
  ]
}
var assert = require('assert');

// ENV が DEV の場合、New Relic 上に保存している TOKEN_DEV credential から値が読み取られて変数に格納される
const clientSecret = $secure.TOKEN_${env};

const requestURL = "https://example.com/${path}"

const headers = {
  accept: "application/json",
  "Authorization": `Bearer ${clientSecret}`,
}
const options = {
  headers: headers,
  timeout: {
    request: 30 * 1000,
  },
}
const res = await $http.get(
  requestURL,
  options,
  (err) => {
    if (err) {
      throw new Error("HTTP request failed: " + err.message);
    }
  }
);

assert.equal(res.statusCode, 200);

Terraformのtemplatefile関数は ${...}という文字列がある箇所について、指定した文字列に変換します。
JavaScriptテンプレートリテラル${...}のため、templatefile関数の引数に指定したファイル内の${...}箇所は全て何に置換するか指定が必要です。
※指定しないとエラーになります。

そのため上記のJavaScript${clientSecret}${clientSecret}として残すために"$${clientSecret}"とする必要があります。

上記のモジュールを利用すると、以下のようなJavaScriptを5分ごとに実行するよう設定できます。

var assert = require('assert');

// ENV が DEV の場合、New Relic 上に保存している TOKEN_DEV credential から値が読み取られて変数に格納される
const clientSecret = $secure.TOKEN_DEV;

const requestURL = "https://example.com/api/foo/bar"

const headers = {
  accept: "application/json",
  "Authorization": `Bearer ${clientSecret}`,
}
const options = {
  headers: headers,
  timeout: {
    request: 30 * 1000,
  },
}
const res = await $http.get(
  requestURL,
  options,
  (err) => {
    if (err) {
      throw new Error("HTTP request failed: " + err.message);
    }
  }
);

assert.equal(res.statusCode, 200);

上記の例では Bearer ${clientSecret} というコードのためにTerraformでclientSecret = "$${clientSecret}"のように書く必要が出てきてしまっています。 そのため、以下のように変更するのも手です。

const headers = {
  accept: "application/json",
  "Authorization": "Bearer " + clientSecret,
}

このようなことに気を遣いながらJavaScriptを書く必要性がありますが、自由度の高い条件で監視を設定できるのが魅力です。

まとめ

DatadogからNew RelicへのAPI監視の移行を通じて、両サービスの設計思想の違いを改めて実感しました。

Datadogは「誰でも迷わず適切な設定ができる」ことを重視した設計で、初めて監視を設定する方にも優しい作りになっています。
一方、New Relicは「どんな要件にも対応できる自由度」を提供する設計で、エンジニアがコードで細かく制御できることを強みとしていると感じました。
Kompira cloudの場合は、すでにNew Relicを活用しており、Terraformでのコード管理も定着していたため、New Relicへの移行がスムーズに進みました。

この記事が、API監視の選定やNew Relicでの監視設定に取り組む方の参考になれば幸いです。