fix(ccm): log assigned credential for each distinct model per session
This commit is contained in:
@@ -5,6 +5,8 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
boxService "github.com/sagernet/sing-box/adapter/service"
|
||||
@@ -163,10 +165,29 @@ type Service struct {
|
||||
allCredentials []Credential
|
||||
userConfigMap map[string]*option.CCMUser
|
||||
|
||||
sessionModelAccess sync.Mutex
|
||||
sessionModels map[sessionModelKey]time.Time
|
||||
|
||||
statusSubscriber *observable.Subscriber[struct{}]
|
||||
statusObserver *observable.Observer[struct{}]
|
||||
}
|
||||
|
||||
type sessionModelKey struct {
|
||||
sessionID string
|
||||
model string
|
||||
}
|
||||
|
||||
func (s *Service) cleanSessionModels() {
|
||||
now := time.Now()
|
||||
s.sessionModelAccess.Lock()
|
||||
for key, createdAt := range s.sessionModels {
|
||||
if now.Sub(createdAt) > sessionExpiry {
|
||||
delete(s.sessionModels, key)
|
||||
}
|
||||
}
|
||||
s.sessionModelAccess.Unlock()
|
||||
}
|
||||
|
||||
func NewService(ctx context.Context, logger log.ContextLogger, tag string, options option.CCMServiceOptions) (adapter.Service, error) {
|
||||
initCCMUserAgent(logger)
|
||||
|
||||
@@ -212,6 +233,7 @@ func NewService(ctx context.Context, logger log.ContextLogger, tag string, optio
|
||||
Listen: options.ListenOptions,
|
||||
}),
|
||||
userManager: userManager,
|
||||
sessionModels: make(map[sessionModelKey]time.Time),
|
||||
statusSubscriber: statusSubscriber,
|
||||
statusObserver: observable.NewObserver[struct{}](statusSubscriber, 8),
|
||||
}
|
||||
|
||||
@@ -218,6 +218,7 @@ func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
provider.pollIfStale()
|
||||
s.cleanSessionModels()
|
||||
|
||||
anthropicBetaHeader := r.Header.Get("anthropic-beta")
|
||||
if isFastModeRequest(anthropicBetaHeader) {
|
||||
@@ -235,7 +236,22 @@ func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
writeNonRetryableCredentialError(w, r, unavailableCredentialMessage(provider, err.Error()))
|
||||
return
|
||||
}
|
||||
if isNew {
|
||||
modelDisplay := requestModel
|
||||
if requestModel != "" && isExtendedContextRequest(anthropicBetaHeader) {
|
||||
modelDisplay += "[1m]"
|
||||
}
|
||||
isNewModel := false
|
||||
if sessionID != "" && modelDisplay != "" {
|
||||
key := sessionModelKey{sessionID, modelDisplay}
|
||||
s.sessionModelAccess.Lock()
|
||||
_, exists := s.sessionModels[key]
|
||||
if !exists {
|
||||
s.sessionModels[key] = time.Now()
|
||||
isNewModel = true
|
||||
}
|
||||
s.sessionModelAccess.Unlock()
|
||||
}
|
||||
if isNew || isNewModel {
|
||||
logParts := []any{"assigned credential ", selectedCredential.tagName()}
|
||||
if sessionID != "" {
|
||||
logParts = append(logParts, " for session ", sessionID)
|
||||
@@ -243,11 +259,7 @@ func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if username != "" {
|
||||
logParts = append(logParts, " by user ", username)
|
||||
}
|
||||
if requestModel != "" {
|
||||
modelDisplay := requestModel
|
||||
if isExtendedContextRequest(anthropicBetaHeader) {
|
||||
modelDisplay += "[1m]"
|
||||
}
|
||||
if modelDisplay != "" {
|
||||
logParts = append(logParts, ", model=", modelDisplay)
|
||||
}
|
||||
s.logger.DebugContext(ctx, logParts...)
|
||||
|
||||
Reference in New Issue
Block a user