Application Insights を使用して Node.js サービスとアプリを監視する

Application Insights は、デプロイ後のコンポーネントを監視して、パフォーマンスや他の問題を検出します。 Application Insights は、自社のデータセンターや、Azure VM、Web アプリ、さらには他のパブリック クラウドにホストされた Node.js サービスに対しても使用できます。

監視データを受信、保存、探索するためには、ご使用のコードに SDK を追加します。 次に、Azure で対応する Application Insights リソースを設定します。 そのリソースに対して SDK からデータが送信され、詳細な分析と探索が行えるようになります。

Node.js クライアント ライブラリでは、着信と発信の HTTP 要求、例外、システムのいくつかのメトリックを自動的に監視できます。 さらに、バージョン 0.20 以降のクライアント ライブラリでは、MongoDB、MySQL、Redis など、一般的なサードパーティ製パッケージを監視することもできます。

受信 HTTP 要求に関連するすべてのイベントは、トラブルシューティングを迅速に行えるように関連付けられます。

TelemetryClient API を使用して手動でインストルメント化すれば、ご使用のアプリとシステムのその他の側面も監視できます。 TelemetryClient API については、この記事の後半でさらに詳しく説明します。

Note

以下のドキュメントは、Application Insights クラシック API に関するものです。 Application Insights の長期的な計画は、OpenTelemetry を使用してデータを収集することです。 詳しくは、「.NET、Node.js、Python、Java アプリケーション用の Azure Monitor OpenTelemetry を有効にする」をご覧ください。

作業の開始

アプリまたはサービスの監視を設定するには、次の作業を完了します。

前提条件

開始する前に、Azure サブスクリプションがあることを確認するか、無償で新しい Azure サブスクリプションを取得してください。 組織に Azure サブスクリプションが既にある場合は、管理者にこちらの手順に従ってもらうことで、追加してもらうことができます。

Application Insights リソースを設定する

  1. Azure portal にサインインします。
  2. Application Insights のリソースを作成します。

注意

インストルメンテーション キーのインジェストのサポートは、2025 年 3 月 31 日に終了します。 インストルメンテーション キーのインジェストは引き続き機能しますが、この機能の更新プログラムやサポートは提供されなくなります。 接続文字列に移行することで、新機能をご利用いただけます。

Node.js クライアント ライブラリを設定する

アプリでデータを収集できるように、アプリに SDK を追加します。

  1. 新しいリソースからリソースの接続文字列をコピーします。 Application Insights は、この接続文字列を使って、対象の Azure リソースにデータをマッピングします。 SDK で接続文字列を使うには、その接続文字列を環境変数またはコードの中で指定する必要があります。

    Screenshot that shows the Application Insights overview and connection string.

  2. package.json を使って、Node.js クライアント ライブラリをアプリの依存関係に追加します。 アプリのルート フォルダーから次を実行します。

    npm install applicationinsights --save
    

    Note

    TypeScript を使用している場合は、個別の "typings" パッケージをインストールしないでください。 この NPM パッケージには、組み込みの型指定が含まれています。

  3. コードでライブラリを明示的に読み込みます。 インストルメンテーションは、SDK によって他の多数のライブラリに挿入されます。そのため、ライブラリはできる限り早く (require ステートメントよりも前に) 読み込むようにしてください。

    let appInsights = require('applicationinsights');
    
  4. また、setup() または new appInsights.TelemetryClient() に手動で渡すのではなく、環境変数 APPLICATIONINSIGHTS_CONNECTION_STRING を使って接続文字列を指定することもできます。 この方法では、コミットされたソース コードに接続文字列を含めず、異なる環境に合わせて異なる接続文字列を指定できます。 手動で構成するには、appInsights.setup('[your connection string]'); を呼び出します。

    その他の構成オプションについては、以降のセクションを参照してください。

    appInsights.defaultClient.config.disableAppInsights = true を設定すると、テレメトリを送信することなく SDK を試すことができます。

  5. appInsights.start(); を呼び出して、データの収集と送信を自動的に開始します。

Note

Application Insights インストルメンテーションの使用時に、診断データが収集され、Microsoft に送信されます。 このデータは、Application Insights の実行と改善に役立ちます。 重要でないデータ収集を無効にするオプションがあります。 詳細については、こちらを参照してください

