feat(admin): add full-chain trace and performance monitoring

- Backend: trace.Logger ring-buffer for request chain events
- Backend: perf.Monitor with runtime.MemStats sampling every 10s
- Backend: /api/v1/admin/trace and /api/v1/admin/perf endpoints
- Frontend: TracePage — timeline with hop icons and status dots
- Frontend: PerformancePage — memory/GC bar charts + live stats
- Admin nav expanded to 11 items
This commit is contained in:
Aska committed 2026-08-12 17:16:33 +08:00
1 parent 8420691438
commit e8b5679cf4
8 files changed
+442

No files matched your search

+36
View File
@@ -66,6 +66,17 @@ type LLMCallLogger interface {
Stats() map[string]any
}
// TraceLogger provides full-chain trace events.
type TraceLogger interface {
Recent(n int) []map[string]any
}
// PerfMonitor provides performance snapshot history.
type PerfMonitor interface {
Latest() map[string]any
History() []map[string]any
}
// Dependencies holds all injectable services.
type Dependencies struct {
AuthMgr AuthManager
@@ -74,6 +85,8 @@ type Dependencies struct {
Orchestrator OrchestratorPipeline
WSHub WebSocketHub
LLMLogger LLMCallLogger
TraceLog TraceLogger
PerfMon PerfMonitor
ModelConfig *ModelConfigStore
PluginList []map[string]string
}
@@ -118,6 +131,8 @@ func (r *Router) setupRoutes() {
r.mux.HandleFunc("/api/v1/admin/sessions", r.authMW(r.adminMW(r.adminSessionsHandler)))
r.mux.HandleFunc("/api/v1/admin/models/config", r.authMW(r.adminMW(r.modelConfigHandler)))
r.mux.HandleFunc("/api/v1/admin/models/config/", r.authMW(r.adminMW(r.modelConfigItemHandler)))
r.mux.HandleFunc("/api/v1/admin/trace", r.authMW(r.adminMW(r.traceHandler)))
r.mux.HandleFunc("/api/v1/admin/perf", r.authMW(r.adminMW(r.perfHandler)))
}
// ServeHTTP implements http.Handler.
@@ -486,6 +501,27 @@ func num(m map[string]any, key string) int {
return 0
}
// --- Trace & Perf ---
func (r *Router) traceHandler(w http.ResponseWriter, req *http.Request) {
if r.deps.TraceLog == nil {
writeJSON(w, 200, M{"events": []any{}})
return
}
writeJSON(w, 200, M{"events": r.deps.TraceLog.Recent(100)})
}
func (r *Router) perfHandler(w http.ResponseWriter, req *http.Request) {
if r.deps.PerfMon == nil {
writeJSON(w, 200, M{"latest": M{}, "history": []any{}})
return
}
writeJSON(w, 200, M{
"latest": r.deps.PerfMon.Latest(),
"history": r.deps.PerfMon.History(),
})
}
// --- Helpers ---
type M = map[string]any