跳至主要內容
Telemetry
瀏覽說明文件

指南更新於 2026年10月3日閱讀約需 4 分鐘

讓程式設計代理使用這篇文件

開啟 Claude Code、Codex、Cursor 或其他編碼代理的集中提示包,然後將其適應此處介紹的工作流程。

本頁內容
  1. 修改路由之前
  2. 加入伺服器輔助函式
  3. 包裝現有處理函式
  4. 驗證實際呼叫
  5. 不保證什麼
  6. 框架參考與後續步驟

觀察一條現有的 Next.js 路由

本範例適用於現有 Next.js App Router 應用,請使用已套用最新修補程式的目前版本及受支援的 Node.js 部署。after API 自 Next.js 15.1 起穩定;這個 API 最低版本並不表示建議安裝未修補的舊版本。它觀察處理函式傳回 Response 或拋出的情況,不代表瀏覽器收到回應、串流回應完成或背景業務工作完成。

修改路由之前

選擇你控制的路由及已獲授權、可安全執行的操作。保留驗證、檢查和業務邏輯。TELEMETRY_API_KEY 只放在伺服器環境中,不要使用 NEXT_PUBLIC_ 前綴。首頁匿名金鑰可傳送和查詢;帳戶金鑰在驗證時需要 read-and-write 權限。僅傳送事件的應用可使用僅攝取金鑰。

加入伺服器輔助函式

儲存為 lib/with-telemetry.js。使用不含客戶識別碼的固定路由範本。產生的呼叫 ID 只識別一次處理函式呼叫,不代表使用者或邏輯工作。不傳送 URL、請求內文、Cookie、標頭或錯誤訊息。

import { after } from 'next/server';
import { randomUUID } from 'node:crypto';

function warnTelemetry(message) {
  try {
    console.warn(message);
  } catch {
    // Diagnostic failure must not change the application outcome.
  }
}

export function withTelemetry(handler, routeTemplate) {
  return async function observedHandler(request, context) {
    const started = performance.now();
    const invocationId = randomUUID();
    let outcome = 'threw';
    let statusCode = null;
    try {
      const response = await handler(request, context);
      outcome = 'returned_response';
      statusCode = response.status;
      return response;
    } finally {
      const event = {
        invocation_id: invocationId,
        route_template: routeTemplate,
        method: request.method,
        handler_outcome: outcome,
        status_code: statusCode,
        latency_ms: performance.now() - started,
        environment: process.env.NODE_ENV || 'development',
      };
      try {
        after(async () => {
          const key = process.env.TELEMETRY_API_KEY;
          if (!key) {
            warnTelemetry('Telemetry key missing; event not sent');
            return;
          }
          try {
            const response = await fetch('https://api.telemetry.sh/log', {
              method: 'POST',
              headers: {
                Authorization: `Bearer ${key}`,
                'Content-Type': 'application/json',
              },
              cache: 'no-store',
              signal: AbortSignal.timeout(2000),
              body: JSON.stringify({ table: 'nextjs_route_observed', data: event }),
            });
            if (!response.ok) warnTelemetry('Telemetry event send rejected');
          } catch {
            warnTelemetry('Telemetry event send failed');
          }
        });
      } catch {
        warnTelemetry('Telemetry background scheduling failed');
      }
    }
  };
}

包裝現有處理函式

將現有匯出的 GET 函式改名為 existingGET,保持函式內容不變,再匯出下方包裝器。依實際路由調整方法和固定範本;不要新增永遠成功的虛構處理函式來完成設定。

import { withTelemetry } from "@/lib/with-telemetry";

export const GET = withTelemetry(existingGET, "/api/reports/:id");

驗證實際呼叫

透過應用執行獲授權的操作,再查詢 Telemetry 資料表。核對路由、方法、時間、結果和狀態是否對應剛才的操作。HTTP 接收不等於驗證。離線測試、示範路由或代理 QA 執行不是客戶整合;虛構傳送應使用 telemetry_quickstart。

SELECT invocation_id, route_template, method, handler_outcome,
       status_code, latency_ms, environment, timestamp_utc
FROM nextjs_route_observed
WHERE timestamp_utc >= now() - INTERVAL '15 minutes'
ORDER BY timestamp_utc DESC
LIMIT 20;

不保證什麼

Next.js after 在回應結束後排程傳送。它不是持久佇列:平台時限、關機、逾時和網路故障可能造成事件遺失。傳送逾時為兩秒,警告是無私密資料的固定文字;不承諾自動重試或去重。保留現有日誌,必要的稽核紀錄應使用持久投遞路徑。

latency_ms 到處理函式傳回或拋出時結束,不含事件傳送時間。returned_response 也可能是 4xx 或 5xx。threw 可能是框架重新導向或控制流程,不能自動視為伺服器故障。缺少金鑰或遙測失敗不得取代原回應或原例外。上線前在自己的執行環境中檢查此函式。

框架參考與後續步驟

Next.js after 參考文件說明版本及部署支援。不支援靜態匯出;配接器需要明確支援。回應保留、拋出的例外及遙測傳送失敗已在隔離的 Next.js 16.3.8 開發模式 App Router 應用中檢查,事件傳送被攔截且外部網路已停用。這不驗證真實的 Telemetry 擷取或你的正式環境主機。請繼續閱讀事件擷取驗證及 JavaScript SDK 指南以擴充埋點。

相關功能

記錄穩定的事件名稱、型別明確的欄位,以及經過隱私審查的上下文。

頁面作者與參考資料

Telemetry 編輯團隊負責維護本文;產品團隊審查功能行為、範例和適用範圍。

我們如何審查文件