アプリを監視する

SDK は、Node.js ランタイムおよび一般的なサード パーティ モジュールに関するテレメトリを自動的に収集します。 アプリケーションを使用して、そうしたデータを生成します。

次に、Azure portal で、先ほど作成した Application Insights リソースに移動します。 [概要のタイムライン] に、いくつかの最初のデータ ポイントが現れます。 さらに詳しいデータを表示するには、グラフ内の別のコンポーネントを選択してください。

対象のアプリに関して検出されたトポロジを表示するには、[アプリケーション マップ] を使用できます。

データなし

SDK では送信するデータをバッチ処理するため、ポータルに項目が表示されるまでに遅延が発生する場合があります。 リソースのデータが表示されない場合は、次の対処方法を試してください。

  • 引き続きアプリケーションを使用します。 操作を実行して、テレメトリをさらに生成します。
  • ポータルのリソース ビューで [最新の情報に更新] を選びます。 グラフは定期的に自動で更新されますが、手動で更新を強制することで最新の情報が直ちに表示されます。
  • 必要な送信ポートが開いていることを確認します。
  • [検索] を使用して特定のイベントを探します。
  • よく寄せられる質問を確認します。

基本的な使用方法

すぐに利用できる HTTP 要求のコレクション、一般的なサードパーティ ライブラリ イベント、未処理の例外、およびシステム メトリックの場合は、次のとおりです。


let appInsights = require("applicationinsights");
appInsights.setup("[your connection string]").start();

Note

接続文字列が環境変数 APPLICATIONINSIGHTS_CONNECTION_STRING で設定されている場合は、引数なしで .setup() を呼び出すことができます。 この方法により、さまざまな環境で異なる接続文字列を簡単に使用できるようになります。

他のパッケージを読み込む前に、スクリプトのできるだけ早い段階で Application Insights ライブラリ require("applicationinsights") を読み込みます。 このステップは、Application Insights ライブラリが追跡のために後でパッケージを準備できるようにするために必要です。 同様の準備を行った他のライブラリとの競合が発生した場合は、後で Application Insights ライブラリを読み込んでみてください。

JavaScript がコールバックを処理する方法が原因で、外部依存関係および後のコールバックで要求を追跡するために追加の作業が必要になります。 既定では、この追加の追跡が有効になっています。 「SDK の構成」セクションの説明に従って setAutoDependencyCorrelation(false) を呼び出して無効にします。

0.22 より前のバージョンからの移行

バージョン 0.22 より前のリリースと、それ以降のリリースの間には、破壊的変更があります。 これらの変更は、他の Application Insights SDK との一貫性を保ち、将来の拡張を可能にするように設計されています。

一般に、次の操作を行うことで移行できます。

  • appInsights.client への参照を appInsights.defaultClient に置き換えます。
  • appInsights.getClient() への参照を new appInsights.TelemetryClient() に置き換えます。
  • client.track* メソッドのすべての引数を、名前付きプロパティを引数として含む 1 つのオブジェクトに置き換えます。 それぞれの型のテレメトリに対して除外されるオブジェクトについては、IDE の組み込みの型ヒントまたは TelemetryTypes を参照してください。

appInsights.setup() にチェーンせずに SDK 構成関数にアクセスすると、これらの関数を appInsights.Configurations で見つけることができるようになります。 たとえば appInsights.Configuration.setAutoCollectDependencies(true) です。 次のセクションで、既定の構成に対する変更を確認してください。

SDK の構成

appInsights オブジェクトには、多くの構成メソッドがあります。 これらを既定値と共に、次のスニペットに一覧表示します。

let appInsights = require("applicationinsights");
appInsights.setup("<connection_string>")
    .setAutoDependencyCorrelation(true)
    .setAutoCollectRequests(true)
    .setAutoCollectPerformance(true, true)
    .setAutoCollectExceptions(true)
    .setAutoCollectDependencies(true)
    .setAutoCollectConsole(true)
    .setUseDiskRetryCaching(true)
    .setSendLiveMetrics(false)
    .setDistributedTracingMode(appInsights.DistributedTracingModes.AI)
    .start();

