Порядок инициализации конфигов: конфиг файл, .env, параметры командной строки
Инициализация конфигурации из нескольких источников (.env
, параметры командной строки, config.yaml
) — это распространённая задача в Go. Принципиальный порядок инициализации часто следующий:
Порядок приоритетов:
- Параметры командной строки (
flag
):- Самый высокий приоритет, так как это явный ввод пользователя.
- Переменные окружения (например, через
.env
):- Средний приоритет, удобно для управления конфигурацией на уровне среды.
- Файл конфигурации (
config.yaml
):- Самый низкий приоритет, используется для базовых настроек.
Этот порядок обеспечивает гибкость: дефолтные значения задаются в файле, могут быть переопределены через .env
, а финальная настройка — через аргументы командной строки.
Пример реализации на Go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
package main import ( "flag" "fmt" "log" "os" "github.com/joho/godotenv" "gopkg.in/yaml.v3" ) // Config структура для конфигурации type Config struct { Host string `yaml:"host"` Port int `yaml:"port"` DbName string `yaml:"db_name"` ApiKey string `yaml:"api_key"` LogLevel string `yaml:"log_level"` } // LoadConfig загружает конфигурацию из всех источников func LoadConfig(configPath string) Config { // 1. Загрузка значений по умолчанию (из файла YAML) config := Config{ Host: "localhost", Port: 8080, DbName: "default_db", ApiKey: "", LogLevel: "info", } // Читаем из config.yaml file, err := os.Open(configPath) if err == nil { defer file.Close() decoder := yaml.NewDecoder(file) if decodeErr := decoder.Decode(&config); decodeErr != nil { log.Fatalf("Ошибка при чтении config.yaml: %v", decodeErr) } } else { log.Printf("config.yaml не найден, используются значения по умолчанию: %v", err) } // 2. Загрузка переменных окружения из .env err = godotenv.Load() if err != nil { log.Printf(".env файл не найден: %v", err) } // Переопределяем значения из переменных окружения if envHost := os.Getenv("HOST"); envHost != "" { config.Host = envHost } if envPort := os.Getenv("PORT"); envPort != "" { fmt.Sscanf(envPort, "%d", &config.Port) } if envDbName := os.Getenv("DB_NAME"); envDbName != "" { config.DbName = envDbName } if envApiKey := os.Getenv("API_KEY"); envApiKey != "" { config.ApiKey = envApiKey } if envLogLevel := os.Getenv("LOG_LEVEL"); envLogLevel != "" { config.LogLevel = envLogLevel } // 3. Чтение параметров командной строки host := flag.String("host", config.Host, "Хост для подключения") port := flag.Int("port", config.Port, "Порт для подключения") dbName := flag.String("db_name", config.DbName, "Имя базы данных") apiKey := flag.String("api_key", config.ApiKey, "Ключ API") logLevel := flag.String("log_level", config.LogLevel, "Уровень логирования") flag.Parse() // Переопределяем значения из флагов config.Host = *host config.Port = *port config.DbName = *dbName config.ApiKey = *apiKey config.LogLevel = *logLevel return config } func main() { // Загружаем конфигурацию config := LoadConfig("config.yaml") // Используем конфигурацию fmt.Printf("Конфигурация: %+v\n", config) } |
Объяснение кода:
- Значения по умолчанию:
- Устанавливаются при инициализации структуры
Config
.
- Устанавливаются при инициализации структуры
- Чтение
config.yaml
:- Открывается файл
config.yaml
, значения из него заполняют структуруConfig
.
- Открывается файл
- Загрузка переменных окружения из
.env
:- Используется библиотека
joho/godotenv
для загрузки переменных из.env
. - Переменные окружения переопределяют значения из
config.yaml
.
- Используется библиотека
- Параметры командной строки:
- Используется стандартная библиотека
flag
. - Значения флагов командной строки переопределяют все предыдущие.
- Используется стандартная библиотека
Пример работы:
1. Файл config.yaml
:
1 2 3 4 5 6 |
host: "example.com" port: 8081 db_name: "my_db" api_key: "default-api-key" log_level: "debug" |
.env
:
1 2 3 4 |
HOST=env-example.com PORT=9090 LOG_LEVEL=warn |
1 2 |
go run main.go -db_name=custom_db -api_key=cli-api-key |
1 2 |
Конфигурация: {Host:env-example.com Port:9090 DbName:custom_db ApiKey:cli-api-key LogLevel:warn} |
Резюме
- Файл
config.yaml
задаёт базовую конфигурацию. .env
переопределяет значения для среды.- Параметры командной строки имеют наивысший приоритет.
- Такой подход обеспечивает гибкость и простоту настройки для разработки и эксплуатации.
Recommended Posts
Golang Sarama: настройка Partitioner
20.03.2024