package main import ( "context" "log" "net/http" "os" "os/signal" "syscall" "time" "gitea.sinav-lab.com/sinav/keenetic-exporter-v2/internal/app" "gitea.sinav-lab.com/sinav/keenetic-exporter-v2/internal/collector" "gitea.sinav-lab.com/sinav/keenetic-exporter-v2/internal/config" "gitea.sinav-lab.com/sinav/keenetic-exporter-v2/internal/device" ) func main() { // Загрузка конфигурации cfg, err := config.Load("config.yaml") if err != nil { log.Fatalf("Failed to load config: %v", err) } // Инициализация компонентов deviceManager := device.NewManager(cfg.Devices) collectorRegistry := collector.NewRegistry() // Регистрация коллекторов collectorRegistry.Register(collector.NewSystemCollector()) collectorRegistry.Register(collector.NewInterfaceCollector()) collectorRegistry.Register(collector.NewInternetCollector()) collectorRegistry.Register(collector.NewHotspotCollector()) collectorRegistry.Register(collector.NewInterfaceStatsCollector()) collectorRegistry.Register(collector.NewProcessCollector()) scrapeCoordinator := app.NewCoordinator(deviceManager, collectorRegistry) prometheusServer := app.NewPrometheusServer(cfg.Server.Port, scrapeCoordinator) // Запуск сервера ctx, cancel := context.WithCancel(context.Background()) defer cancel() go func() { if err := prometheusServer.Start(ctx); err != nil && err != http.ErrServerClosed { log.Fatalf("server failed: %v", err) } }() // Graceful shutdown sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) <-sigChan log.Println("shutting down...") cancel() // Stop all background updaters with timeout shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 10*time.Second) defer shutdownCancel() if err := deviceManager.Shutdown(shutdownCtx); err != nil { log.Printf("warning: shutdown error: %v", err) } log.Println("shutdown complete") }