サービスのイベントを完全に関連付けるには、必ず .setAutoDependencyCorrelation(true) を設定します。 このオプションを設定することにより、Node.js の非同期コールバック全体のコンテキストを SDK で追跡できます。

IDE の組み込みの型ヒントで説明を確認するか、applicationinsights.ts で詳細な情報と省略可能なセカンダリ引数を確認してください。

注意

既定では、setAutoCollectConsoleconsole.log およびその他のコンソール メソッドの呼び出しを "除外" するように構成されています。 サポートされているサードパーティのロガー (たとえば、winston や bunyan) の呼び出しのみが収集されます。 setAutoCollectConsole(true, true) を使用することで、この動作を変更して console メソッドの呼び出しを含めることができます。

サンプリング

既定では、SDK は収集されたすべてのデータを Application Insights サービスに送信します。 サンプリングを有効にしてデータの量を減らす場合は、クライアントの config オブジェクトで samplingPercentage フィールドを設定します。 samplingPercentage を 100 (既定値) に設定すると、すべてのデータが送信され、0 にした場合は何も送信されません。

自動関連付けを使っている場合は、1 つの要求に関連付けられているすべてのデータが 1 つの単位として、追加または除外されます。

次のようなコードを追加して、サンプリングを有効にします。

const appInsights = require("applicationinsights");
appInsights.setup("<connection_string>");
appInsights.defaultClient.config.samplingPercentage = 33; // 33% of all telemetry will be sent to Application Insights
appInsights.start();

複数コンポーネント アプリケーションの複数のロール

一部のシナリオでは、アプリケーションは、同じ接続文字列ですべてをインストルメント化する複数のコンポーネントで構成される場合があります。 これらのコンポーネントは、個別の接続文字列を使用しているかのように、ポータルで個別の単位として引き続き表示される必要があります。 例として、アプリケーション マップ上の個別のノードがあります。 あるコンポーネントのテレメトリと Application Insights リソースにデータを送信する他のコンポーネントを区別するには、RoleName フィールドを手動で構成する必要があります。

次のコードを使用して RoleName フィールドを設定します。

const appInsights = require("applicationinsights");
appInsights.setup("<connection_string>");
appInsights.defaultClient.context.tags[appInsights.defaultClient.context.keys.cloudRole] = "MyRoleName";
appInsights.start();

ブラウザー SDK ローダー

Note

パブリック プレビューとして利用できます。 Microsoft Azure プレビューの使用条件に関する補足

構成によって、JavaScript (Web) SDK ローダー スクリプトの挿入を使用して、自動 Web インストルメンテーションをノード サーバーに対して有効にすることができます。

let appInsights = require("applicationinsights");
appInsights.setup("<connection_string>")
    .enableWebInstrumentation(true)
    .start();

を使用するか、または環境変数 APPLICATIONINSIGHTS_WEB_INSTRUMENTATION_ENABLED = true を設定します。

Web インストルメンテーションは、次のすべての要件が満たされている場合、ノード サーバーの応答で有効になります。

  • 応答に状態コード 200 が含まれている。
  • 応答メソッドが GET である。
  • サーバーの応答に Content-Type html が含まれている。
  • サーバー応答に <head></head> の両方のタグが含まれている。
  • 応答が圧縮されている場合は、Content-Encoding の種類が 1 つしか存在せず、エンコードの種類は gzipbrdeflate のいずれかである必要がある。
  • 応答に現在およびバックアップの Web インストルメンテーション CDN エンドポイントが含まれていない。 (現在およびバックアップの Web インストルメンテーション CDN エンドポイントはここにあります)

Web インストルメンテーション CDN エンドポイントは、環境変数 APPLICATIONINSIGHTS_WEB_INSTRUMENTATION_SOURCE = "web Instrumentation CDN endpoints" を設定することによって変更できます。 Web インストルメンテーション接続文字列は、環境変数 APPLICATIONINSIGHTS_WEB_INSTRUMENTATION_CONNECTION_STRING = "web Instrumentation connection string" を設定することによって変更できます。

Note

Web インストルメンテーションでは、特に応答サイズが大きいか、または応答が圧縮されている場合、サーバー応答時間が遅くなる可能性があります。 いくつかの中間層が適用される場合は、Web インストルメンテーションが機能しなくなる可能性があり、そのときは元の応答が返されます。

