觀察一條現有的 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 指南以擴充埋點。