Files
cacto 81040eec62 Добавлены метрики Prometheus и дашборды Grafana (этап 2.5)
Все три Go-сервиса (ingest, device-control, rule-engine) отдают
/metrics в формате Prometheus: счётчики MQTT/RabbitMQ/ClickHouse
операций, гистограммы длительности батч-флашей и диспатча правил,
переходы устройств online/offline. Добавлены сервисы prometheus и
grafana в docker-compose с провижининг конфигом (datasource +
два готовых дашборда: "Ingest & Telemetry" и "Automation & Devices").
2026-08-11 21:58:59 +05:00

97 lines
2.4 KiB
Go

// Package config loads ingest-service settings from environment variables,
// matching the names used in the repo-root .env.example.
package config
import (
"fmt"
"os"
"strconv"
"time"
)
type Config struct {
MQTTBrokerURL string
MQTTClientID string
MQTTTopic string
ClickHouseAddr string
ClickHouseDatabase string
ClickHouseUsername string
ClickHousePassword string
RabbitMQURL string
BatchMaxSize int
BatchFlushInterval time.Duration
BatchFlushTimeout time.Duration
MetricsPort int
}
func Load() (Config, error) {
cfg := Config{
MQTTBrokerURL: fmt.Sprintf("tcp://%s:%s", getEnv("MQTT_HOST", "localhost"), getEnv("MQTT_PORT", "1883")),
MQTTClientID: getEnv("INGEST_MQTT_CLIENT_ID", "ingest-service"),
MQTTTopic: getEnv("INGEST_MQTT_TOPIC", "devices/+/telemetry"),
ClickHouseAddr: fmt.Sprintf("%s:%s", getEnv("CLICKHOUSE_HOST", "localhost"), getEnv("CLICKHOUSE_NATIVE_PORT", "9000")),
ClickHouseDatabase: getEnv("CLICKHOUSE_DB", "telemetry"),
ClickHouseUsername: getEnv("CLICKHOUSE_USER", "default"),
ClickHousePassword: getEnv("CLICKHOUSE_PASSWORD", ""),
RabbitMQURL: fmt.Sprintf("amqp://%s:%s@%s:%s/",
getEnv("RABBITMQ_USER", "guest"),
getEnv("RABBITMQ_PASSWORD", "guest"),
getEnv("RABBITMQ_HOST", "localhost"),
getEnv("RABBITMQ_PORT", "5672"),
),
}
var err error
if cfg.BatchMaxSize, err = getEnvInt("INGEST_BATCH_MAX_SIZE", 500); err != nil {
return Config{}, err
}
if cfg.BatchFlushInterval, err = getEnvDuration("INGEST_BATCH_FLUSH_INTERVAL", 5*time.Second); err != nil {
return Config{}, err
}
if cfg.BatchFlushTimeout, err = getEnvDuration("INGEST_BATCH_FLUSH_TIMEOUT", 10*time.Second); err != nil {
return Config{}, err
}
if cfg.MetricsPort, err = getEnvInt("INGEST_METRICS_PORT", 9101); err != nil {
return Config{}, err
}
return cfg, nil
}
func getEnv(key, fallback string) string {
if v := os.Getenv(key); v != "" {
return v
}
return fallback
}
func getEnvInt(key string, fallback int) (int, error) {
v := os.Getenv(key)
if v == "" {
return fallback, nil
}
n, err := strconv.Atoi(v)
if err != nil {
return 0, fmt.Errorf("%s: %w", key, err)
}
return n, nil
}
func getEnvDuration(key string, fallback time.Duration) (time.Duration, error) {
v := os.Getenv(key)
if v == "" {
return fallback, nil
}
d, err := time.ParseDuration(v)
if err != nil {
return 0, fmt.Errorf("%s: %w", key, err)
}
return d, nil
}