自動サードパーティ インストルメンテーション

非同期呼び出し間でコンテキストを追跡するには、MongoDB や Redis などのサードパーティ製のライブラリでいくつかの変更が必要になります。 既定では、Application Insights は diagnostic-channel-publishers を使用して、これらのライブラリの一部をモンキーパッチにより修正します。 この機能は、APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL 環境変数を設定することによって無効にできます。

Note

この環境変数を設定することで、イベントが適切な操作に正しく関連付けられない可能性があります。

個々のモンキーパッチを無効にするには、APPLICATION_INSIGHTS_NO_PATCH_MODULES 環境変数に、無効にするパッケージをコンマ区切りリストで設定します。 たとえば、console および redis パッケージの修正プログラムの適用を回避するために APPLICATION_INSIGHTS_NO_PATCH_MODULES=console,redis を使用します。

現時点では、bunyanconsolemongodbmongodb-coremysqlrediswinstonpgpg-pool の 9 つのパッケージがインストルメント化されています。 これらのパッケージのどのバージョンにパッチが適用されているかについては、「diagnostic-channel-publishers の README」を参照してください。

bunyanwinstonconsole のパッチにより、setAutoCollectConsole が有効になっているかどうかに基づいて Application Insights トレース イベントが生成されます。 残りにより、setAutoCollectDependencies が有効になっているかどうかに基づいて Application Insights 依存関係イベントが生成されます。

Live metrics

アプリから Azure へのライブ メトリックの送信を有効にするには、setSendLiveMetrics(true) を使用します。 現在、ポータルでのライブ メトリックのフィルター処理はサポートされていません。

拡張メトリック

Note

拡張ネイティブ メトリックを送信する機能が、バージョン 1.4.0 で追加されました。

アプリから Azure に拡張ネイティブ メトリックを送信できるようにするには、個別のネイティブ メトリック パッケージをインストールします。 SDK はインストールされると自動的に読み込まれ、Node.js ネイティブ メトリックの収集を開始します。

npm install applicationinsights-native-metrics

現在、ネイティブ メトリック パッケージでは、ガベージ コレクションの CPU 時間、イベント ループのティック、およびヒープの使用率の自動収集が実行されます。

  • ガベージ コレクション:各種類のガベージコレクションに費やされた CPU 時間と、それぞれの種類の発生回数。
  • イベント ループ:発生したティックの数と、合計で費やされた CPU 時間。
  • ヒープと非ヒープ: ヒープまたは非ヒープの、アプリのメモリ使用量。

分散トレース モード

既定では、SDK は、Application Insights SDK でインストルメント化された他のアプリケーションやサービスによって認識されるヘッダーを送信します。 既存の AI ヘッダーに加えて、W3C トレース コンテキスト ヘッダーの送受信を有効にすることができます。 この方法では、既存のレガシ サービスとの相関関係を損ないません。 W3C ヘッダーを有効にすると、アプリは Application Insights でインストルメント化されていない他のサービスと関連付けることが可能になりますが、この W3C 標準が採用されます。

const appInsights = require("applicationinsights");
appInsights
  .setup("<your connection string>")
  .setDistributedTracingMode(appInsights.DistributedTracingModes.AI_AND_W3C)
  .start()

TelemetryClient API

TelemetryClient API の詳細な説明については、「カスタムのイベントとメトリックのための Application Insights API」を参照してください。

Node.js 用の Application Insights クライアント ライブラリを使って、任意の要求、イベント、メトリック、または例外を追跡できます。 次のコード サンプルで、使用できるいくつかの API を紹介します。

let appInsights = require("applicationinsights");
appInsights.setup().start(); // assuming connection string in env var. start() can be omitted to disable any non-custom data
let client = appInsights.defaultClient;
client.trackEvent({name: "my custom event", properties: {customProperty: "custom property value"}});
client.trackException({exception: new Error("handled exceptions can be logged with this method")});
client.trackMetric({name: "custom metric", value: 3});
client.trackTrace({message: "trace message"});
client.trackDependency({target:"http://dbname", name:"select customers proc", data:"SELECT * FROM Customers", duration:231, resultCode:0, success: true, dependencyTypeName: "ZSQL"});
client.trackRequest({name:"GET /customers", url:"http://myserver/customers", duration:309, resultCode:200, success:true});

