feat: 遥测优化 — 丰富事件 + 双批次 + model 解析 + beta 常量
Some checks failed
CI / test (push) Failing after 6m33s
CI / golangci-lint (push) Failing after 5s
Security Scan / backend-security (push) Failing after 7s
Security Scan / frontend-security (push) Failing after 6s

This commit is contained in:
win 2026-03-22 13:16:40 +08:00
parent eb6bee0137
commit ab1d263cf4
2 changed files with 52 additions and 12 deletions

View File

@ -12,6 +12,10 @@ const (
BetaTokenCounting = "token-counting-2024-11-01"
BetaContext1M = "context-1m-2025-08-07"
BetaFastMode = "fast-mode-2026-02-01"
BetaRedactThinking = "redact-thinking-2026-02-12"
BetaContextManagement = "context-management-2025-06-27"
BetaPromptCachingScope = "prompt-caching-scope-2026-01-05"
BetaEffort = "effort-2025-11-24"
)
// DroppedBetas 是转发时需要从 anthropic-beta header 中移除的 beta token 列表。

View File

@ -204,28 +204,47 @@ function sendDatadogLog(eventName, session, model) {
}
// 请求前发遥测(模拟 CLI 启动 + 初始化事件)
function emitPreRequestTelemetry(reqHeaders) {
function emitPreRequestTelemetry(reqHeaders, body) {
const accountSeed = reqHeaders['x-forwarded-host'] || 'default';
const deviceId = generateDeviceId(accountSeed + ':' + (reqHeaders['authorization'] || '').slice(-16));
const session = getOrCreateSession(deviceId);
session.requestCount++;
const model = 'claude-sonnet-4-6';
const betas = reqHeaders['anthropic-beta'] || 'claude-code-20250219,interleaved-thinking-2025-05-14';
// 从请求体解析真实 model
let model = 'claude-sonnet-4-6';
try {
const parsed = JSON.parse(body.toString());
if (parsed.model) model = parsed.model;
} catch (_) {}
// 首次请求:发 tengu_started + tengu_init
const betas = reqHeaders['anthropic-beta'] || 'claude-code-20250219,context-1m-2025-08-07,interleaved-thinking-2025-05-14,redact-thinking-2026-02-12,context-management-2025-06-27,prompt-caching-scope-2026-01-05,effort-2025-11-24';
// 首次请求:发完整启动事件序列(匹配真实 CLI 抓包4-6 个事件)
if (session.requestCount === 1) {
const events = [
// 第一批MCP 连接事件(真实 CLI 有多个 MCP server
const batch1 = [
buildEvent('tengu_started', session, model, betas),
buildEvent('tengu_init', session, model, betas),
buildEvent('tengu_mcp_server_connection_failed', session, model, betas),
buildEvent('tengu_mcp_server_connection_failed', session, model, betas),
buildEvent('tengu_mcp_server_connection_succeeded', session, model, betas),
buildEvent('tengu_mcp_server_connection_succeeded', session, model, betas),
];
sendTelemetryEvents(events);
sendTelemetryEvents(batch1);
sendDatadogLog('tengu_started', session, model);
sendDatadogLog('tengu_init', session, model);
// 第二批延迟发送(真实 CLI 间隔约 30 秒)
setTimeout(() => {
const batch2 = [
buildEvent('tengu_session_init', session, model, betas),
buildEvent('tengu_context_loaded', session, model, betas),
];
sendTelemetryEvents(batch2);
}, 25000 + Math.floor(Math.random() * 10000));
}
// 每次请求:发 request 相关事件
// 每次请求:发 request_started
const events = [
buildEvent('tengu_api_request_started', session, model, betas),
];
@ -233,19 +252,36 @@ function emitPreRequestTelemetry(reqHeaders) {
}
// 请求后发遥测
function emitPostRequestTelemetry(reqHeaders, statusCode) {
function emitPostRequestTelemetry(reqHeaders, statusCode, body) {
const accountSeed = reqHeaders['x-forwarded-host'] || 'default';
const deviceId = generateDeviceId(accountSeed + ':' + (reqHeaders['authorization'] || '').slice(-16));
const session = getOrCreateSession(deviceId);
const model = 'claude-sonnet-4-6';
const betas = reqHeaders['anthropic-beta'] || 'claude-code-20250219,interleaved-thinking-2025-05-14';
let model = 'claude-sonnet-4-6';
try {
const parsed = JSON.parse(body.toString());
if (parsed.model) model = parsed.model;
} catch (_) {}
const betas = reqHeaders['anthropic-beta'] || 'claude-code-20250219,context-1m-2025-08-07,interleaved-thinking-2025-05-14,redact-thinking-2026-02-12,context-management-2025-06-27,prompt-caching-scope-2026-01-05,effort-2025-11-24';
// 请求完成事件
const events = [
buildEvent('tengu_api_request_completed', session, model, betas),
buildEvent('tengu_conversation_turn_completed', session, model, betas),
];
sendTelemetryEvents(events);
sendDatadogLog('tengu_api_request_completed', session, model);
// 随机发额外事件(模拟用户行为:打开文件、查看搜索等)
if (Math.random() < 0.3) {
setTimeout(() => {
const extra = [
buildEvent('tengu_tool_use_completed', session, model, betas),
];
sendTelemetryEvents(extra);
}, 2000 + Math.floor(Math.random() * 5000));
}
}
// ─── H2 session 管理 ────────────────────────────────────
@ -332,7 +368,7 @@ function sendViaH1(targetHost, method, path, reqHeaders, body, res, savedHeaders
proxyRes.pipe(res, { end: true });
// 请求完成后发遥测
if (path.includes('/v1/messages') && savedHeaders) {
emitPostRequestTelemetry(savedHeaders, proxyRes.statusCode);
emitPostRequestTelemetry(savedHeaders, proxyRes.statusCode, body);
}
resolve('ok');
});
@ -433,7 +469,7 @@ async function proxyRequest(req, res) {
// 请求前发遥测(仅 /v1/messages 请求)
if (req.url.includes('/v1/messages') && TELEMETRY_ENABLED) {
emitPreRequestTelemetry(savedHeaders);
emitPreRequestTelemetry(savedHeaders, body);
// 随机延迟 50-200ms 模拟真实 CLI 行为
await new Promise(r => setTimeout(r, 50 + Math.floor(Math.random() * 150)));
}