Align usage dashboard with CCSwitch

Filter request logs to model API calls and add request, provider, model, and settings tabs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Opus 5 committed 2026-10-19 19:33:51 +08:00
1 parent f729910082
commit 272f604274
8 files changed
+444 -64

No files matched your search

+59 -2
View File
@@ -680,6 +680,60 @@ func TestApplyAndRestore(t *testing.T) {
}
}
func TestResponsesRequestsAreLogged(t *testing.T) {
env := newCodexTestEnv(t)
resp := env.post(t, "/v1/responses", responsesBody("gpt-5-codex", false), env.store.Config().RelayToken)
io.Copy(io.Discard, resp.Body)
resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Fatalf("status = %d, want 200", resp.StatusCode)
}
status := env.get(t, "/api/status")
stats := status["stats"].(map[string]any)
if stats["requests_total"].(float64) != 1 {
t.Errorf("requests_total = %v, want 1", stats["requests_total"])
}
logs := env.get(t, "/api/logs")["items"].([]any)
if len(logs) != 1 {
t.Fatalf("request logs = %v, want exactly one Responses request", logs)
}
if logs[0].(map[string]any)["path"] != "/v1/responses" {
t.Errorf("logged path = %v, want /v1/responses", logs[0].(map[string]any)["path"])
}
if logs[0].(map[string]any)["app"] != "Codex" || logs[0].(map[string]any)["provider"] != "codex-up" {
t.Errorf("log app/provider = %v/%v, want Codex/codex-up", logs[0].(map[string]any)["app"], logs[0].(map[string]any)["provider"])
}
}
func TestManagementRequestsAreExcludedFromLogsAndStats(t *testing.T) {
env := newTestEnv(t)
for _, path := range []string{"/api/status", "/api/logs", "/api/providers?target=claude", "/api/settings"} {
resp, err := http.Get(env.gateway.URL + path)
if err != nil {
t.Fatalf("get %s: %v", path, err)
}
io.Copy(io.Discard, resp.Body)
resp.Body.Close()
if resp.StatusCode != http.StatusOK {
t.Errorf("GET %s status = %d, want 200", path, resp.StatusCode)
}
}
resp := env.post(t, "/v1/messages/count_tokens", messagesBody("m", false), env.store.Config().RelayToken)
resp.Body.Close()
status := env.get(t, "/api/status")
stats := status["stats"].(map[string]any)
if stats["requests_total"].(float64) != 0 {
t.Errorf("requests_total = %v, want 0 after management requests", stats["requests_total"])
}
logs := env.get(t, "/api/logs")["items"].([]any)
if len(logs) != 0 {
t.Errorf("request logs = %v, want no management requests", logs)
}
}
func TestStatusAndLogs(t *testing.T) {
env := newTestEnv(t)
resp := env.post(t, "/v1/messages", messagesBody("m", false), env.store.Config().RelayToken)
@@ -701,8 +755,8 @@ func TestStatusAndLogs(t *testing.T) {
t.Errorf("status = %v", status)
}
stats := status["stats"].(map[string]any)
if stats["requests_total"].(float64) < 1 {
t.Errorf("stats = %v", stats)
if stats["requests_total"].(float64) != 1 {
t.Errorf("stats = %v, want exactly the one model request", stats)
}
active := status["active_claude_provider"].(map[string]any)
if active["name"] != "test" {
@@ -725,6 +779,9 @@ func TestStatusAndLogs(t *testing.T) {
if messageLog["model"] != "ds-chat" {
t.Errorf("log model = %v, want the resolved model", messageLog["model"])
}
if messageLog["app"] != "Claude Code" || messageLog["provider"] != "test" {
t.Errorf("log app/provider = %v/%v, want Claude Code/test", messageLog["app"], messageLog["provider"])
}
if messageLog["status"].(float64) != 200 {
t.Errorf("log status = %v", messageLog["status"])
}