let http = require("http");
http.createServer( (req, res) => {
  client.trackNodeHttpRequest({request: req, response: res}); // Place at the beginning of your request handler
});

依存関係を追跡する

依存関係を追跡するには、次のコードを使用します。

let appInsights = require("applicationinsights");
let client = new appInsights.TelemetryClient();

var success = false;
let startTime = Date.now();
// execute dependency call here....
let duration = Date.now() - startTime;
success = true;

client.trackDependency({target:"http://dbname", name:"select customers proc", data:"SELECT * FROM Customers", duration:duration, resultCode:0, success: true, dependencyTypeName: "ZSQL"});;

trackMetric を使用して、イベント ループのスケジュール設定にかかる時間を測定するユーティリティの例を次に示します。

function startMeasuringEventLoop() {
  var startTime = process.hrtime();
  var sampleSum = 0;
  var sampleCount = 0;

  // Measure event loop scheduling delay
  setInterval(() => {
    var elapsed = process.hrtime(startTime);
    startTime = process.hrtime();
    sampleSum += elapsed[0] * 1e9 + elapsed[1];
    sampleCount++;
  }, 0);

  // Report custom metric every second
  setInterval(() => {
    var samples = sampleSum;
    var count = sampleCount;
    sampleSum = 0;
    sampleCount = 0;

    if (count > 0) {
      var avgNs = samples / count;
      var avgMs = Math.round(avgNs / 1e6);
      client.trackMetric({name: "Event Loop Delay", value: avgMs});
    }
  }, 1000);
}

すべてのイベントにカスタム プロパティを追加する

すべてのイベントにカスタム プロパティを追加するには、次のコードを使用します。

appInsights.defaultClient.commonProperties = {
  environment: process.env.SOME_ENV_VARIABLE
};

HTTP GET 要求を追跡する

HTTP GET 要求を手動で追跡するには、次のコードを使用します。

Note

既定では、すべての要求が追跡されます。 自動収集を無効にするには、start() を呼び出す前に .setAutoCollectRequests(false) を呼び出します。

appInsights.defaultClient.trackRequest({name:"GET /customers", url:"http://myserver/customers", duration:309, resultCode:200, success:true});

または、trackNodeHttpRequest メソッドを使用して要求を追跡することもできます。

var server = http.createServer((req, res) => {
  if ( req.method === "GET" ) {
      appInsights.defaultClient.trackNodeHttpRequest({request:req, response:res});
  }
  // other work here....
  res.end();
});

サーバーの起動時間を追跡する

サーバーの起動時間を追跡するには、次のコードを使用します。

let start = Date.now();
server.on("listening", () => {
  let duration = Date.now() - start;
  appInsights.defaultClient.trackMetric({name: "server startup time", value: duration});
});

フラッシュ

既定では、テレメトリは 15 秒間バッファリングされた後、インジェスト サーバーへ送信されます。 存続期間の短いアプリケーション (CLI ツールなど) の場合は、アプリケーションの終了時に、appInsights.defaultClient.flush() を使ってバッファリングされたテレメトリを手動でフラッシュすることが必要になる場合があります。

SDK はアプリケーションがクラッシュしたことを検知すると、appInsights.defaultClient.flush({ isAppCrashing: true }) を使ってフラッシュを呼び出します。 フラッシュ オプション (isAppCrashing) によって、アプリケーションが異常な状態であり、テレメトリ送信に適していないと見なされます。 代わりに、SDK はバッファリングしたすべてのテレメトリを永続ストレージに保存して、アプリケーションを終了させます。 アプリケーションは、再起動すると、永続ストレージに保存されたテレメトリを送信しようと試みます。

テレメトリ プロセッサを使用したデータの前処理

"テレメトリ プロセッサ" を使って、収集されたデータを保持のために送信する前に、データ処理とフィルター処理を行うことができます。 テレメトリ プロセッサは、テレメトリ項目がクラウドに送信される前に、追加された順序で、1 つずつ呼び出されます。

