选项
首页首页 Skill 网页开发 applicationinsights-web-ts

applicationinsights-web-ts

microsoft/skills microsoft/skills

利用 Application Insights JavaScript SDK 进行真实用户监控 (RUM),可监控仪表盘浏览器/Web 应用,包括页面浏览量、点击、AJAX/fetch 依赖关系、异常、自定义事件,以及与后端 OpenTelemetry 跟踪相关联的 GenAI 代理跟踪。

...展开全部
8
更新时间 2026-09-11

适用于 TypeScript 的 Application Insights JavaScript SDK(Web)

适用于浏览器应用的真实用户监控 (RUM),支持 @microsoft/applicationinsights-web。自动收集页面浏览、AJAX/fetch 依赖项、未处理的异常,以及(配合点击分析插件)点击数据。支持自定义事件、指标和 GenAI 代理跟踪,这些跟踪遵循 OpenTelemetry GenAI 语义规范,并通过 W3C 跟踪上下文与后端跨度建立关联。

适用于 Node.js 服务器应用的 azure-monitor-opentelemetry-ts 不同。此技能适用于浏览器/Web 代码(以及 React Native)。

实施前

搜索 microsoft-docs 在MCP中搜索当前的API模式:

  • 查询:“Application Insights JavaScript SDK 设置”
  • 查询:“Application Insights JavaScript SDK 配置”
  • 查询:“Application Insights JavaScript 框架扩展 React Angular”
  • 验证包版本: npm view @microsoft/applicationinsights-web version

用途
@microsoft/applicationinsights-web 核心 RUM SDK(页面浏览量、AJAX、异常)。
@microsoft/applicationinsights-clickanalytics-js 自动收集点击遥测数据。
@microsoft/applicationinsights-react-js React 插件(路由监控、Hooks、高阶组件、ErrorBoundary)。
@microsoft/applicationinsights-react-native React Native 插件(原生崩溃、会话)。
@microsoft/applicationinsights-angularplugin-js Angular 插件(路由事件、ErrorHandler)。
@microsoft/applicationinsights-debugplugin-js 仅限开发人员使用的遥测检查器。
@microsoft/applicationinsights-perfmarkmeasure-js 用户计时(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

该包自带 Typings — 无需单独 @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() exactly once,且应尽早调用(在您希望追踪的用户交互发生之前)。随后 trackPageView() 针对初始加载——当 enableAutoRouteTracking 启用后,后续的路由切换将自动进行。

快速入门(SDK 加载脚本)

当您希望 SDK 自动更新且无需构建管道时,建议使用此方法。将此内容作为第一个

仅限加载器的 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");
  }
});

点击分析

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/replaceStatepopstate.
  • React Router:使用 @microsoft/applicationinsights-react-js withAITracking HOC(参见 references/framework-extensions.md)。
  • 手动:在路由器中调用 appInsights.trackPageView({ name, uri }) 在路由器的 useEffect 中调用该方法。禁用 enableAutoRouteTracking 以避免重复计数。

分布式追踪(与后端关联)

设置 distributedTracingMode: 2 (DistributedTracingModes.AI_AND_W3C)。SDK会添加 traceparent (以及旧版 Request-Id)到出站 fetch/XHR。已通过 OpenTelemetry 进行instrumentation的后端(例如 @azure/monitor-opentelemetry)会自动与浏览器的 operation_Id 建立关联。

对于跨源调用,还需设置 enableCorsCorrelation: true 并将调用源添加到 API 的 CORS 暴露头中。

生成式 AI 代理跟踪(OTel 语义约定)

当浏览器调用 AI 代理(函数调用、工具使用、客户端直接调用模型)时,请发布 App Insights 依赖项遥测数据,其属性应遵循 OpenTelemetry GenAI 语义约定,以便在 App Insights / Log Analytics 中与后端代理跨度一起进行查询。

请先设置 opt-in 环境变量,以确保后端instrumentation采用相同的模式版本:

OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental

必需的属性键(请原样使用 OTel 名称)

Span / op 必填属性
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;

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
      });
      if (error) {
        appInsights.trackException({
          exception: error,
          severityLevel: SeverityLevel.Error,
          properties: { ...properties, "error.type": error.name } as Record
        });
      }
    }
  };
}

// 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。如需添加核心 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 } });

通过遥测初始化程序进行按类型采样:使用 return false 基于 item.baseType.

离线 / 卸载时发送

