package main import ( "context" "log/slog" "os" "os/signal" "syscall" "git.daviestechlabs.io/daviestechlabs/ntfy-discord/internal/bridge" "git.daviestechlabs.io/daviestechlabs/ntfy-discord/internal/config" "git.daviestechlabs.io/daviestechlabs/ntfy-discord/internal/server" ) func main() { // Setup structured logging logLevel := slog.LevelInfo if os.Getenv("LOG_LEVEL") == "debug" { logLevel = slog.LevelDebug } logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: logLevel})) slog.SetDefault(logger) slog.Info("starting ntfy-discord bridge") // Create context with cancellation ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Load configuration (may connect to Vault) cfg, err := config.Load(ctx) if err != nil { slog.Error("failed to load config", "error", err) os.Exit(1) } defer cfg.Close() // Start the bridge b := bridge.New(cfg) // Start HTTP server for health/metrics srv := server.New(cfg.HTTPPort, b) go srv.Start() // Start watching secrets for hot reload (Vault and/or file-based) cfg.WatchSecrets(ctx) // Start the bridge go b.Run(ctx) // Wait for shutdown signal sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) <-sigCh slog.Info("shutting down") cancel() srv.Shutdown(ctx) }