Files
ProxyPool/internal/config/config.go
2026-01-31 22:53:12 +08:00

146 lines
3.3 KiB
Go

package config
import (
"os"
"strconv"
"time"
)
// Config 应用配置
type Config struct {
DatabaseURL string
ListenAddr string
APIKey string
ReturnSecret bool
MaxConcurrency int
MaxTestLimit int
LeaseTTL time.Duration
// Telegram Bot 配置
TelegramBotToken string
TelegramAdminIDs []int64
TelegramNotifyChatID string
TelegramTestIntervalMin int
TelegramAlertThreshold int
TelegramTestURL string
TelegramTestTimeoutMs int
}
// Load 从环境变量加载配置
func Load() *Config {
cfg := &Config{
DatabaseURL: getEnv("DATABASE_URL", "postgres://postgres:postgres@localhost:5432/proxyrotator?sslmode=disable"),
ListenAddr: getEnv("LISTEN_ADDR", ":8080"),
APIKey: getEnv("API_KEY", ""),
ReturnSecret: getEnvBool("RETURN_SECRET", true),
MaxConcurrency: getEnvInt("MAX_CONCURRENCY", 200),
MaxTestLimit: getEnvInt("MAX_TEST_LIMIT", 2000),
LeaseTTL: getEnvDuration("LEASE_TTL", 60*time.Second),
// Telegram
TelegramBotToken: getEnv("TELEGRAM_BOT_TOKEN", ""),
TelegramAdminIDs: getEnvInt64Slice("TELEGRAM_ADMIN_IDS", nil),
TelegramNotifyChatID: getEnv("TELEGRAM_NOTIFY_CHAT_ID", ""),
TelegramTestIntervalMin: getEnvInt("TELEGRAM_TEST_INTERVAL_MIN", 60),
TelegramAlertThreshold: getEnvInt("TELEGRAM_ALERT_THRESHOLD", 50),
TelegramTestURL: getEnv("TELEGRAM_TEST_URL", "https://httpbin.org/ip"),
TelegramTestTimeoutMs: getEnvInt("TELEGRAM_TEST_TIMEOUT_MS", 5000),
}
return cfg
}
func getEnv(key, defaultValue string) string {
if v := os.Getenv(key); v != "" {
return v
}
return defaultValue
}
func getEnvBool(key string, defaultValue bool) bool {
if v := os.Getenv(key); v != "" {
b, err := strconv.ParseBool(v)
if err == nil {
return b
}
}
return defaultValue
}
func getEnvInt(key string, defaultValue int) int {
if v := os.Getenv(key); v != "" {
i, err := strconv.Atoi(v)
if err == nil {
return i
}
}
return defaultValue
}
func getEnvDuration(key string, defaultValue time.Duration) time.Duration {
if v := os.Getenv(key); v != "" {
d, err := time.ParseDuration(v)
if err == nil {
return d
}
}
return defaultValue
}
func getEnvInt64Slice(key string, defaultValue []int64) []int64 {
v := os.Getenv(key)
if v == "" {
return defaultValue
}
parts := splitAndTrim(v, ",")
result := make([]int64, 0, len(parts))
for _, p := range parts {
if p == "" {
continue
}
i, err := strconv.ParseInt(p, 10, 64)
if err == nil {
result = append(result, i)
}
}
return result
}
func splitAndTrim(s, sep string) []string {
parts := make([]string, 0)
for _, p := range stringsSplit(s, sep) {
p = stringsTrim(p)
if p != "" {
parts = append(parts, p)
}
}
return parts
}
func stringsSplit(s, sep string) []string {
if s == "" {
return nil
}
result := make([]string, 0)
start := 0
for i := 0; i < len(s); i++ {
if i+len(sep) <= len(s) && s[i:i+len(sep)] == sep {
result = append(result, s[start:i])
start = i + len(sep)
i += len(sep) - 1
}
}
result = append(result, s[start:])
return result
}
func stringsTrim(s string) string {
start, end := 0, len(s)
for start < end && (s[start] == ' ' || s[start] == '\t') {
start++
}
for end > start && (s[end-1] == ' ' || s[end-1] == '\t') {
end--
}
return s[start:end]
}