SDK 使用 sendBeacon (默认 onunloadDisableBeacon: false) 在 pagehide / unload。对于单页应用(SPA),还需在 appInsights.flush() 在破坏性状态转换(注销、强制刷新)之前调用该方法。

常见陷阱

  1. 请勿进行两次初始化。在不同的捆绑包下重新导入该模块会导致页面浏览量重复计算。请使用单个共享模块导出。
  2. 请在用户首次输入前完成初始化,以避免丢失早期点击或异常。
  3. 连接字符串是公开的——切勿为后端密钥重复使用相同的 App Insights 资源。
  4. enableAutoRouteTracking + 手动trackPageView= 导致重复。请选择其中一种。
  5. CORS 分布式追踪要求 API 允许 Request-Id, Request-Context, traceparent, tracestate 请求头,并暴露 Request-Context 响应头。
  6. 生成式人工智能(GenAI)的敏感内容gen_ai.input.messages 等)采用“主动启用”机制——除非设置显式运行时标志并经批准的数据处理流程,否则绝不进行日志记录。
  7. 代理令牌的使用情况记录在 chat 跨度中,而非 invoke_agent —— 仅在您确知的情况下,才将聚合的使用情况复制到父代理跨度中。
  8. React StrictMode 在开发环境中会双重调用效果——请使用 loadAppInsights() 模块级单例进行保护。

打包大小

完整的 Web SDK 经 gzip 压缩后为 36压缩后为 110 KB( KB)。若预算紧张,请使用加载器脚本路径,使 SDK 在关键路径之外异步加载,或通过树摇动移除未使用的插件。

关键类型

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. 从单个模块导出一个单例实例
  2. 在应用程序入口点尽早初始化,在路由器设置之前。
  3. 使用遥测初始化程序进行附加 app.version, tenantId,并清除个人身份信息(PII)和查询字符串中的机密信息。
  4. 设置distributedTracingMode: 2,并确保您的API接受/暴露W3C跟踪上下文标头。
  5. 对于 GenAI,请严格遵循 OTel gen_ai.* 属性名称——这些名称在浏览器和后端遥测中均可统一查询。
  6. 对敏感内容的捕获gen_ai.input.messages / gen_ai.output.messages)设置为构建时或运行时的选择加入机制。
  7. 在注销或进行敏感导航时进行刷新,以确保正在传输中的遥测数据不会丢失。

参考资料

  • 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/

在 GitHub 上查看
---
name: applicationinsights-web-ts
description: Instrument browser/web apps with the Application Insights JavaScript SDK for Real User Monitoring (RUM), including page views, clicks, AJAX/fetch dependencies, exceptions, custom events, and GenAI agent traces correlated to backend OpenTelemetry traces.
license: MIT
---

# Application Insights JavaScript SDK (Web) for TypeScript

Real User Monitoring (RUM) for browser apps with `@microsoft/applicationinsights-web`. Auto-collects page views, AJAX/fetch dependencies, unhandled exceptions, and (with the Click Analytics plugin) clicks. Supports custom events, metrics, and **GenAI agent traces** that follow OpenTelemetry GenAI semantic conventions and correlate to backend spans via W3C Trace Context.

> **Distinct from `azure-monitor-opentelemetry-ts`**, which is for Node.js server apps. This skill is for **browser/web** code (and React Native).

## Before Implementation

Search `microsoft-docs` MCP for current API patterns:

- Query: "Application Insights JavaScript SDK setup"
- Query: "Application Insights JavaScript SDK configuration"
- Query: "Application Insights JavaScript framework extensions React Angular"
- Verify package version: `npm view @microsoft/applicationinsights-web version`

## Packages

| Package | Purpose |
| --- | --- |
| `@microsoft/applicationinsights-web` | Core RUM SDK (page views, AJAX, exceptions). |
| `@microsoft/applicationinsights-clickanalytics-js` | Auto-collect click telemetry. |
| `@microsoft/applicationinsights-react-js` | React plugin (router instrumentation, hooks, HOC, ErrorBoundary). |
| `@microsoft/applicationinsights-react-native` | React Native plugin (native crashes, sessions). |
| `@microsoft/applicationinsights-angularplugin-js` | Angular plugin (router events, ErrorHandler). |
| `@microsoft/applicationinsights-debugplugin-js` | Dev-only telemetry inspector. |
| `@microsoft/applicationinsights-perfmarkmeasure-js` | User Timing (`performance.mark/measure`) integration. |

