applicationinsights-web-ts について
ブラウザーアプリと React Native に Application Insights のリアルユーザーモニタリングを導入する TypeScript スキルです。テレメトリー、分散トレース、フレームワーク用プラグインに加え、バックエンドのスパンと関連付ける GenAI トレースを扱います。
主な機能
- 01ページビューと依存関係を収集
- 02例外、イベント、メトリクスを記録
- 03SPA のルートとクリックを計測
- 04フロントエンドとバックエンドのトレースを関連付け
- 05OTel 規約に沿った GenAI トレース
- 06プライバシーとサンプリングを設定
活用シーン
- 01ブラウザーアプリの利用状況とエラーを監視
- 02フロントエンドからバックエンドまでリクエストを追跡
- 03GenAI エージェントとツールの動作を計測
- 04React または Angular アプリにテレメトリーを追加
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ microsoft/ skills --skill applicationinsights-web-tsインストール後、Claude Code で/applicationinsights-web-tsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/agent-traces.mdconfiguration.mdframework-extensions.md詳細
TypeScript 向け Application Insights JavaScript SDK(Web)
@microsoft/applicationinsights-web を使用して、ブラウザーアプリのリアルユーザー監視(RUM)を行います。ページビュー、AJAX/fetch の依存関係、未処理の例外を自動収集し、Click Analytics プラグインを使用するとクリックも収集します。カスタムイベントやメトリックに加え、OpenTelemetry GenAI のセマンティック規約に準拠し、W3C Trace Context を介してバックエンドのスパンと関連付ける GenAI エージェントのトレース にも対応しています。
azure-monitor-opentelemetry-tsとは異なります。こちらは Node.js サーバーアプリ向けです。このスキルは ブラウザー/Web コード(および React Native)向けです。
実装前
最新の API パターンを microsoft-docs MCP で検索します。
- クエリ:"Application Insights JavaScript SDK setup"
- クエリ:"Application Insights JavaScript SDK configuration"
- クエリ:"Application Insights JavaScript framework extensions React Angular"
- パッケージのバージョンを確認します:
npm view @microsoft/applicationinsights-web version
パッケージ
| パッケージ | 用途 |
|---|---|
@microsoft/applicationinsights-web | コア RUM SDK(ページビュー、AJAX、例外)。 |
@microsoft/applicationinsights-clickanalytics-js | クリックのテレメトリを自動収集します。 |
@microsoft/applicationinsights-react-js | React プラグイン(ルーターの計装、フック、HOC、ErrorBoundary)。 |
@microsoft/applicationinsights-react-native | React Native プラグイン(ネイティブのクラッシュ、セッション)。 |
@microsoft/applicationinsights-angularplugin-js | Angular プラグイン(ルーターイベント、ErrorHandler)。 |
@microsoft/applicationinsights-debugplugin-js | 開発専用のテレメトリインスペクター。 |
@microsoft/applicationinsights-perfmarkmeasure-js | User Timing(performance.mark/measure)との統合。 |
インストール
npm i --save @microsoft/applicationinsights-web
# Optional plugins (install only what you use):
npm i --save @microsoft/applicationinsights-clickanalytics-js
npm i --save @microsoft/applicationinsights-react-js @microsoft/applicationinsights-react-native @microsoft/applicationinsights-angularplugin-js
型定義はパッケージに含まれているため、別途 @types/... をインストールする必要はありません。
接続文字列
ブラウザー SDK では、初期化時に接続文字列が必要です。接続文字列はプレーンテキストでクライアントに配布されます。ブラウザーのテレメトリでは Microsoft Entra ID 認証はサポートされていません。バックエンドのテレメトリと分離する必要がある場合は、ブラウザーの RUM 用にローカル認証を有効にした別の App Insights リソースを使用してください。
# Vite / CRA / Next.js — expose to client via the public env prefix
VITE_APPINSIGHTS_CONNECTION_STRING="InstrumentationKey=...;IngestionEndpoint=https://...;LiveEndpoint=https://..."
NEXT_PUBLIC_APPINSIGHTS_CONNECTION_STRING="InstrumentationKey=..."
クイックスタート(npm)
import { ApplicationInsights } from "@microsoft/applicationinsights-web";
export const appInsights = new ApplicationInsights({
config: {
connectionString: import.meta.env.VITE_APPINSIGHTS_CONNECTION_STRING,
enableAutoRouteTracking: true, // SPA route changes -> page views
enableCorsCorrelation: true, // propagate Request-Id / traceparent to cross-origin AJAX
enableRequestHeaderTracking: true,
enableResponseHeaderTracking: true,
distributedTracingMode: 2, // DistributedTracingModes.AI_AND_W3C — emit traceparent for backend correlation
autoTrackPageVisitTime: true,
disableFetchTracking: false, // fetch() is auto-instrumented by default
excludeRequestFromAutoTrackingPatterns: [/livemetrics\.azure\.com/i]
}
});
appInsights.loadAppInsights();
appInsights.trackPageView();
loadAppInsights() は、追跡対象にしたいユーザー操作より前に、できるだけ早く一度だけ呼び出します。次に、初回読み込みのために trackPageView() を呼び出します。enableAutoRouteTracking が有効な場合、その後のルート変更は自動的に追跡されます。
クイックスタート(SDK ローダースクリプト)
SDK を自動更新し、ビルドパイプラインを使わずに済ませたい場合におすすめです。これを <head> 内の 最初の <script> として貼り付けます。
<script type="text/javascript" src="https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js" crossorigin="anonymous"></script>
<script type="text/javascript">
var appInsights = window.appInsights || function (cfg) {
/* See: https://learn.microsoft.com/azure/azure-monitor/app/javascript-sdk
Use the latest snippet from the Microsoft Learn page above — it includes
backup-CDN failover (cr), SDK-load-failure reporting, and the queue shim
so calls before SDK ready are not lost. */
}({ src: "https://js.monitor.azure.com/scripts/b/ai.3.gbl.min.js",
crossOrigin: "anonymous",
cfg: { connectionString: "YOUR_CONNECTION_STRING" } });
</script>
ローダーのみの API(SDK の読み込みが完了するまでキューに登録されます):trackEvent、trackPageView、trackException、trackTrace、trackDependencyData、trackMetric、trackPageViewPerformance、startTrackPage、stopTrackPage、startTrackEvent、stopTrackEvent、addTelemetryInitializer、setAuthenticatedUserContext、clearAuthenticatedUserContext、flush。
コアの追跡 API
// Page views (SPAs that disable enableAutoRouteTracking)
appInsights.trackPageView({ name: "Checkout", uri: "/checkout", properties: { cartSize: 3 } });
// Custom events (user actions, business events)
appInsights.trackEvent({ name: "PurchaseCompleted" }, { orderId: "ord_123", amountUsd: 49.95 });
// Exceptions (caught errors)
try {
await pay(order);
} catch (err) {
appInsights.trackException({ exception: err as Error, severityLevel: 3, properties: { orderId: order.id } });
}
// Traces (logs, severity 0=Verbose, 1=Info, 2=Warning, 3=Error, 4=Critical)
appInsights.trackTrace({ message: "Cart hydrated from local storage", severityLevel: 1 });
// Custom metrics (numeric)
appInsights.trackMetric({ name: "checkout.duration_ms", average: 1234 });
// Dependencies (manually-tracked outbound calls — fetch/XHR are auto-tracked)
appInsights.trackDependencyData({
id: crypto.randomUUID(),
name: "GET /api/orders",
duration: 87, success: true, responseCode: 200,
data: "https://api.example.com/api/orders", target: "api.example.com", type: "Fetch"
});
// User identity (set ONCE per authenticated session — values are PII; do not pass emails)
appInsights.setAuthenticatedUserContext("user-id-123", "tenant-456", /*storeInCookie*/ true);
appInsights.clearAuthenticatedUserContext(); // on logout
// Force send before unload
appInsights.flush();
テレメトリ初期化子(拡充とフィルタリング)
送信前に、すべてのエンベロープに対して実行されます。破棄するには false を返します。
import type { ITelemetryItem } from "@microsoft/applicationinsights-web";
appInsights.addTelemetryInitializer((item: ITelemetryItem) => {
item.tags ??= {};
item.tags["ai.cloud.role"] = "web-shop";
item.tags["ai.cloud.roleInstance"] = window.location.hostname;
item.data ??= {};
item.data["app.version"] = import.meta.env.VITE_APP_VERSION;
item.data["app.build"] = import.meta.env.VITE_BUILD_SHA;
// Drop noisy health-check page views
if (item.baseType === "PageviewData" && item.baseData?.uri?.endsWith("/healthz")) return false;
// Scrub query-string secrets
if (item.baseData?.uri) {
item.baseData.uri = item.baseData.uri.replace(/([?&](token|sig|key)=)[^&]+/gi, "$1REDACTED");
}
});
Click Analytics
import { ClickAnalyticsPlugin } from "@microsoft/applicationinsights-clickanalytics-js";
const clickPlugin = new ClickAnalyticsPlugin();
const appInsights = new ApplicationInsights({
config: {
connectionString: import.meta.env.VITE_APPINSIGHTS_CONNECTION_STRING,
extensions: [clickPlugin],
extensionConfig: {
[clickPlugin.identifier]: {
autoCapture: true,
dataTags: { useDefaultContentNameOrId: true, customDataPrefix: "data-ai-" },
urlCollectHash: false,
behaviorValidator: (b: string) => /^[a-z0-9_]+$/.test(b) ? b : ""
}
}
}
});
appInsights.loadAppInsights();
要素に data-ai-* 属性を指定します。クリックは、親コンテンツのメタデータを含むカスタムイベントとして出力されます。
SPA のルート追跡
- 組み込み:
enableAutoRouteTracking: trueを設定します。history.pushState/replaceStateとpopstateをフックします。 - React Router:
@microsoft/applicationinsights-react-jsのwithAITrackingHOC を使用します(references/framework-extensions.md を参照)。 - 手動: ルート変更時に、ルーターの
useEffect内でappInsights.trackPageView({ name, uri })を呼び出します。二重カウントを避けるには、enableAutoRouteTrackingを無効にします。
分散トレーシング(バックエンドとの相関付け)
distributedTracingMode: 2(DistributedTracingModes.AI_AND_W3C)を設定します。SDK は送信する fetch/XHR に traceparent(およびレガシーの Request-Id)を追加します。OpenTelemetry(例:@azure/monitor-opentelemetry)でインストルメント化されたバックエンドは、ブラウザーの operation_Id に自動的にリンクします。
クロスオリジン呼び出しの場合は、enableCorsCorrelation: true も設定し、呼び出し元のオリジンを API の CORS 公開ヘッダーに追加します。
GenAI エージェントのトレース(OTel セマンティック規約)
ブラウザーが AI エージェントを呼び出す場合(関数呼び出し、ツール使用、クライアントから直接行うモデル呼び出し)、属性が OpenTelemetry の GenAI セマンティック規約に従う App Insights の Dependency テレメトリを送信すると、App Insights/Log Analytics でバックエンドのエージェントスパンと併せてクエリできます。
バックエンドのインストルメンテーションが同じスキーマバージョンを使用するよう、最初にオプトイン環境変数を設定します。
OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental
必須属性キー(OTel の名称をそのまま使用)
| スパン/操作 | 必須属性 |
|---|---|
invoke_agent {agent.name} | gen_ai.operation.name=invoke_agent、gen_ai.provider.name、gen_ai.agent.name、gen_ai.agent.id(判明している場合) |
create_agent {agent.name} | gen_ai.operation.name=create_agent、gen_ai.provider.name、gen_ai.agent.name、gen_ai.request.model |
chat {model} | gen_ai.operation.name=chat、gen_ai.provider.name、gen_ai.request.model、gen_ai.response.model、gen_ai.usage.input_tokens、gen_ai.usage.output_tokens |
execute_tool {tool.name} | gen_ai.operation.name=execute_tool、gen_ai.tool.name、gen_ai.tool.type(function | extension | datastore)、gen_ai.tool.call.id |
gen_ai.provider.name の既知の値:openai、azure.ai.openai、azure.ai.inference、anthropic、aws.bedrock、gcp.gemini、gcp.vertex_ai、cohere、mistral_ai、groq、deepseek、perplexity、x_ai、ibm.watsonx.ai。
機密コンテンツのオプトイン。
gen_ai.system_instructions、gen_ai.input.messages、gen_ai.output.messages、gen_ai.tool.call.arguments、gen_ai.tool.call.resultは、デフォルトで オプトインです。実行時フラグで制御し、承認されたデータ取り扱い手順がない限り、本番環境では使用しないでください。
パターン:invoke_agent とネストされたツール/モデルスパン
import { ApplicationInsights, SeverityLevel } from "@microsoft/applicationinsights-web";
type GenAiAttrs = Record<string, string | number | boolean | undefined>;
function startGenAiSpan(name: string, attrs: GenAiAttrs) {
const id = crypto.randomUUID();
const start = performance.now();
const baseProps: GenAiAttrs = { "gen_ai.span.id": id, ...attrs };
return {
end(success: boolean, extra: GenAiAttrs = {}, error?: Error) {
const duration = Math.round(performance.now() - start);
const properties = { ...baseProps, ...extra };
appInsights.trackDependencyData({
id, name, duration, success,
responseCode: error ? 500 : 200,
type: "GenAI",
target: String(attrs["gen_ai.provider.name"] ?? "genai"),
properties: properties as Record<string, string>
});
if (error) {
appInsights.trackException({
exception: error,
severityLevel: SeverityLevel.Error,
properties: { ...properties, "error.type": error.name } as Record<string, string>
});
}
}
};
}
// Agent invocation
const agentSpan = startGenAiSpan("invoke_agent ResearchAssistant", {
"gen_ai.operation.name": "invoke_agent",
"gen_ai.provider.name": "azure.ai.openai",
"gen_ai.agent.name": "ResearchAssistant",
"gen_ai.agent.id": "asst_5j66UpCpwteGg4YSxUnt7lPY",
"gen_ai.request.model": "gpt-4o-mini",
"server.address": "myresource.openai.azure.com"
});
try {
// Nested chat completion span
const chat = startGenAiSpan("chat gpt-4o-mini", {
"gen_ai.operation.name": "chat",
"gen_ai.provider.name": "azure.ai.openai",
"gen_ai.request.model": "gpt-4o-mini"
});
const res = await callAzureOpenAi(/* ... */);
chat.end(true, {
"gen_ai.response.model": res.model,
"gen_ai.response.id": res.id,
"gen_ai.response.finish_reasons": JSON.stringify(res.choices.map(c => c.finish_reason)),
"gen_ai.usage.input_tokens": res.usage.prompt_tokens,
"gen_ai.usage.output_tokens": res.usage.completion_tokens,
"gen_ai.output.type": "text"
});
// Nested tool execution span
const tool = startGenAiSpan("execute_tool getWeather", {
"gen_ai.operation.name": "execute_tool",
"gen_ai.tool.name": "getWeather",
"gen_ai.tool.type": "function",
"gen_ai.tool.call.id": "call_abc123"
});
const toolResult = await runGetWeather({ location: "SF" });
tool.end(true);
agentSpan.end(true, {
"gen_ai.usage.input_tokens": res.usage.prompt_tokens,
"gen_ai.usage.output_tokens": res.usage.completion_tokens
});
} catch (err) {
agentSpan.end(false, { "error.type": (err as Error).name }, err as Error);
}
ブラウザーの traceparent は送信する fetch に自動的に付加されるため(distributedTracingMode: 2 の場合)、下流の Azure OpenAI/エージェントバックエンドのスパンは、App Insights で同じ operation_Id の配下に記録されます。
属性の完全なリファレンス、既知の値、コンテンツ収集のガイダンスについては、references/agent-traces.md を参照してください。
KQL:App Insights で GenAI トレースをクエリする
dependencies
| where type == "GenAI"
| extend op = tostring(customDimensions["gen_ai.operation.name"]),
agent = tostring(customDimensions["gen_ai.agent.name"]),
model = tostring(customDimensions["gen_ai.request.model"]),
tin = toint(customDimensions["gen_ai.usage.input_tokens"]),
tout = toint(customDimensions["gen_ai.usage.output_tokens"])
| summarize calls=count(), p95_ms=percentile(duration, 95),
avg_in=avg(tin), avg_out=avg(tout) by op, agent, model, bin(timestamp, 5m)
React(TypeScript)
React、React Native、Angular、Next.js、Vite の詳しいレシピについては、references/framework-extensions.md を参照してください。
import { ApplicationInsights } from "@microsoft/applicationinsights-web";
import { ReactPlugin, withAITracking } from "@microsoft/applicationinsights-react-js";
import { createBrowserHistory } from "history";
const reactPlugin = new ReactPlugin();
const browserHistory = createBrowserHistory();
export const appInsights = new ApplicationInsights({
config: {
connectionString: import.meta.env.VITE_APPINSIGHTS_CONNECTION_STRING,
extensions: [reactPlugin],
extensionConfig: { [reactPlugin.identifier]: { history: browserHistory } }
}
});
appInsights.loadAppInsights();
export const TrackedCheckout = withAITracking(reactPlugin, Checkout, "Checkout");
React Native
import { ApplicationInsights } from "@microsoft/applicationinsights-web";
import { ReactNativePlugin } from "@microsoft/applicationinsights-react-native";
const rnPlugin = new ReactNativePlugin();
const appInsights = new ApplicationInsights({
config: {
connectionString: process.env.EXPO_PUBLIC_APPINSIGHTS_CONNECTION_STRING,
extensions: [rnPlugin],
disableFetchTracking: false
}
});
appInsights.loadAppInsights();
パフォーマンス — Web Vitals
自動収集:PerformanceTiming/PerformanceNavigationTiming によるページ読み込み時間。Core Web Vitals を追加するには:
import { onCLS, onLCP, onINP, type Metric } from "web-vitals";
function send(m: Metric) {
appInsights.trackMetric(
{ name: `web_vitals.${m.name.toLowerCase()}`, average: m.value },
{ rating: m.rating, navigationType: m.navigationType, id: m.id }
);
}
onCLS(send); onLCP(send); onINP(send);
Cookie とプライバシー
new ApplicationInsights({ config: {
connectionString,
isCookieUseDisabled: true, // hard-disable all cookies
cookieCfg: { enabled: true, domain: ".example.com", path: "/", expiry: 365 }
}});
同意状態を動的に反映するには:
appInsights.getCookieMgr().setEnabled(userGaveConsent);
appInsights.config.disableTelemetry = !userGaveConsent;
サンプリング
サーバー側の取り込みサンプリング(推奨)は、App Insights リソースで設定します。SDK 側のサンプリングにより、ネットワーク使用量を削減できます。
new ApplicationInsights({ config: { connectionString, samplingPercentage: 50 } });
テレメトリ初期化子によるタイプ別サンプリング:item.baseType に基づいて return false を返し、破棄します。
オフライン/送信時のフラッシュ
SDK は sendBeacon(デフォルトは onunloadDisableBeacon: false)を使用して、pagehide/unload 時にデータをフラッシュします。SPA では、破壊的な遷移(ログアウト、ハードリロード)の前にも appInsights.flush() を呼び出してください。
よくある落とし穴
- 二重に初期化しないでください。 異なるバンドルでモジュールを再インポートすると、ページビューが重複します。共有モジュールのエクスポートは1つだけ使用してください。
- 最初のユーザー入力より前に初期化してください。 そうしないと、初期のクリックや例外が失われる可能性があります。
- 接続文字列は公開情報です — バックエンドのシークレットには、同じ App Insights リソースを決して再利用しないでください。
enableAutoRouteTrackingと手動のtrackPageViewを併用すると重複します。どちらか一方を選んでください。- CORS の分散トレース を利用するには、API で
Request-Id、Request-Context、traceparent、tracestateのリクエストヘッダーを許可し、Request-Contextレスポンスヘッダーを公開する必要があります。 - GenAI の機密コンテンツ(
gen_ai.input.messagesなど)はオプトインです。明示的なランタイムフラグと承認済みのデータ取り扱いがない限り、決してログに記録しないでください。 - エージェントのトークン使用量は
invoke_agentではなくchatスパンに記録されます — 使用量を把握している場合に限り、集計した使用量を親のエージェントスパンにコピーしてください。 - React StrictMode では開発時にエフェクトが二重に呼び出されます。
loadAppInsights()をモジュールレベルのシングルトンで保護してください。
バンドルサイズ
Web SDK のフル版は、最小化後で約 110 KB(gzip 圧縮後で約 36 KB)です。サイズの制約が厳しい場合は、クリティカルパス外で SDK を非同期に読み込める Loader Script の方法を使用するか、未使用のプラグインをツリーシェイクしてください。
主な型
import {
ApplicationInsights,
SeverityLevel,
DistributedTracingModes,
type IConfiguration,
type IConfig,
type ITelemetryItem,
type ITelemetryPlugin,
type ICustomProperties,
type IPageViewTelemetry,
type IEventTelemetry,
type IExceptionTelemetry,
type ITraceTelemetry,
type IMetricTelemetry,
type IDependencyTelemetry
} from "@microsoft/applicationinsights-web";
ベストプラクティス
- シングルトンインスタンスを1つだけにする — 1つのモジュールからエクスポートしてください。
- 早い段階で初期化する — ルーターを設定する前に、アプリのエントリーポイントで初期化してください。
- テレメトリ初期化子を使用する —
app.version、tenantIdを付加し、PII やクエリー文字列のシークレットを除去してください。 distributedTracingMode: 2を設定する — API が W3C トレースコンテキストのヘッダーを受け入れ、公開することを確認してください。- GenAI では、OTel の
gen_ai.*属性名をそのまま使用してください。ブラウザーとバックエンドのテレメトリ全体で一貫してクエリーできます。 - 機密コンテンツの取得(
gen_ai.input.messages/gen_ai.output.messages)は、ビルド時またはランタイムのオプトインを条件にしてください。 - ログアウト時や機密性の高い画面への移動時にフラッシュする — 送信中のテレメトリが破棄されないようにしてください。
参考資料
- references/agent-traces.md — OTel GenAI のセマンティック規約をまとめた完全版(エージェント/モデル/ツールのスパン、属性、コンテンツ取得)。
- references/framework-extensions.md — React、React Native、Angular、Next.js、Vite のレシピ。
- references/configuration.md —
IConfigurationの完全なリファレンスと調整ガイド。 - Microsoft Learn:https://learn.microsoft.com/azure/azure-monitor/app/javascript-sdk
- ApplicationInsights-JS のソース:https://github.com/microsoft/ApplicationInsights-JS
- OTel GenAI セマンティック規約:https://opentelemetry.io/docs/specs/semconv/gen-ai/