// Package config loads runtime configuration from environment variables. // // All env vars are prefixed with INGEST_ except shared infra ones // (POSTGRES_DSN, REDIS_ADDR, KAFKA_BROKERS). package config import ( "fmt" "time" "github.com/caarlos0/env/v11" ) type Config struct { HTTPAddr string `env:"INGEST_HTTP_ADDR" envDefault:":3049"` LogLevel string `env:"INGEST_LOG_LEVEL" envDefault:"info"` PayloadLimitKB int `env:"INGEST_PAYLOAD_LIMIT_KB" envDefault:"100"` BatchLimitKB int `env:"INGEST_BATCH_LIMIT_KB" envDefault:"4000"` LateEventHours int `env:"INGEST_LATE_EVENT_HOURS" envDefault:"24"` DedupTTLHours int `env:"INGEST_DEDUP_TTL_HOURS" envDefault:"24"` WriteKeyCacheTTL time.Duration `env:"INGEST_WRITE_KEY_CACHE_TTL_SECONDS" envDefault:"45s"` ShutdownTimeout time.Duration `env:"INGEST_SHUTDOWN_TIMEOUT_SECONDS" envDefault:"30s"` LogPayloadOnSuccess bool `env:"INGEST_LOG_PAYLOAD_ON_SUCCESS" envDefault:"false"` LogPayloadOnError bool `env:"INGEST_LOG_PAYLOAD_ON_ERROR" envDefault:"true"` // RateLimitRPS caps requests per workspace per second. 0 disables the // limiter entirely (use for load tests; never in production). RateLimitRPS int `env:"INGEST_RATE_LIMIT_RPS" envDefault:"100"` PostgresDSN string `env:"POSTGRES_DSN,required"` RedisAddr string `env:"REDIS_ADDR" envDefault:"localhost:6379"` KafkaBrokers []string `env:"KAFKA_BROKERS" envSeparator:"," envDefault:"localhost:9092"` KafkaTopicIngest string `env:"KAFKA_TOPIC_INGEST" envDefault:"events.ingest"` KafkaTopicDLQ string `env:"KAFKA_TOPIC_DLQ" envDefault:"events.dlq"` KafkaTopicRetry string `env:"KAFKA_TOPIC_RETRY" envDefault:"events.retry"` } func Load() (*Config, error) { cfg := &Config{} if err := env.Parse(cfg); err != nil { return nil, fmt.Errorf("config load: %w", err) } return cfg, nil }