この記事では、New Relic SyntheticのScripted API 機能を使い、TCPポートの監視とRTTの計測を実現する方法を、具体的なスクリプト付きで解説します!
PingモニターだとWeb疎通チェックになるためTCPレベルの監視ができないのですが、Scripted APIを使えば以下の様なTCP監視が実現できます。
- 特定のTCPポートの疎通確認を定期的に実行したい
- サービスのネットワーク遅延を切り分けたいので、TCPのRTT(Round Trip Time)を計測したい
実現方法について
Scripted API を使うと、Node.jsの実行環境で好きなスクリプトを動かせます。今回は、Node.jsの標準モジュールであるnetを使って、TCPソケット通信を監視します。
RTT計測の仕組み
スクリプト内でRTT(Round Trip Time)を計測する仕組みはとてもシンプルです。
- TCP接続を開始する直前にタイムスタンプを記録 (
startTime) - TCP接続が成功した直後にもタイムスタンプを記録 (
endTime) -
endTime - startTimeを計算することで、TCPの3ウェイハンドシェイクにかかった時間、つまりRTTを近似的に計測します。 - 計測した値をカスタム属性としてNew Relicに送信します。
具体的な設定手順と監視スクリプト
1. Syntheticsモニターの作成
- New Relicのメニューから [Synthetic Monitoring] を開きます。
- [+ Create monitor] をクリックし、モニタータイプは [Scripted API] を選択します。
- モニター名(例:
TCP RTT Monitor)や監視ロケーションを設定します。 - [Write script] タブに移動し、以下のスクリプトを貼り付けます。
※監視ロケーションの選択は、監視対象の拠点からネットワーク的に遠い箇所を選択するとRTTの数値が悪化したりTCPタイムアウトのmsが短いとタイムアウトでジョブが失敗するなど起こり得るので、どの拠点を選ぶとき注意してください。
コードについて
監視したいホストとポートを書き換えるだけで、すぐに利用できるようになっています。
/**
* New Relic Synthetic Scripted API
* TCP接続を試み、RTT(Round Trip Time)を計測するスクリプト
*/
const assert = require('assert');
const net = require('net');
// --- 設定項目 ---
// 監視対象のホスト名またはIPアドレス
const HOST = 'one.newrelic.com';
// 監視対象のTCPポート (例: HTTPS: 443)
const PORT = 443;
// TCP接続タイムアウト時間(ミリ秒)
const TIMEOUT = 5000;
// --- 設定項目ここまで ---
console.log(`TCP接続テスト開始: ${HOST}:${PORT}`);
// TCPソケットを作成
const socket = new net.Socket();
socket.setTimeout(TIMEOUT);
// 計測開始時間
const startTime = Date.now();
// 接続処理
socket.connect(PORT, HOST, () => {
// 接続成功
const rtt = Date.now() - startTime;
console.log(`接続成功! RTT: ${rtt} ms`);
// ★重要★ 計測したRTTをカスタム属性としてNew Relicに送信
// 'tcpRtt'という属性名でNRDBに保存され、クエリやダッシュボードで利用できる
$util.insights.set('tcpRtt', rtt);
$util.insights.set('targetHost', HOST);
$util.insights.set('targetPort', PORT);
// アサーション: RTTがタイムアウト未満であることを確認(正常終了の条件)
assert.ok(rtt < TIMEOUT, `RTT (${rtt} ms) がタイムアウト値 (${TIMEOUT} ms) を超えました`);
// ソケットを閉じる
socket.end();
});
// エラーハンドリング
socket.on('error', (err) => {
console.error(`接続エラー: ${err.message}`);
assert.fail(`TCP接続に失敗しました: ${err.message}`);
});
// タイムアウトハンドリング
socket.on('timeout', () => {
console.error('接続がタイムアウトしました。');
socket.destroy();
assert.fail(`TCP接続がタイムアウトしました (${TIMEOUT} ms)`);
});
スクリプト内の $util.insights.set('tcpRtt', rtt); が重要な部分です。
$util.insights.setを使うとSyntheticの監視結果にカスタムで属性情報を追加することができます。
今回はRTTの数値をカスタム属性としてSyntheticの監視結果に付与することで、計測した結果をNRQLで取り出して、ダッシュボードで可視化したりアラート条件として扱うことができるようになります。
$util.insights.setの使い方については以下ドキュメントが参考になります。
結果の確認とダッシュボードでの可視化
スクリプトを保存して監視を開始すると、SyntheticCheckイベントにcustom.tcpRttというカスタム属性が追加されます。これをNRQLで取り出すことができます。
SELECT average(custom.tcpRtt) FROM SyntheticCheck WHERE monitorName = 'TCP RTT Monitor'
このように、計測したRTTの平均値をグラフで表示できます。もちろん、このNRQLを元にアラートを設定することも可能です。
その他参考記事リンク
New Relic Syntheticの他モニタリング方法について紹介している記事がありますのでご案内です。
まとめ
New Relic SyntheticのScripted API の柔軟性を活用することで、TCPレベルの監視とRTT計測を簡単に実現できます。ぜひご活用ください。
New Relicでは、新しい機能やその活用方法について、QiitaやXで発信しています!
無料でアカウント作成も可能なのでぜひお試しください!
New Relic株式会社のX(旧Twitter) や Qiita Organizationでは、
新機能を含む活用方法を公開していますので、ぜひフォローをお願いします。
無料のアカウントで試してみよう!
New Relic フリープランで始めるオブザーバビリティ!
