Fixed: #1711
fix(server): use resolved log directory for request logger initialization and test fallback logic
This commit is contained in:
@@ -59,10 +59,8 @@ type ServerOption func(*serverOptionConfig)
|
|||||||
|
|
||||||
func defaultRequestLoggerFactory(cfg *config.Config, configPath string) logging.RequestLogger {
|
func defaultRequestLoggerFactory(cfg *config.Config, configPath string) logging.RequestLogger {
|
||||||
configDir := filepath.Dir(configPath)
|
configDir := filepath.Dir(configPath)
|
||||||
if base := util.WritablePath(); base != "" {
|
logsDir := logging.ResolveLogDirectory(cfg)
|
||||||
return logging.NewFileRequestLogger(cfg.RequestLog, filepath.Join(base, "logs"), configDir, cfg.ErrorLogsMaxFiles)
|
return logging.NewFileRequestLogger(cfg.RequestLog, logsDir, configDir, cfg.ErrorLogsMaxFiles)
|
||||||
}
|
|
||||||
return logging.NewFileRequestLogger(cfg.RequestLog, "logs", configDir, cfg.ErrorLogsMaxFiles)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithMiddleware appends additional Gin middleware during server construction.
|
// WithMiddleware appends additional Gin middleware during server construction.
|
||||||
|
|||||||
@@ -7,9 +7,11 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
gin "github.com/gin-gonic/gin"
|
gin "github.com/gin-gonic/gin"
|
||||||
proxyconfig "github.com/router-for-me/CLIProxyAPI/v6/internal/config"
|
proxyconfig "github.com/router-for-me/CLIProxyAPI/v6/internal/config"
|
||||||
|
internallogging "github.com/router-for-me/CLIProxyAPI/v6/internal/logging"
|
||||||
sdkaccess "github.com/router-for-me/CLIProxyAPI/v6/sdk/access"
|
sdkaccess "github.com/router-for-me/CLIProxyAPI/v6/sdk/access"
|
||||||
"github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
|
"github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
|
||||||
sdkconfig "github.com/router-for-me/CLIProxyAPI/v6/sdk/config"
|
sdkconfig "github.com/router-for-me/CLIProxyAPI/v6/sdk/config"
|
||||||
@@ -109,3 +111,100 @@ func TestAmpProviderModelRoutes(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDefaultRequestLoggerFactory_UsesResolvedLogDirectory(t *testing.T) {
|
||||||
|
t.Setenv("WRITABLE_PATH", "")
|
||||||
|
t.Setenv("writable_path", "")
|
||||||
|
|
||||||
|
originalWD, errGetwd := os.Getwd()
|
||||||
|
if errGetwd != nil {
|
||||||
|
t.Fatalf("failed to get current working directory: %v", errGetwd)
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
if errChdir := os.Chdir(tmpDir); errChdir != nil {
|
||||||
|
t.Fatalf("failed to switch working directory: %v", errChdir)
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if errChdirBack := os.Chdir(originalWD); errChdirBack != nil {
|
||||||
|
t.Fatalf("failed to restore working directory: %v", errChdirBack)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Force ResolveLogDirectory to fallback to auth-dir/logs by making ./logs not a writable directory.
|
||||||
|
if errWriteFile := os.WriteFile(filepath.Join(tmpDir, "logs"), []byte("not-a-directory"), 0o644); errWriteFile != nil {
|
||||||
|
t.Fatalf("failed to create blocking logs file: %v", errWriteFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
configDir := filepath.Join(tmpDir, "config")
|
||||||
|
if errMkdirConfig := os.MkdirAll(configDir, 0o755); errMkdirConfig != nil {
|
||||||
|
t.Fatalf("failed to create config dir: %v", errMkdirConfig)
|
||||||
|
}
|
||||||
|
configPath := filepath.Join(configDir, "config.yaml")
|
||||||
|
|
||||||
|
authDir := filepath.Join(tmpDir, "auth")
|
||||||
|
if errMkdirAuth := os.MkdirAll(authDir, 0o700); errMkdirAuth != nil {
|
||||||
|
t.Fatalf("failed to create auth dir: %v", errMkdirAuth)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := &proxyconfig.Config{
|
||||||
|
SDKConfig: proxyconfig.SDKConfig{
|
||||||
|
RequestLog: false,
|
||||||
|
},
|
||||||
|
AuthDir: authDir,
|
||||||
|
ErrorLogsMaxFiles: 10,
|
||||||
|
}
|
||||||
|
|
||||||
|
logger := defaultRequestLoggerFactory(cfg, configPath)
|
||||||
|
fileLogger, ok := logger.(*internallogging.FileRequestLogger)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("expected *FileRequestLogger, got %T", logger)
|
||||||
|
}
|
||||||
|
|
||||||
|
errLog := fileLogger.LogRequestWithOptions(
|
||||||
|
"/v1/chat/completions",
|
||||||
|
http.MethodPost,
|
||||||
|
map[string][]string{"Content-Type": []string{"application/json"}},
|
||||||
|
[]byte(`{"input":"hello"}`),
|
||||||
|
http.StatusBadGateway,
|
||||||
|
map[string][]string{"Content-Type": []string{"application/json"}},
|
||||||
|
[]byte(`{"error":"upstream failure"}`),
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
true,
|
||||||
|
"issue-1711",
|
||||||
|
time.Now(),
|
||||||
|
time.Now(),
|
||||||
|
)
|
||||||
|
if errLog != nil {
|
||||||
|
t.Fatalf("failed to write forced error request log: %v", errLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
authLogsDir := filepath.Join(authDir, "logs")
|
||||||
|
authEntries, errReadAuthDir := os.ReadDir(authLogsDir)
|
||||||
|
if errReadAuthDir != nil {
|
||||||
|
t.Fatalf("failed to read auth logs dir %s: %v", authLogsDir, errReadAuthDir)
|
||||||
|
}
|
||||||
|
foundErrorLogInAuthDir := false
|
||||||
|
for _, entry := range authEntries {
|
||||||
|
if strings.HasPrefix(entry.Name(), "error-") && strings.HasSuffix(entry.Name(), ".log") {
|
||||||
|
foundErrorLogInAuthDir = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !foundErrorLogInAuthDir {
|
||||||
|
t.Fatalf("expected forced error log in auth fallback dir %s, got entries: %+v", authLogsDir, authEntries)
|
||||||
|
}
|
||||||
|
|
||||||
|
configLogsDir := filepath.Join(configDir, "logs")
|
||||||
|
configEntries, errReadConfigDir := os.ReadDir(configLogsDir)
|
||||||
|
if errReadConfigDir != nil && !os.IsNotExist(errReadConfigDir) {
|
||||||
|
t.Fatalf("failed to inspect config logs dir %s: %v", configLogsDir, errReadConfigDir)
|
||||||
|
}
|
||||||
|
for _, entry := range configEntries {
|
||||||
|
if strings.HasPrefix(entry.Name(), "error-") && strings.HasSuffix(entry.Name(), ".log") {
|
||||||
|
t.Fatalf("unexpected forced error log in config dir %s", configLogsDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user