## Installation

```bash
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
```

Typings ship with the package — no separate `@types/...` install needed.

## Connection String

The browser SDK requires a connection string at init time. **It ships in plaintext to clients** — Microsoft Entra ID auth is not supported for browser telemetry. Use a separate App Insights resource with local auth enabled for browser RUM if you need to isolate it from backend telemetry.

```bash
# 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=..."
```

## Quick Start (npm)

```typescript
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();
```

Call `loadAppInsights()` exactly once, as early as possible (before user interactions you want tracked). Then `trackPageView()` for the initial load — when `enableAutoRouteTracking` is on, subsequent route changes are automatic.

## Quick Start (SDK Loader Script)

Recommended when you want auto-updating SDK and zero build pipeline. Paste this as the **first** `<script>` in `<head>`:

```html
<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>
```

Loader-only API (queued until SDK loads): `trackEvent`, `trackPageView`, `trackException`, `trackTrace`, `trackDependencyData`, `trackMetric`, `trackPageViewPerformance`, `startTrackPage`, `stopTrackPage`, `startTrackEvent`, `stopTrackEvent`, `addTelemetryInitializer`, `setAuthenticatedUserContext`, `clearAuthenticatedUserContext`, `flush`.

## Core Tracking APIs

```typescript
// 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();
```

## Telemetry Initializers (enrichment & filtering)

Run for every envelope before send. Return `false` to drop.

```typescript
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

```typescript
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();
```

Mark elements with `data-ai-*` attributes; clicks are emitted as Custom Events with parent-content metadata.

## SPA Route Tracking

- **Built-in:** set `enableAutoRouteTracking: true`. Hooks `history.pushState/replaceState` and `popstate`.
- **React Router:** use `@microsoft/applicationinsights-react-js` `withAITracking` HOC (see [references/framework-extensions.md](references/framework-extensions.md)).
- **Manual:** call `appInsights.trackPageView({ name, uri })` in your router's `useEffect` on route change. Disable `enableAutoRouteTracking` to avoid double counting.

## Distributed Tracing (correlate to backend)

Set `distributedTracingMode: 2` (`DistributedTracingModes.AI_AND_W3C`). The SDK adds `traceparent` (and legacy `Request-Id`) to outbound `fetch`/`XHR`. Backends instrumented with **OpenTelemetry** (e.g. `@azure/monitor-opentelemetry`) auto-link to the browser's operation_Id.

For cross-origin calls, also set `enableCorsCorrelation: true` and add the calling origin to the **CORS exposed headers** on the API.

## GenAI Agent Traces (OTel semantic conventions)

When the browser invokes an AI agent (function-calling, tool-use, model calls direct from the client), emit App Insights **Dependency** telemetry whose attributes follow the OpenTelemetry **GenAI semantic conventions** so they are queryable alongside backend agent spans in App Insights / Log Analytics.

**Set the opt-in env first** so backend instrumentations agree on the same schema version:

```bash
OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental
```

### Required attribute keys (use the OTel names verbatim)

| Span / op | Required attributes |
| --- | --- |
| `invoke_agent {agent.name}` | `gen_ai.operation.name=invoke_agent`, `gen_ai.provider.name`, `gen_ai.agent.name`, `gen_ai.agent.id` (when known) |
| `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` well-known values: `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`.

> **Sensitive content opt-in.** `gen_ai.system_instructions`, `gen_ai.input.messages`, `gen_ai.output.messages`, `gen_ai.tool.call.arguments`, `gen_ai.tool.call.result` are **Opt-In** by default. Gate them behind a runtime flag and avoid them in production unless you have approved data handling.

### Pattern: invoke_agent + nested tool/model spans

```typescript
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);
}
```

The browser's `traceparent` is automatically attached to outbound `fetch` (when `distributedTracingMode: 2`), so downstream Azure OpenAI / agent backend spans hang under the same operation_Id in App Insights.

For the full attribute reference, well-known values, and content-capture guidance, see [references/agent-traces.md](references/agent-traces.md).

### KQL: query GenAI traces in App Insights

```kusto
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)

See [references/framework-extensions.md](references/framework-extensions.md) for full React, React Native, Angular, Next.js, and Vite recipes.

