Created
March 19, 2024 12:24
-
-
Save adomaskizogian/a2df1149d750fef843718e1b04e93689 to your computer and use it in GitHub Desktop.
go http quick setup
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "context" | |
| "errors" | |
| "fmt" | |
| "log/slog" | |
| "net/http" | |
| "net/http/httputil" | |
| "os" | |
| "os/signal" | |
| "runtime" | |
| "syscall" | |
| "time" | |
| ) | |
| func main() { | |
| var retCode int | |
| defer func() { | |
| os.Exit(retCode) | |
| }() | |
| defer func() { | |
| if err := recover(); err != nil { | |
| buf := make([]byte, 64<<10) | |
| buf = buf[:runtime.Stack(buf, false)] | |
| slog.Error("recovered panic on main", "panic", err, "stack", string(buf)) | |
| retCode = 2 | |
| } | |
| }() | |
| logHandler := slog.NewTextHandler(os.Stdout, nil) | |
| slog.SetDefault(slog.New(logHandler)) | |
| if err := run(context.Background()); err != nil { | |
| slog.Error("service stopped abnormally", "error", err) | |
| retCode = 1 | |
| } | |
| } | |
| func run(ctx context.Context) error { | |
| srv := &http.Server{ | |
| Addr: ":8080", | |
| Handler: dumper(), | |
| ErrorLog: slog.NewLogLogger(slog.Default().Handler(), slog.LevelError), | |
| } | |
| ctx, cancel := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM, syscall.SIGINT) | |
| go func() { | |
| defer func() { | |
| if err := recover(); err != nil { | |
| buf := make([]byte, 64<<10) | |
| buf = buf[:runtime.Stack(buf, false)] | |
| slog.Error("recovered panic on ListenAndServe goroutine", "panic", err, "stack", string(buf)) | |
| cancel() | |
| } | |
| }() | |
| slog.Info("server is listening for incoming requests", "addr", srv.Addr) | |
| if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { | |
| slog.Error("ListenAndServe stopped unexpectedly", "error", err) | |
| cancel() | |
| } | |
| }() | |
| <-ctx.Done() | |
| timeoutCtx, cancel := context.WithTimeout(context.Background(), time.Second*5) | |
| defer cancel() | |
| slog.Info("stopping gracefully. force shutdown in 5 seconds") | |
| if err := srv.Shutdown(timeoutCtx); err != nil { | |
| slog.Warn("server shutdown returned error", "error", err) | |
| } | |
| slog.Info("bye") | |
| return nil | |
| } | |
| func dumper() http.HandlerFunc { | |
| return func(w http.ResponseWriter, r *http.Request) { | |
| dump, err := httputil.DumpRequest(r, true) | |
| if err != nil { | |
| w.WriteHeader(http.StatusInternalServerError) | |
| return | |
| } | |
| fmt.Println(string(dump)) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment