Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/server/handlers/claude.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,11 @@ export const handleClaudeRequest = async (req, res, isStream) => {
type: "message_stop"
}));

// 存储 token 数量到 res.locals 供日志使用
if (usageData) {
res.locals.tokens = usageData.total_tokens || usageData.completion_tokens;
}

clearInterval(heartbeatTimer);
res.end();
} catch (error) {
Expand Down Expand Up @@ -346,6 +351,12 @@ export const handleClaudeRequest = async (req, res, isStream) => {
);

const stopReason = toolCalls.length > 0 ? 'tool_use' : 'end_turn';

// 存储 token 数量到 res.locals 供日志使用
if (usageData) {
res.locals.tokens = usageData.total_tokens || usageData.completion_tokens;
}

const response = createClaudeResponse(
msgId,
model,
Expand Down Expand Up @@ -377,6 +388,12 @@ export const handleClaudeRequest = async (req, res, isStream) => {
);

const stopReason = toolCalls.length > 0 ? 'tool_use' : 'end_turn';

// 存储 token 数量到 res.locals 供日志使用
if (usage) {
res.locals.tokens = usage.total_tokens || usage.completion_tokens;
}

const response = createClaudeResponse(
msgId,
model,
Expand Down
17 changes: 17 additions & 0 deletions src/server/handlers/gemini.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ export const handleGeminiRequest = async (req, res, modelName, isStream) => {
const finalChunk = createGeminiResponse(null, null, null, null, finishReason, usageData, { passSignatureToClient: config.passSignatureToClient });
writeStreamData(res, finalChunk);

// 存储 token 数量到 res.locals 供日志使用
if (usageData) {
res.locals.tokens = usageData.total_tokens || usageData.completion_tokens;
}

clearInterval(heartbeatTimer);
endStream(res, false);
} catch (error) {
Expand Down Expand Up @@ -234,6 +239,12 @@ export const handleGeminiRequest = async (req, res, modelName, isStream) => {
);

const finishReason = "STOP";

// 存储 token 数量到 res.locals 供日志使用
if (usageData) {
res.locals.tokens = usageData.total_tokens || usageData.completion_tokens;
}

const response = createGeminiResponse(content, reasoningContent || null, reasoningSignature, toolCalls, finishReason, usageData, { passSignatureToClient: config.passSignatureToClient });
res.json(response);
} catch (error) {
Expand All @@ -254,6 +265,12 @@ export const handleGeminiRequest = async (req, res, modelName, isStream) => {
);

const finishReason = toolCalls.length > 0 ? "STOP" : "STOP";

// 存储 token 数量到 res.locals 供日志使用
if (usage) {
res.locals.tokens = usage.total_tokens || usage.completion_tokens;
}

const response = createGeminiResponse(content, reasoningContent, reasoningSignature, toolCalls, finishReason, usage, { passSignatureToClient: config.passSignatureToClient });
res.json(response);
}
Expand Down
16 changes: 16 additions & 0 deletions src/server/handlers/geminicli.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ export const handleGeminiCliRequest = async (req, res, forceFormat = null) => {

writer.finalize();

// 存储 token 数量到 res.locals 供日志使用
const usageData = writer.getUsageData();
if (usageData) {
res.locals.tokens = usageData.total_tokens || usageData.completion_tokens;
}

clearInterval(heartbeatTimer);
endStream(res, false);
} catch (error) {
Expand Down Expand Up @@ -138,6 +144,11 @@ export const handleGeminiCliRequest = async (req, res, forceFormat = null) => {
usage
});

// 存储 token 数量到 res.locals 供日志使用
if (usage) {
res.locals.tokens = usage.total_tokens || usage.completion_tokens;
}

clearInterval(heartbeatTimer);
endStream(res, false);
} catch (error) {
Expand Down Expand Up @@ -186,6 +197,11 @@ export const handleGeminiCliRequest = async (req, res, forceFormat = null) => {
}
}

// 存储 token 数量到 res.locals 供日志使用
if (usage) {
res.locals.tokens = usage.total_tokens || usage.completion_tokens;
}

// 根据请求格式返回相应格式的响应
if (format === 'gemini') {
res.json(createGeminiResponse(
Expand Down
14 changes: 14 additions & 0 deletions src/server/handlers/openai.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ export const handleOpenAIRequest = async (req, res) => {
);

writeStreamData(res, { ...createStreamChunk(id, created, model, {}, hasToolCall ? 'tool_calls' : 'stop'), usage: usageData });
// 存储 token 数量到 res.locals 供日志使用
if (usageData) {
res.locals.tokens = usageData.total_tokens || usageData.completion_tokens;
}
}

clearInterval(heartbeatTimer);
Expand Down Expand Up @@ -192,6 +196,11 @@ export const handleOpenAIRequest = async (req, res) => {
}
}

// 存储 token 数量到 res.locals 供日志使用
if (usageData) {
res.locals.tokens = usageData.total_tokens || usageData.completion_tokens;
}

res.json(createOpenAIChatCompletionResponse({
id,
created,
Expand Down Expand Up @@ -236,6 +245,11 @@ export const handleOpenAIRequest = async (req, res) => {
}
}

// 存储 token 数量到 res.locals 供日志使用
if (usage) {
res.locals.tokens = usage.total_tokens || usage.completion_tokens;
}

// 使用预构建的响应对象,减少内存分配
res.json(createOpenAIChatCompletionResponse({
id,
Expand Down
6 changes: 5 additions & 1 deletion src/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ app.use((req, res, next) => {
if (!ignorePaths.some(p => fullPath.startsWith(p))) {
const start = Date.now();
res.on('finish', () => {
logger.request(req.method, fullPath, res.statusCode, Date.now() - start);
// 从请求体或 URL 参数中获取模型名称
const model = req.body?.model || req.params?.model || null;
// 从响应对象中获取 token 数量
const tokens = res.locals?.tokens || null;
logger.request(req.method, fullPath, res.statusCode, Date.now() - start, model, tokens);
});
}
next();
Expand Down
8 changes: 5 additions & 3 deletions src/utils/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ function logMessage(level, ...args) {
logWsServer.storeLog(level, message);
}

function logRequest(method, path, status, duration) {
function logRequest(method, path, status, duration, model, tokens) {
const statusColor = status >= 500 ? colors.red : status >= 400 ? colors.yellow : colors.green;
const message = `[${method}] - ${path} ${status} ${duration}ms`;
const modelInfo = model ? ` [${model}]` : '';
const tokensInfo = tokens ? ` tokens:${tokens}` : '';
const message = `[${method}] - ${path}${modelInfo} ${status} ${duration}ms${tokensInfo}`;

// 输出到控制台
console.log(`${colors.cyan}[${method}]${colors.reset} - ${path} ${statusColor}${status}${colors.reset} ${colors.gray}${duration}ms${colors.reset}`);
console.log(`${colors.cyan}[${method}]${colors.reset} - ${path}${colors.cyan}${modelInfo}${colors.reset} ${statusColor}${status}${colors.reset} ${colors.gray}${duration}ms${colors.reset}${colors.yellow}${tokensInfo}${colors.reset}`);

// 存储日志(根据状态码决定级别)
const level = status >= 500 ? 'error' : status >= 400 ? 'warn' : 'request';
Expand Down