```typescript
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

```typescript
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();
```

## Performance — Web Vitals

Auto-collected: page-load timings via `PerformanceTiming` / `PerformanceNavigationTiming`. To add Core Web Vitals:

```typescript
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);
```

## Cookies & Privacy

```typescript
new ApplicationInsights({ config: {
  connectionString,
  isCookieUseDisabled: true,         // hard-disable all cookies
  cookieCfg: { enabled: true, domain: ".example.com", path: "/", expiry: 365 }
}});
```

To honor consent dynamically:

```typescript
appInsights.getCookieMgr().setEnabled(userGaveConsent);
appInsights.config.disableTelemetry = !userGaveConsent;
```

## Sampling

Server-side ingestion sampling (recommended) is configured on the App Insights resource. SDK-side sampling reduces network use:

```typescript
new ApplicationInsights({ config: { connectionString, samplingPercentage: 50 } });
```

Per-type sampling via telemetry initializer: drop with `return false` based on `item.baseType`.

## Offline / Send-on-Unload

The SDK uses `sendBeacon` (default `onunloadDisableBeacon: false`) to flush on `pagehide` / `unload`. For SPAs, also call `appInsights.flush()` before destructive transitions (logout, hard reload).

## Common Pitfalls

1. **Do not initialize twice.** Re-importing the module under different bundles produces duplicate page views. Use a single shared module export.
2. **Initialize before first user input** to avoid losing early clicks/exceptions.
3. **Connection string is public** — never reuse the same App Insights resource for backend secrets.
4. **`enableAutoRouteTracking` + manual `trackPageView`** = duplicates. Pick one.
5. **CORS distributed tracing** requires the API to allow `Request-Id`, `Request-Context`, `traceparent`, `tracestate` request headers and expose `Request-Context` response header.
6. **GenAI sensitive content** (`gen_ai.input.messages` etc.) is Opt-In — never log without an explicit runtime flag and approved data handling.
7. **Agent token usage is on `chat` spans, not `invoke_agent`** — copy aggregated usage to the parent agent span only if you know it.
8. **React StrictMode** double-invokes effects in dev — guard `loadAppInsights()` with a module-level singleton.

## Bundle Size

The full web SDK is ~110 KB minified (~36 KB gzipped). For aggressive budgets, use the **Loader Script** path so the SDK loads asynchronously off the critical path, or tree-shake unused plugins.

## Key Types

```typescript
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";
```

## Best Practices

1. **One singleton instance** exported from a single module.
2. **Initialize early** in the app entrypoint, before router setup.
3. **Use telemetry initializers** to attach `app.version`, `tenantId`, and to scrub PII / query-string secrets.
4. **Set `distributedTracingMode: 2`** and ensure your APIs accept/expose W3C trace context headers.
5. **For GenAI**, follow OTel `gen_ai.*` attribute names verbatim — they are queryable across browser and backend telemetry uniformly.
6. **Gate sensitive content capture** (`gen_ai.input.messages` / `gen_ai.output.messages`) behind a build-time or runtime opt-in.
7. **Flush on logout / sensitive navigation** so in-flight telemetry isn't dropped.

## References

- [references/agent-traces.md](references/agent-traces.md) — Full OTel GenAI semconv distilled (agent / model / tool spans, attributes, content capture).
- [references/framework-extensions.md](references/framework-extensions.md) — React, React Native, Angular, Next.js, Vite recipes.
- [references/configuration.md](references/configuration.md) — Full `IConfiguration` reference and tuning guide.
- Microsoft Learn: <https://learn.microsoft.com/azure/azure-monitor/app/javascript-sdk>
- ApplicationInsights-JS source: <https://github.com/microsoft/ApplicationInsights-JS>
- OTel GenAI semantic conventions: <https://opentelemetry.io/docs/specs/semconv/gen-ai/>

所有文件

0 个文件

安装 applicationinsights-web-ts

下载技能文件并将其解压到 .claude/skills/ 目录中。

下载ZIP

克隆仓库并复制技能文件到您的项目中。

git clone https://github.com/microsoft/skills/tree/main/.github/skills/applicationinsights-web-ts # Copy SKILL.md to your .claude/skills/ directory

复制 复制
快速设置: 将技能文件夹复制到 .claude/skills/ Claude 会自动检测并使用该技能

相关技能

github-code-search
更新时间 2026-06-29
drizzle-orm
更新时间 2026-06-29
clickhouse-io
更新时间 2026-06-29
prisma-client-api
更新时间 2026-06-29
OR