feat: 全链路追踪系统 — ai-core追踪事件 + ethend管道视图
ai-core: - 新增 TraceEvent 内存环形缓冲区(200条) - GET /api/v1/trace/events 端点(支持session_id过滤) - 预置 trace.go 追踪事件定义 ethend: - trace/recent 聚合 platform-bridge消息日志 + ai-core追踪事件 - 消息按管线分组: msg_received→llm_call→tool_call→msg_sent - 前端管线卡片视图: 每条消息显示完整处理步骤 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+22
-5
@@ -1277,16 +1277,16 @@ function parseLogTimestamp(line) {
|
||||
app.get('/api/trace/recent', async (req, res) => {
|
||||
const limit = Math.min(parseInt(req.query.limit) || 50, 200);
|
||||
try {
|
||||
const [llmResult, toolResult, sessionsResult, bridgeLogsResult, aiCoreLogsResult] = await Promise.all([
|
||||
const [llmResult, toolResult, sessionsResult, bridgeLogsResult, traceEventsResult] = await Promise.all([
|
||||
proxyToAICore(`/api/v1/llm-calls?limit=${limit}`).catch(() => ({ status: 502, body: [] })),
|
||||
proxyToAICore(`/api/v1/tools/calls?limit=${limit}`).catch(() => ({ status: 502, body: { calls: [] } })),
|
||||
proxyToGateway('/api/v1/admin/sessions/active').catch(() => ({ status: 502, body: { users: {} } })),
|
||||
// 拉 platform-bridge 最近的消息日志
|
||||
Promise.all((['obv11', 'qq']).map(platform =>
|
||||
proxyToPlatformBridge(`/api/v1/logs/${platform}?limit=50`).catch(() => ({ status: 502, body: { entries: [] } }))
|
||||
Promise.all((['obv11']).map(platform =>
|
||||
proxyToPlatformBridge(`/api/v1/logs/${platform}?limit=50`).catch(() => ({ status: 502, body: { logs: [] } }))
|
||||
)),
|
||||
// 拉 ai-core 最近的日志(解析处理事件)
|
||||
proxyToAICore('/api/v1/llm-calls/stream?limit=0').catch(() => ({ status: 502, body: [] })),
|
||||
// 拉 ai-core 追踪事件
|
||||
proxyToAICore(`/api/v1/trace/events?limit=${limit}`).catch(() => ({ status: 502, body: { events: [] } })),
|
||||
]);
|
||||
|
||||
const traces = [];
|
||||
@@ -1349,6 +1349,23 @@ app.get('/api/trace/recent', async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
// === ai-core 追踪事件 (intent, subsession, synthesis, etc.) ===
|
||||
const traceEvents = traceEventsResult.body?.events || [];
|
||||
for (const ev of traceEvents) {
|
||||
const ts = ev.timestamp ? new Date(ev.timestamp).getTime() : Date.now();
|
||||
traces.push({
|
||||
id: ev.id || `trace-${ts}`,
|
||||
timestamp: new Date(ts).toISOString(), ts,
|
||||
service: 'ai-core',
|
||||
hop: ev.hop || 'trace',
|
||||
label: ev.label || '',
|
||||
status: ev.status || 'success',
|
||||
durationMs: ev.duration_ms || 0,
|
||||
detail: ev.detail || '',
|
||||
data: ev.data || {},
|
||||
});
|
||||
}
|
||||
|
||||
// === 活跃会话 ===
|
||||
const users = sessionsResult.body?.users || {};
|
||||
for (const [userID, sessions] of Object.entries(users)) {
|
||||
|
||||
Reference in New Issue
Block a user