feat(observabillity): #115 integrate otel for metrics and traces
This commit was merged in pull request #152.
This commit is contained in:
@@ -19,56 +19,67 @@ import (
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
|
||||
func Run(ctx context.Context, database *sqlx.DB, migrationsPrefix string, env func(string) string) error {
|
||||
ctx, cancel := signal.NotifyContext(ctx, syscall.SIGINT, syscall.SIGTERM)
|
||||
defer cancel()
|
||||
|
||||
log.Info("Starting server...")
|
||||
log.L.Info("Starting server...")
|
||||
|
||||
// init server settings
|
||||
serverSettings := types.NewSettingsFromEnv(env)
|
||||
serverSettings, err := types.NewSettingsFromEnv(env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// init db
|
||||
err := db.RunMigrations(database, migrationsPrefix)
|
||||
err = db.RunMigrations(database, migrationsPrefix)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not run migrations: %w", err)
|
||||
}
|
||||
|
||||
// init servers
|
||||
var prometheusServer *http.Server
|
||||
if serverSettings.PrometheusEnabled {
|
||||
prometheusServer := &http.Server{
|
||||
Addr: ":8081",
|
||||
Handler: promhttp.Handler(),
|
||||
ReadHeaderTimeout: 10 * time.Second,
|
||||
if serverSettings.OtelEnabled {
|
||||
// use context.Background(), otherwise the shutdown can't be called, as the context is already cancelled
|
||||
otelShutdown, err := setupOTelSDK(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not setup OpenTelemetry SDK: %w", err)
|
||||
}
|
||||
go startServer(prometheusServer)
|
||||
defer func() {
|
||||
// User context.Background(), as the main context is already cancelled
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
err = otelShutdown(ctx)
|
||||
if err != nil {
|
||||
log.L.Error("error shutting down OpenTelemetry SDK", "err", err)
|
||||
}
|
||||
cancel()
|
||||
}()
|
||||
|
||||
log.InitOtelLogger()
|
||||
}
|
||||
|
||||
// init server
|
||||
httpServer := &http.Server{
|
||||
Addr: ":" + serverSettings.Port,
|
||||
Handler: createHandler(database, serverSettings),
|
||||
ReadHeaderTimeout: 10 * time.Second,
|
||||
ReadHeaderTimeout: 2 * time.Second,
|
||||
}
|
||||
go startServer(httpServer)
|
||||
|
||||
// graceful shutdown
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(2)
|
||||
wg.Add(1)
|
||||
go shutdownServer(httpServer, ctx, &wg)
|
||||
go shutdownServer(prometheusServer, ctx, &wg)
|
||||
wg.Wait()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func startServer(s *http.Server) {
|
||||
log.Info("Starting server on %q", s.Addr)
|
||||
log.L.Info("Starting server", "addr", s.Addr)
|
||||
if err := s.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
log.Error("error listening and serving: %v", err)
|
||||
log.L.Error("error listening and serving", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,9 +94,9 @@ func shutdownServer(s *http.Server, ctx context.Context, wg *sync.WaitGroup) {
|
||||
shutdownCtx, cancel := context.WithTimeout(shutdownCtx, 10*time.Second)
|
||||
defer cancel()
|
||||
if err := s.Shutdown(shutdownCtx); err != nil {
|
||||
log.Error("error shutting down http server: %v", err)
|
||||
log.L.Error("error shutting down http server", "err", err)
|
||||
} else {
|
||||
log.Info("Gracefully stopped http server on %v", s.Addr)
|
||||
log.L.Info("Gracefully stopped http server", "addr", s.Addr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +133,7 @@ func createHandler(d *sqlx.DB, serverSettings *types.Settings) http.Handler {
|
||||
// Serve static files (CSS, JS and images)
|
||||
router.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static/"))))
|
||||
|
||||
return middleware.Wrapper(
|
||||
wrapper := middleware.Wrapper(
|
||||
router,
|
||||
middleware.GenerateRecurringTransactions(transactionRecurringService),
|
||||
middleware.SecurityHeaders(serverSettings),
|
||||
@@ -132,4 +143,8 @@ func createHandler(d *sqlx.DB, serverSettings *types.Settings) http.Handler {
|
||||
middleware.Gzip,
|
||||
middleware.Log,
|
||||
)
|
||||
|
||||
wrapper = otelhttp.NewHandler(wrapper, "http.request")
|
||||
|
||||
return wrapper
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user