Merge pull request #29 from luispater/bugfix

Enhance client counting and logging
This commit is contained in:
Luis Pater
2025-09-05 21:48:30 +08:00
committed by GitHub
3 changed files with 85 additions and 9 deletions
+42 -1
View File
@@ -18,6 +18,7 @@ import (
managementHandlers "github.com/luispater/CLIProxyAPI/internal/api/handlers/management" managementHandlers "github.com/luispater/CLIProxyAPI/internal/api/handlers/management"
"github.com/luispater/CLIProxyAPI/internal/api/handlers/openai" "github.com/luispater/CLIProxyAPI/internal/api/handlers/openai"
"github.com/luispater/CLIProxyAPI/internal/api/middleware" "github.com/luispater/CLIProxyAPI/internal/api/middleware"
"github.com/luispater/CLIProxyAPI/internal/client"
"github.com/luispater/CLIProxyAPI/internal/config" "github.com/luispater/CLIProxyAPI/internal/config"
"github.com/luispater/CLIProxyAPI/internal/interfaces" "github.com/luispater/CLIProxyAPI/internal/interfaces"
"github.com/luispater/CLIProxyAPI/internal/logging" "github.com/luispater/CLIProxyAPI/internal/logging"
@@ -315,7 +316,47 @@ func (s *Server) UpdateClients(clients map[string]interfaces.Client, cfg *config
if s.mgmt != nil { if s.mgmt != nil {
s.mgmt.SetConfig(cfg) s.mgmt.SetConfig(cfg)
} }
log.Infof("server clients and configuration updated: %d clients", len(clientSlice))
// Count client types for detailed logging
authFiles := 0
glAPIKeyCount := 0
claudeAPIKeyCount := 0
codexAPIKeyCount := 0
openAICompatCount := 0
for _, c := range clientSlice {
switch cl := c.(type) {
case *client.GeminiCLIClient:
authFiles++
case *client.CodexClient:
if cl.GetAPIKey() == "" {
authFiles++
} else {
codexAPIKeyCount++
}
case *client.ClaudeClient:
if cl.GetAPIKey() == "" {
authFiles++
} else {
claudeAPIKeyCount++
}
case *client.QwenClient:
authFiles++
case *client.GeminiClient:
glAPIKeyCount++
case *client.OpenAICompatibilityClient:
openAICompatCount++
}
}
log.Infof("server clients and configuration updated: %d clients (%d auth files + %d GL API keys + %d Claude API keys + %d Codex keys + %d OpenAI-compat)",
len(clientSlice),
authFiles,
glAPIKeyCount,
claudeAPIKeyCount,
codexAPIKeyCount,
openAICompatCount,
)
} }
// (management handlers moved to internal/api/handlers/management) // (management handlers moved to internal/api/handlers/management)
+26 -3
View File
@@ -50,6 +50,7 @@ import (
func StartService(cfg *config.Config, configPath string) { func StartService(cfg *config.Config, configPath string) {
// Create a pool of API clients, one for each token file found. // Create a pool of API clients, one for each token file found.
cliClients := make(map[string]interfaces.Client) cliClients := make(map[string]interfaces.Client)
successfulAuthCount := 0
err := filepath.Walk(cfg.AuthDir, func(path string, info fs.FileInfo, err error) error { err := filepath.Walk(cfg.AuthDir, func(path string, info fs.FileInfo, err error) error {
if err != nil { if err != nil {
return err return err
@@ -89,6 +90,7 @@ func StartService(cfg *config.Config, configPath string) {
// Add the new client to the pool. // Add the new client to the pool.
cliClient := client.NewGeminiCLIClient(httpClient, &ts, cfg) cliClient := client.NewGeminiCLIClient(httpClient, &ts, cfg)
cliClients[path] = cliClient cliClients[path] = cliClient
successfulAuthCount++
} }
} else if tokenType == "codex" { } else if tokenType == "codex" {
var ts codex.CodexTokenStorage var ts codex.CodexTokenStorage
@@ -103,6 +105,7 @@ func StartService(cfg *config.Config, configPath string) {
} }
log.Info("Authentication successful.") log.Info("Authentication successful.")
cliClients[path] = codexClient cliClients[path] = codexClient
successfulAuthCount++
} }
} else if tokenType == "claude" { } else if tokenType == "claude" {
var ts claude.ClaudeTokenStorage var ts claude.ClaudeTokenStorage
@@ -112,6 +115,7 @@ func StartService(cfg *config.Config, configPath string) {
claudeClient := client.NewClaudeClient(cfg, &ts) claudeClient := client.NewClaudeClient(cfg, &ts)
log.Info("Authentication successful.") log.Info("Authentication successful.")
cliClients[path] = claudeClient cliClients[path] = claudeClient
successfulAuthCount++
} }
} else if tokenType == "qwen" { } else if tokenType == "qwen" {
var ts qwen.QwenTokenStorage var ts qwen.QwenTokenStorage
@@ -121,6 +125,7 @@ func StartService(cfg *config.Config, configPath string) {
qwenClient := client.NewQwenClient(cfg, &ts) qwenClient := client.NewQwenClient(cfg, &ts)
log.Info("Authentication successful.") log.Info("Authentication successful.")
cliClients[path] = qwenClient cliClients[path] = qwenClient
successfulAuthCount++
} }
} }
} }
@@ -130,7 +135,17 @@ func StartService(cfg *config.Config, configPath string) {
log.Fatalf("Error walking auth directory: %v", err) log.Fatalf("Error walking auth directory: %v", err)
} }
apiKeyClients := buildAPIKeyClients(cfg) apiKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount := buildAPIKeyClients(cfg)
totalNewClients := len(cliClients) + len(apiKeyClients)
log.Infof("full client load complete - %d clients (%d auth files + %d GL API keys + %d Claude API keys + %d Codex keys + %d OpenAI-compat)",
totalNewClients,
successfulAuthCount,
glAPIKeyCount,
claudeAPIKeyCount,
codexAPIKeyCount,
openAICompatCount,
)
// Combine file-based and API key-based clients for the initial server setup // Combine file-based and API key-based clients for the initial server setup
allClients := clientsToSlice(cliClients) allClients := clientsToSlice(cliClients)
@@ -283,8 +298,12 @@ func clientsToSlice(clientMap map[string]interfaces.Client) []interfaces.Client
} }
// buildAPIKeyClients creates clients from API keys in the config // buildAPIKeyClients creates clients from API keys in the config
func buildAPIKeyClients(cfg *config.Config) map[string]interfaces.Client { func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int, int, int, int) {
apiKeyClients := make(map[string]interfaces.Client) apiKeyClients := make(map[string]interfaces.Client)
glAPIKeyCount := 0
claudeAPIKeyCount := 0
codexAPIKeyCount := 0
openAICompatCount := 0
if len(cfg.GlAPIKey) > 0 { if len(cfg.GlAPIKey) > 0 {
for _, key := range cfg.GlAPIKey { for _, key := range cfg.GlAPIKey {
@@ -292,6 +311,7 @@ func buildAPIKeyClients(cfg *config.Config) map[string]interfaces.Client {
log.Debug("Initializing with Generative Language API Key...") log.Debug("Initializing with Generative Language API Key...")
cliClient := client.NewGeminiClient(httpClient, cfg, key) cliClient := client.NewGeminiClient(httpClient, cfg, key)
apiKeyClients[cliClient.GetClientID()] = cliClient apiKeyClients[cliClient.GetClientID()] = cliClient
glAPIKeyCount++
} }
} }
@@ -300,6 +320,7 @@ func buildAPIKeyClients(cfg *config.Config) map[string]interfaces.Client {
log.Debug("Initializing with Claude API Key...") log.Debug("Initializing with Claude API Key...")
cliClient := client.NewClaudeClientWithKey(cfg, i) cliClient := client.NewClaudeClientWithKey(cfg, i)
apiKeyClients[cliClient.GetClientID()] = cliClient apiKeyClients[cliClient.GetClientID()] = cliClient
claudeAPIKeyCount++
} }
} }
@@ -308,6 +329,7 @@ func buildAPIKeyClients(cfg *config.Config) map[string]interfaces.Client {
log.Debug("Initializing with Codex API Key...") log.Debug("Initializing with Codex API Key...")
cliClient := client.NewCodexClientWithKey(cfg, i) cliClient := client.NewCodexClientWithKey(cfg, i)
apiKeyClients[cliClient.GetClientID()] = cliClient apiKeyClients[cliClient.GetClientID()] = cliClient
codexAPIKeyCount++
} }
} }
@@ -320,8 +342,9 @@ func buildAPIKeyClients(cfg *config.Config) map[string]interfaces.Client {
continue continue
} }
apiKeyClients[compatClient.GetClientID()] = compatClient apiKeyClients[compatClient.GetClientID()] = compatClient
openAICompatCount++
} }
} }
return apiKeyClients return apiKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount
} }
+17 -5
View File
@@ -238,7 +238,7 @@ func (w *Watcher) reloadClients() {
} }
// Create new API key clients based on the new config // Create new API key clients based on the new config
newAPIKeyClients := buildAPIKeyClients(cfg) newAPIKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount := buildAPIKeyClients(cfg)
log.Debugf("created %d new API key clients", len(newAPIKeyClients)) log.Debugf("created %d new API key clients", len(newAPIKeyClients))
// Load file-based clients // Load file-based clients
@@ -269,11 +269,15 @@ func (w *Watcher) reloadClients() {
w.clientsMutex.Unlock() w.clientsMutex.Unlock()
totalNewClients := len(newFileClients) + len(newAPIKeyClients) totalNewClients := len(newFileClients) + len(newAPIKeyClients)
log.Infof("full client reload complete - old: %d clients, new: %d clients (%d auth files + %d API keys)",
log.Infof("full client reload complete - old: %d clients, new: %d clients (%d auth files + %d GL API keys + %d Claude API keys + %d Codex keys + %d OpenAI-compat)",
oldFileClientCount+oldAPIKeyClientCount, oldFileClientCount+oldAPIKeyClientCount,
totalNewClients, totalNewClients,
successfulAuthCount, successfulAuthCount,
len(newAPIKeyClients), glAPIKeyCount,
claudeAPIKeyCount,
codexAPIKeyCount,
openAICompatCount,
) )
// Trigger the callback to update the server // Trigger the callback to update the server
@@ -506,26 +510,33 @@ func (w *Watcher) loadFileClients(cfg *config.Config) (map[string]interfaces.Cli
} }
// buildAPIKeyClients creates clients from API keys in the config. // buildAPIKeyClients creates clients from API keys in the config.
func buildAPIKeyClients(cfg *config.Config) map[string]interfaces.Client { func buildAPIKeyClients(cfg *config.Config) (map[string]interfaces.Client, int, int, int, int) {
apiKeyClients := make(map[string]interfaces.Client) apiKeyClients := make(map[string]interfaces.Client)
glAPIKeyCount := 0
claudeAPIKeyCount := 0
codexAPIKeyCount := 0
openAICompatCount := 0
if len(cfg.GlAPIKey) > 0 { if len(cfg.GlAPIKey) > 0 {
for _, key := range cfg.GlAPIKey { for _, key := range cfg.GlAPIKey {
httpClient := util.SetProxy(cfg, &http.Client{}) httpClient := util.SetProxy(cfg, &http.Client{})
cliClient := client.NewGeminiClient(httpClient, cfg, key) cliClient := client.NewGeminiClient(httpClient, cfg, key)
apiKeyClients[cliClient.GetClientID()] = cliClient apiKeyClients[cliClient.GetClientID()] = cliClient
glAPIKeyCount++
} }
} }
if len(cfg.ClaudeKey) > 0 { if len(cfg.ClaudeKey) > 0 {
for i := range cfg.ClaudeKey { for i := range cfg.ClaudeKey {
cliClient := client.NewClaudeClientWithKey(cfg, i) cliClient := client.NewClaudeClientWithKey(cfg, i)
apiKeyClients[cliClient.GetClientID()] = cliClient apiKeyClients[cliClient.GetClientID()] = cliClient
claudeAPIKeyCount++
} }
} }
if len(cfg.CodexKey) > 0 { if len(cfg.CodexKey) > 0 {
for i := range cfg.CodexKey { for i := range cfg.CodexKey {
cliClient := client.NewCodexClientWithKey(cfg, i) cliClient := client.NewCodexClientWithKey(cfg, i)
apiKeyClients[cliClient.GetClientID()] = cliClient apiKeyClients[cliClient.GetClientID()] = cliClient
codexAPIKeyCount++
} }
} }
if len(cfg.OpenAICompatibility) > 0 { if len(cfg.OpenAICompatibility) > 0 {
@@ -536,7 +547,8 @@ func buildAPIKeyClients(cfg *config.Config) map[string]interfaces.Client {
continue continue
} }
apiKeyClients[compatClient.GetClientID()] = compatClient apiKeyClients[compatClient.GetClientID()] = compatClient
openAICompatCount++
} }
} }
return apiKeyClients return apiKeyClients, glAPIKeyCount, claudeAPIKeyCount, codexAPIKeyCount, openAICompatCount
} }