package main import ( "context" "log/slog" "os" "os/signal" "syscall" "time" ) func main() { logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) slog.SetDefault(logger) ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Handle OS signals go func() { sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) <-sigChan slog.Info("Received shutdown signal") cancel() }() if err := run(ctx); err != nil { slog.Error("Application error", "error", err) os.Exit(1) } } func run(ctx context.Context) error { slog.Info("Starting application...") // Simulate long running process or server start // e.g. server.ListenAndServe() <-ctx.Done() slog.Info("Shutting down application...") // Cleanup with timeout _, shutdownCancel := context.WithTimeout(context.Background(), 5*time.Second) defer shutdownCancel() // Pretend to cleanup time.Sleep(100 * time.Millisecond) return nil }