231 lines
7.4 KiB
Go
231 lines
7.4 KiB
Go
// Package config provides configuration management for the application
|
|
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"gpt-load/internal/errors"
|
|
"gpt-load/internal/types"
|
|
"gpt-load/internal/utils"
|
|
|
|
"github.com/joho/godotenv"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// Constants represents configuration constants
|
|
type Constants struct {
|
|
MinPort int
|
|
MaxPort int
|
|
MinTimeout int
|
|
DefaultTimeout int
|
|
DefaultMaxSockets int
|
|
DefaultMaxFreeSockets int
|
|
}
|
|
|
|
// DefaultConstants holds default configuration values
|
|
var DefaultConstants = Constants{
|
|
MinPort: 1,
|
|
MaxPort: 65535,
|
|
MinTimeout: 1,
|
|
DefaultTimeout: 30,
|
|
DefaultMaxSockets: 50,
|
|
DefaultMaxFreeSockets: 10,
|
|
}
|
|
|
|
// Manager implements the ConfigManager interface
|
|
type Manager struct {
|
|
config *Config
|
|
settingsManager *SystemSettingsManager
|
|
}
|
|
|
|
// Config represents the application configuration
|
|
type Config struct {
|
|
Server types.ServerConfig `json:"server"`
|
|
Auth types.AuthConfig `json:"auth"`
|
|
CORS types.CORSConfig `json:"cors"`
|
|
Performance types.PerformanceConfig `json:"performance"`
|
|
Log types.LogConfig `json:"log"`
|
|
Database types.DatabaseConfig `json:"database"`
|
|
RedisDSN string `json:"redis_dsn"`
|
|
}
|
|
|
|
// NewManager creates a new configuration manager
|
|
func NewManager(settingsManager *SystemSettingsManager) (types.ConfigManager, error) {
|
|
manager := &Manager{
|
|
settingsManager: settingsManager,
|
|
}
|
|
if err := manager.ReloadConfig(); err != nil {
|
|
return nil, err
|
|
}
|
|
return manager, nil
|
|
}
|
|
|
|
// ReloadConfig reloads the configuration from environment variables
|
|
func (m *Manager) ReloadConfig() error {
|
|
if err := godotenv.Load(); err != nil {
|
|
logrus.Info("Info: Create .env file to support environment variable configuration")
|
|
}
|
|
|
|
config := &Config{
|
|
Server: types.ServerConfig{
|
|
Port: utils.ParseInteger(os.Getenv("PORT"), 3000),
|
|
Host: utils.GetEnvOrDefault("HOST", "0.0.0.0"),
|
|
ReadTimeout: utils.ParseInteger(os.Getenv("SERVER_READ_TIMEOUT"), 120),
|
|
WriteTimeout: utils.ParseInteger(os.Getenv("SERVER_WRITE_TIMEOUT"), 1800),
|
|
IdleTimeout: utils.ParseInteger(os.Getenv("SERVER_IDLE_TIMEOUT"), 120),
|
|
GracefulShutdownTimeout: utils.ParseInteger(os.Getenv("SERVER_GRACEFUL_SHUTDOWN_TIMEOUT"), 60),
|
|
},
|
|
Auth: types.AuthConfig{
|
|
Key: os.Getenv("AUTH_KEY"),
|
|
},
|
|
CORS: types.CORSConfig{
|
|
Enabled: utils.ParseBoolean(os.Getenv("ENABLE_CORS"), true),
|
|
AllowedOrigins: utils.ParseArray(os.Getenv("ALLOWED_ORIGINS"), []string{"*"}),
|
|
AllowedMethods: utils.ParseArray(os.Getenv("ALLOWED_METHODS"), []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}),
|
|
AllowedHeaders: utils.ParseArray(os.Getenv("ALLOWED_HEADERS"), []string{"*"}),
|
|
AllowCredentials: utils.ParseBoolean(os.Getenv("ALLOW_CREDENTIALS"), false),
|
|
},
|
|
Performance: types.PerformanceConfig{
|
|
MaxConcurrentRequests: utils.ParseInteger(os.Getenv("MAX_CONCURRENT_REQUESTS"), 100),
|
|
},
|
|
Log: types.LogConfig{
|
|
Level: utils.GetEnvOrDefault("LOG_LEVEL", "info"),
|
|
Format: utils.GetEnvOrDefault("LOG_FORMAT", "text"),
|
|
EnableFile: utils.ParseBoolean(os.Getenv("LOG_ENABLE_FILE"), false),
|
|
FilePath: utils.GetEnvOrDefault("LOG_FILE_PATH", "logs/app.log"),
|
|
},
|
|
Database: types.DatabaseConfig{
|
|
DSN: os.Getenv("DATABASE_DSN"),
|
|
},
|
|
RedisDSN: os.Getenv("REDIS_DSN"),
|
|
}
|
|
m.config = config
|
|
|
|
// Validate configuration
|
|
if err := m.Validate(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetAuthConfig returns authentication configuration
|
|
func (m *Manager) GetAuthConfig() types.AuthConfig {
|
|
return m.config.Auth
|
|
}
|
|
|
|
// GetCORSConfig returns CORS configuration
|
|
func (m *Manager) GetCORSConfig() types.CORSConfig {
|
|
return m.config.CORS
|
|
}
|
|
|
|
// GetPerformanceConfig returns performance configuration
|
|
func (m *Manager) GetPerformanceConfig() types.PerformanceConfig {
|
|
return m.config.Performance
|
|
}
|
|
|
|
// GetLogConfig returns logging configuration
|
|
func (m *Manager) GetLogConfig() types.LogConfig {
|
|
return m.config.Log
|
|
}
|
|
|
|
// GetRedisDSN returns the Redis DSN string.
|
|
func (m *Manager) GetRedisDSN() string {
|
|
return m.config.RedisDSN
|
|
}
|
|
|
|
// GetDatabaseConfig returns the database configuration.
|
|
func (m *Manager) GetDatabaseConfig() types.DatabaseConfig {
|
|
return m.config.Database
|
|
}
|
|
|
|
// GetEffectiveServerConfig returns server configuration merged with system settings
|
|
func (m *Manager) GetEffectiveServerConfig() types.ServerConfig {
|
|
return m.config.Server
|
|
}
|
|
|
|
// Validate validates the configuration
|
|
func (m *Manager) Validate() error {
|
|
var validationErrors []string
|
|
|
|
// Validate port
|
|
if m.config.Server.Port < DefaultConstants.MinPort || m.config.Server.Port > DefaultConstants.MaxPort {
|
|
validationErrors = append(validationErrors, fmt.Sprintf("port must be between %d-%d", DefaultConstants.MinPort, DefaultConstants.MaxPort))
|
|
}
|
|
|
|
if m.config.Performance.MaxConcurrentRequests < 1 {
|
|
validationErrors = append(validationErrors, "max concurrent requests cannot be less than 1")
|
|
}
|
|
|
|
// Validate auth key
|
|
if m.config.Auth.Key == "" {
|
|
validationErrors = append(validationErrors, "AUTH_KEY is required and cannot be empty")
|
|
}
|
|
|
|
// Validate GracefulShutdownTimeout and reset if necessary
|
|
if m.config.Server.GracefulShutdownTimeout < 10 {
|
|
logrus.Warnf("SERVER_GRACEFUL_SHUTDOWN_TIMEOUT value %ds is too short, resetting to minimum 10s.", m.config.Server.GracefulShutdownTimeout)
|
|
m.config.Server.GracefulShutdownTimeout = 10
|
|
}
|
|
|
|
if len(validationErrors) > 0 {
|
|
logrus.Error("Configuration validation failed:")
|
|
for _, err := range validationErrors {
|
|
logrus.Errorf(" - %s", err)
|
|
}
|
|
return errors.NewAPIError(errors.ErrValidation, strings.Join(validationErrors, "; "))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// DisplayServerConfig displays current server-related configuration information
|
|
func (m *Manager) DisplayServerConfig() {
|
|
serverConfig := m.GetEffectiveServerConfig()
|
|
corsConfig := m.GetCORSConfig()
|
|
perfConfig := m.GetPerformanceConfig()
|
|
logConfig := m.GetLogConfig()
|
|
dbConfig := m.GetDatabaseConfig()
|
|
|
|
logrus.Info("--- Server Configuration ---")
|
|
logrus.Infof(" Listen Address: %s:%d", serverConfig.Host, serverConfig.Port)
|
|
logrus.Infof(" Graceful Shutdown Timeout: %d seconds", serverConfig.GracefulShutdownTimeout)
|
|
logrus.Infof(" Read Timeout: %d seconds", serverConfig.ReadTimeout)
|
|
logrus.Infof(" Write Timeout: %d seconds", serverConfig.WriteTimeout)
|
|
logrus.Infof(" Idle Timeout: %d seconds", serverConfig.IdleTimeout)
|
|
|
|
logrus.Info("--- Performance ---")
|
|
logrus.Infof(" Max Concurrent Requests: %d", perfConfig.MaxConcurrentRequests)
|
|
|
|
logrus.Info("--- Security ---")
|
|
logrus.Infof(" Authentication: enabled (key loaded)")
|
|
corsStatus := "disabled"
|
|
if corsConfig.Enabled {
|
|
corsStatus = fmt.Sprintf("enabled (Origins: %s)", strings.Join(corsConfig.AllowedOrigins, ", "))
|
|
}
|
|
logrus.Infof(" CORS: %s", corsStatus)
|
|
|
|
logrus.Info("--- Logging ---")
|
|
logrus.Infof(" Log Level: %s", logConfig.Level)
|
|
logrus.Infof(" Log Format: %s", logConfig.Format)
|
|
logrus.Infof(" File Logging: %t", logConfig.EnableFile)
|
|
if logConfig.EnableFile {
|
|
logrus.Infof(" Log File Path: %s", logConfig.FilePath)
|
|
}
|
|
|
|
logrus.Info("--- Dependencies ---")
|
|
if dbConfig.DSN != "" {
|
|
logrus.Info(" Database: configured")
|
|
} else {
|
|
logrus.Info(" Database: not configured")
|
|
}
|
|
if m.config.RedisDSN != "" {
|
|
logrus.Info(" Redis: configured")
|
|
} else {
|
|
logrus.Info(" Redis: not configured")
|
|
}
|
|
logrus.Info("--------------------------")
|
|
}
|