mcpField
A
applicationinsights-web-ts

applicationinsights-web-ts

github.com/microsoft开发3.2k39 次安装今天更新
代码仓库

关于 applicationinsights-web-ts

这项 TypeScript 技能介绍如何为浏览器应用和 React Native 添加 Application Insights 用户监测,涵盖遥测、分布式追踪、框架插件,以及可关联后端跨度的 GenAI 追踪。

主要功能

  1. 01采集页面浏览和依赖数据
  2. 02跟踪异常、事件和指标
  3. 03监测 SPA 路由和点击
  4. 04关联前端与后端追踪
  5. 05按 OTel 规范记录 GenAI 追踪
  6. 06配置隐私和采样

适用场景

  1. 01监测浏览器应用的使用情况和错误
  2. 02跨前端与后端追踪请求
  3. 03衡量 GenAI Agent 和工具活动
  4. 04为 React 或 Angular 应用添加遥测

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/microsoft/skills --skill applicationinsights-web-ts

安装后在 Claude Code 中输入/applicationinsights-web-ts确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
agent-traces.md
configuration.md
framework-extensions.md

详细介绍

TypeScript 的 Application Insights JavaScript SDK(Web)

使用 @microsoft/applicationinsights-web 为浏览器应用提供真实用户监控(RUM)。自动收集页面浏览、AJAX/fetch 依赖项、未处理的异常,以及(使用 Click Analytics 插件时)点击数据。支持自定义事件、指标和生成式 AI Agent 跟踪,遵循 OpenTelemetry GenAI 语义约定,并通过 W3C Trace Context 与后端 Span 关联。

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

实施前

在 microsoft-docs MCP 中搜索最新的 API 用法:

  • 查询:“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-jsReact 插件(路由器检测、Hook、HOC、ErrorBoundary)。
@microsoft/applicationinsights-react-nativeReact Native 插件(原生崩溃、会话)。
@microsoft/applicationinsights-angularplugin-jsAngular 插件(路由器事件、ErrorHandler)。
@microsoft/applicationinsights-debugplugin-js仅供开发使用的遥测检查器。
@microsoft/applicationinsights-perfmarkmeasure-jsUser 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");
  }
});

点击分析

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 的 withAITracking HOC(参见 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 Agent 跟踪(OTel 语义约定)

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

先设置选择启用的环境变量,确保后端插桩使用相同的架构版本:

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 / Agent 后端跨度会归属到 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. 不要重复初始化。 在不同的打包中重新导入模块会产生重复的页面浏览记录。请使用单一的共享模块导出。
  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. Agent 的令牌用量记录在 chat span 上,而不是 invoke_agent 上——只有在确认用量后,才将汇总用量复制到父级 Agent span。
  8. React StrictMode 会在开发环境中双重调用副作用——使用模块级单例保护 loadAppInsights()。

包体积

完整的 Web SDK 压缩后约为 110 KB(gzip 后约为 36 KB)。若要严格控制体积预算,请使用 Loader Script 路径,让 SDK 异步加载,避免占用关键路径;或者通过 tree-shaking 移除未使用的插件。

关键类型

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. 在注销或敏感导航时刷新,以免丢弃正在传输的遥测数据。

参考资料

评论

支持 Markdown