Logging auf console eingebaut
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Config enthält alle Anwendungskonfigurationen
|
||||
type Config struct {
|
||||
// Server Konfiguration
|
||||
ServerPort string
|
||||
|
||||
// Database Konfiguration
|
||||
DatabaseURL string
|
||||
|
||||
// Logging Konfiguration
|
||||
DebugMode bool
|
||||
LogLevel string
|
||||
|
||||
// Environment
|
||||
Environment string
|
||||
}
|
||||
|
||||
// defaultConfig gibt die Standard-Konfiguration zurück
|
||||
func defaultConfig() *Config {
|
||||
return &Config{
|
||||
ServerPort: "8180",
|
||||
DatabaseURL: "",
|
||||
DebugMode: false,
|
||||
LogLevel: "INFO",
|
||||
Environment: "production",
|
||||
}
|
||||
}
|
||||
|
||||
// LoadConfig lädt die Konfiguration aus Umgebungsvariablen
|
||||
func LoadConfig() *Config {
|
||||
// Lade .env-Datei falls vorhanden
|
||||
loadEnvFile()
|
||||
|
||||
config := defaultConfig()
|
||||
|
||||
// Server Port
|
||||
if port := os.Getenv("PORT"); port != "" {
|
||||
config.ServerPort = port
|
||||
}
|
||||
if port := os.Getenv("SERVER_PORT"); port != "" {
|
||||
config.ServerPort = port
|
||||
}
|
||||
|
||||
// Database
|
||||
if dbURL := os.Getenv("DATABASE_URL"); dbURL != "" {
|
||||
config.DatabaseURL = dbURL
|
||||
}
|
||||
|
||||
// Debug Mode
|
||||
if debug := os.Getenv("DEBUG"); debug != "" {
|
||||
config.DebugMode = strings.ToLower(debug) == "true" || debug == "1"
|
||||
}
|
||||
|
||||
// Log Level
|
||||
if logLevel := os.Getenv("LOG_LEVEL"); logLevel != "" {
|
||||
config.LogLevel = strings.ToUpper(logLevel)
|
||||
}
|
||||
|
||||
// Environment
|
||||
if env := os.Getenv("ENVIRONMENT"); env != "" {
|
||||
config.Environment = strings.ToLower(env)
|
||||
}
|
||||
if env := os.Getenv("GO_ENV"); env != "" {
|
||||
config.Environment = strings.ToLower(env)
|
||||
}
|
||||
|
||||
// Automatisch Debug-Modus für Development-Environment aktivieren
|
||||
if config.Environment == "development" || config.Environment == "dev" {
|
||||
config.DebugMode = true
|
||||
if config.LogLevel == "INFO" {
|
||||
config.LogLevel = "DEBUG"
|
||||
}
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
// loadEnvFile lädt eine .env-Datei falls vorhanden
|
||||
func loadEnvFile() {
|
||||
envFiles := []string{".env", ".env.local"}
|
||||
|
||||
for _, envFile := range envFiles {
|
||||
if _, err := os.Stat(envFile); err == nil {
|
||||
loadEnvFileContent(envFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// loadEnvFileContent lädt den Inhalt einer .env-Datei
|
||||
func loadEnvFileContent(filename string) {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
|
||||
// Überspringe leere Zeilen und Kommentare
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
|
||||
// Teile die Zeile in Key=Value auf
|
||||
parts := strings.SplitN(line, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
key := strings.TrimSpace(parts[0])
|
||||
value := strings.TrimSpace(parts[1])
|
||||
|
||||
// Entferne Anführungszeichen falls vorhanden
|
||||
value = strings.Trim(value, `"'`)
|
||||
|
||||
// Setze die Umgebungsvariable nur, wenn sie noch nicht gesetzt ist
|
||||
if os.Getenv(key) == "" {
|
||||
os.Setenv(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IsDevelopment prüft, ob die Anwendung im Development-Modus läuft
|
||||
func (c *Config) IsDevelopment() bool {
|
||||
return c.Environment == "development" || c.Environment == "dev"
|
||||
}
|
||||
|
||||
// IsProduction prüft, ob die Anwendung im Production-Modus läuft
|
||||
func (c *Config) IsProduction() bool {
|
||||
return c.Environment == "production" || c.Environment == "prod"
|
||||
}
|
||||
|
||||
// GetServerAddress gibt die vollständige Server-Adresse zurück
|
||||
func (c *Config) GetServerAddress() string {
|
||||
return ":" + c.ServerPort
|
||||
}
|
||||
|
||||
// GetBoolEnv ist eine Hilfsfunktion zum Laden von Boolean-Umgebungsvariablen
|
||||
func GetBoolEnv(key string, defaultValue bool) bool {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
if parsed, err := strconv.ParseBool(value); err == nil {
|
||||
return parsed
|
||||
}
|
||||
return strings.ToLower(value) == "true" || value == "1"
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// GetIntEnv ist eine Hilfsfunktion zum Laden von Integer-Umgebungsvariablen
|
||||
func GetIntEnv(key string, defaultValue int) int {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
if parsed, err := strconv.Atoi(value); err == nil {
|
||||
return parsed
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLoadEnvFile(t *testing.T) {
|
||||
// Test-Datei erstellen
|
||||
envContent := `# Test .env file
|
||||
DEBUG=true
|
||||
LOG_LEVEL=DEBUG
|
||||
PORT=9999
|
||||
# Comment line should be ignored
|
||||
|
||||
ENVIRONMENT=test
|
||||
DATABASE_URL="postgresql://test:test@localhost:5432/test"
|
||||
QUOTED_VALUE='single quotes'
|
||||
`
|
||||
|
||||
// Temporäre .env-Datei erstellen
|
||||
err := os.WriteFile(".env.test", []byte(envContent), 0644)
|
||||
if err != nil {
|
||||
t.Fatalf("Fehler beim Erstellen der Test-.env-Datei: %v", err)
|
||||
}
|
||||
defer os.Remove(".env.test")
|
||||
|
||||
// Ursprüngliche Umgebungsvariablen sichern
|
||||
originalDebug := os.Getenv("DEBUG")
|
||||
originalLogLevel := os.Getenv("LOG_LEVEL")
|
||||
originalPort := os.Getenv("PORT")
|
||||
originalEnv := os.Getenv("ENVIRONMENT")
|
||||
originalDB := os.Getenv("DATABASE_URL")
|
||||
originalQuoted := os.Getenv("QUOTED_VALUE")
|
||||
|
||||
// Umgebungsvariablen zurücksetzen
|
||||
os.Unsetenv("DEBUG")
|
||||
os.Unsetenv("LOG_LEVEL")
|
||||
os.Unsetenv("PORT")
|
||||
os.Unsetenv("ENVIRONMENT")
|
||||
os.Unsetenv("DATABASE_URL")
|
||||
os.Unsetenv("QUOTED_VALUE")
|
||||
|
||||
// Test-Datei laden
|
||||
loadEnvFileContent(".env.test")
|
||||
|
||||
// Tests
|
||||
tests := []struct {
|
||||
key string
|
||||
expected string
|
||||
}{
|
||||
{"DEBUG", "true"},
|
||||
{"LOG_LEVEL", "DEBUG"},
|
||||
{"PORT", "9999"},
|
||||
{"ENVIRONMENT", "test"},
|
||||
{"DATABASE_URL", "postgresql://test:test@localhost:5432/test"},
|
||||
{"QUOTED_VALUE", "single quotes"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
if value := os.Getenv(test.key); value != test.expected {
|
||||
t.Errorf("Für %s: erwartet '%s', erhalten '%s'", test.key, test.expected, value)
|
||||
}
|
||||
}
|
||||
|
||||
// Ursprüngliche Werte wiederherstellen
|
||||
if originalDebug != "" {
|
||||
os.Setenv("DEBUG", originalDebug)
|
||||
} else {
|
||||
os.Unsetenv("DEBUG")
|
||||
}
|
||||
if originalLogLevel != "" {
|
||||
os.Setenv("LOG_LEVEL", originalLogLevel)
|
||||
} else {
|
||||
os.Unsetenv("LOG_LEVEL")
|
||||
}
|
||||
if originalPort != "" {
|
||||
os.Setenv("PORT", originalPort)
|
||||
} else {
|
||||
os.Unsetenv("PORT")
|
||||
}
|
||||
if originalEnv != "" {
|
||||
os.Setenv("ENVIRONMENT", originalEnv)
|
||||
} else {
|
||||
os.Unsetenv("ENVIRONMENT")
|
||||
}
|
||||
if originalDB != "" {
|
||||
os.Setenv("DATABASE_URL", originalDB)
|
||||
} else {
|
||||
os.Unsetenv("DATABASE_URL")
|
||||
}
|
||||
if originalQuoted != "" {
|
||||
os.Setenv("QUOTED_VALUE", originalQuoted)
|
||||
} else {
|
||||
os.Unsetenv("QUOTED_VALUE")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnvVariablesPrecedence(t *testing.T) {
|
||||
// Test, dass bereits gesetzte Umgebungsvariablen Vorrang haben
|
||||
envContent := `DEBUG=false
|
||||
LOG_LEVEL=ERROR`
|
||||
|
||||
// Temporäre .env-Datei erstellen
|
||||
err := os.WriteFile(".env.precedence", []byte(envContent), 0644)
|
||||
if err != nil {
|
||||
t.Fatalf("Fehler beim Erstellen der Test-.env-Datei: %v", err)
|
||||
}
|
||||
defer os.Remove(".env.precedence")
|
||||
|
||||
// Umgebungsvariable vorher setzen
|
||||
os.Setenv("DEBUG", "true")
|
||||
os.Setenv("LOG_LEVEL", "INFO")
|
||||
|
||||
// .env-Datei laden
|
||||
loadEnvFileContent(".env.precedence")
|
||||
|
||||
// Tests - bereits gesetzte Werte sollten nicht überschrieben werden
|
||||
if debug := os.Getenv("DEBUG"); debug != "true" {
|
||||
t.Errorf("DEBUG sollte 'true' bleiben, aber ist '%s'", debug)
|
||||
}
|
||||
|
||||
if logLevel := os.Getenv("LOG_LEVEL"); logLevel != "INFO" {
|
||||
t.Errorf("LOG_LEVEL sollte 'INFO' bleiben, aber ist '%s'", logLevel)
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
os.Unsetenv("DEBUG")
|
||||
os.Unsetenv("LOG_LEVEL")
|
||||
}
|
||||
|
||||
func TestLoadConfigWithEnvFile(t *testing.T) {
|
||||
// Test-Konfiguration mit .env-Datei
|
||||
envContent := `ENVIRONMENT=development
|
||||
DEBUG=true
|
||||
LOG_LEVEL=DEBUG
|
||||
PORT=7777
|
||||
DATABASE_URL=test://localhost/testdb`
|
||||
|
||||
// Temporäre .env-Datei erstellen
|
||||
err := os.WriteFile(".env", []byte(envContent), 0644)
|
||||
if err != nil {
|
||||
t.Fatalf("Fehler beim Erstellen der .env-Datei: %v", err)
|
||||
}
|
||||
defer os.Remove(".env")
|
||||
|
||||
// Alle relevanten Umgebungsvariablen zurücksetzen
|
||||
originalVars := map[string]string{
|
||||
"ENVIRONMENT": os.Getenv("ENVIRONMENT"),
|
||||
"DEBUG": os.Getenv("DEBUG"),
|
||||
"LOG_LEVEL": os.Getenv("LOG_LEVEL"),
|
||||
"PORT": os.Getenv("PORT"),
|
||||
"DATABASE_URL": os.Getenv("DATABASE_URL"),
|
||||
}
|
||||
|
||||
for key := range originalVars {
|
||||
os.Unsetenv(key)
|
||||
}
|
||||
|
||||
// Konfiguration laden
|
||||
config := LoadConfig()
|
||||
|
||||
// Tests
|
||||
if config.Environment != "development" {
|
||||
t.Errorf("Environment: erwartet 'development', erhalten '%s'", config.Environment)
|
||||
}
|
||||
|
||||
if !config.DebugMode {
|
||||
t.Error("DebugMode sollte true sein")
|
||||
}
|
||||
|
||||
if config.LogLevel != "DEBUG" {
|
||||
t.Errorf("LogLevel: erwartet 'DEBUG', erhalten '%s'", config.LogLevel)
|
||||
}
|
||||
|
||||
if config.ServerPort != "7777" {
|
||||
t.Errorf("ServerPort: erwartet '7777', erhalten '%s'", config.ServerPort)
|
||||
}
|
||||
|
||||
if config.DatabaseURL != "test://localhost/testdb" {
|
||||
t.Errorf("DatabaseURL: erwartet 'test://localhost/testdb', erhalten '%s'", config.DatabaseURL)
|
||||
}
|
||||
|
||||
// Ursprüngliche Werte wiederherstellen
|
||||
for key, value := range originalVars {
|
||||
if value != "" {
|
||||
os.Setenv(key, value)
|
||||
} else {
|
||||
os.Unsetenv(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user