public addTelemetryProcessor(telemetryProcessor: (envelope: Contracts.Envelope, context: { http.RequestOptions, http.ClientRequest, http.ClientResponse, correlationContext }) => boolean)

テレメトリ プロセッサが false を返した場合、そのテレメトリ項目は送信されません。

すべてのテレメトリ プロセッサは、検査と変更のために、テレメトリ データとそのエンベロープを受け取ります。 また、コンテキスト オブジェクトも受け取ります。 このオブジェクトの内容は、手動で追跡されたテレメトリの追跡メソッド呼び出し時に、contextObjects パラメーターによって定義されます。 自動収集されたテレメトリについては、このオブジェクトには、appInsights.getCorrelationContext() によって提供される、使用可能な要求情報と永続的な要求コンテンツが格納されます (依存関係の自動関連付けが有効になっている場合)。

テレメトリ プロセッサの TypeScript の種類は次のとおりです。

telemetryProcessor: (envelope: ContractsModule.Contracts.Envelope, context: { http.RequestOptions, http.ClientRequest, http.ClientResponse, correlationContext }) => boolean;

たとえば、スタック トレースのデータを例外から削除するプロセッサは、次のように記述、および追加できます。

function removeStackTraces ( envelope, context ) {
  if (envelope.data.baseType === "Microsoft.ApplicationInsights.ExceptionData") {
    var data = envelope.data.baseData;
    if (data.exceptions && data.exceptions.length > 0) {
      for (var i = 0; i < data.exceptions.length; i++) {
        var exception = data.exceptions[i];
        exception.parsedStack = null;
        exception.hasFullStack = false;
      }
    }
  }
  return true;
}

appInsights.defaultClient.addTelemetryProcessor(removeStackTraces);

複数の接続文字列を使用する

複数の Application Insights リソースを作成し、それぞれの接続文字列を使って異なるデータを送信することができます。

次に例を示します。

let appInsights = require("applicationinsights");

// configure auto-collection under one connection string
appInsights.setup("Connection String A").start();

// track some events manually under another connection string
let otherClient = new appInsights.TelemetryClient("Connection String B");
otherClient.trackEvent({name: "my custom event"});

高度な構成オプション

クライアント オブジェクトには、高度なシナリオ用の多くのオプション設定を持つ config プロパティが含まれています。 これらを設定するには、次を使用します。

client.config.PROPERTYNAME = VALUE;

これらのプロパティはクライアント固有であるため、new appInsights.TelemetryClient() で作成されたクライアントとは別に appInsights.defaultClient を構成することができます。

プロパティ 説明
connectionString Application Insights リソースの識別子。
endpointUrl テレメトリ ペイロードを送信するインジェスト エンドポイント。
quickPulseHost ライブ メトリック テレメトリの送信先である Live Metrics Stream ホスト。
proxyHttpUrl SDK HTTP トラフィック用のプロキシ サーバー。 (省略可能。既定値は環境変数 http_proxy からプルされます)。
proxyHttpsUrl SDK HTTPS トラフィック用のプロキシ サーバー。 (省略可能。既定値は環境変数 https_proxy からプルされます)。
httpAgent SDK HTTP トラフィックに使用する http.Agent。 (省略可能、既定値は未定義)。
httpsAgent SDK HTTPS トラフィックに使用する https.Agent。 (省略可能、既定値は未定義)。
maxBatchSize インジェスト エンドポイントへのペイロードに含めるテレメトリ項目の最大数。 (既定 250)。
maxBatchIntervalMs ペイロードが maxBatchSize になるまでの最大待機時間。 (既定 15000)。
disableAppInsights テレメトリの送信が無効になっているかどうかを示すフラグ。 (既定 false)。
samplingPercentage 送信すべき追跡されたテレメトリ項目の割合。 (既定 100)。
correlationIdRetryIntervalMs コンポーネント間の関連付けのために ID 取得を再試行するまでの待機時間。 (既定 30000)。
correlationHeaderExcludedDomains コンポーネント間の関連付けヘッダーの挿入から除外するドメインの一覧。 (既定。Config.ts を参照してください)

トラブルシューティング

"データなし" のシナリオやログのカスタマイズなどのトラブルシューティング情報については、「Node.js アプリとサービスの Application Insights の監視のトラブルシューティング」を参照してください。

次のステップ