onasty/cmd/server/main.go(view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
package main
import (
"context"
"errors"
"fmt"
"log/slog"
"net/http"
"os"
"os/signal"
"github.com/gin-gonic/gin"
"github.com/olexsmir/onasty/internal/config"
"github.com/olexsmir/onasty/internal/service/usersrv"
"github.com/olexsmir/onasty/internal/store/psql/userepo"
"github.com/olexsmir/onasty/internal/store/psqlutil"
httptransport "github.com/olexsmir/onasty/internal/transport/http"
"github.com/olexsmir/onasty/internal/transport/http/httpserver"
)
func main() {
if err := run(context.Background()); err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
}
func run(ctx context.Context) error {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
cfg := config.NewConfig()
if err := setupLogger(cfg); err != nil {
return err
}
if !cfg.IsDevMode() {
gin.SetMode(gin.ReleaseMode)
}
psqlDB, err := psqlutil.Connect(ctx, cfg.PostgresDSN)
if err != nil {
return err
}
// app deps
userepo := userepo.New(psqlDB)
usersrv := usersrv.New(userepo)
handler := httptransport.NewTransport(usersrv)
// http server
srv := httpserver.NewServer(cfg.ServerPort, handler.Handler())
go func() {
slog.Info("starting http server", "port", cfg.ServerPort)
if err := srv.Start(); !errors.Is(err, http.ErrServerClosed) {
slog.Error("failed to start http server", "error", err)
}
}()
// graceful shutdown
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt)
<-quit
if err := srv.Stop(ctx); err != nil {
return errors.Join(errors.New("failed to stop http server"), err)
}
if err := psqlDB.Close(); err != nil {
return errors.Join(errors.New("failed to close postgres connection"), err)
}
return nil
}
func setupLogger(cfg *config.Config) error {
loggerLevels := map[string]slog.Level{
"info": slog.LevelInfo,
"debug": slog.LevelDebug,
"error": slog.LevelError,
"warn": slog.LevelWarn,
}
logLevel, ok := loggerLevels[cfg.LogLevel]
if !ok {
return errors.New("unknown log level")
}
var slogHandler slog.Handler
switch cfg.LogFormat {
case "json":
slogHandler = slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: logLevel})
case "text":
slogHandler = slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: logLevel})
default:
return errors.New("unknown log format")
}
slog.SetDefault(slog.New(slogHandler))
return nil
}
|