Add optional pprof endpoint for debugging
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
_ "net/http/pprof" // registers /debug/pprof on http.DefaultServeMux (served only on PprofAddr)
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/golang-migrate/migrate/v4"
|
"github.com/golang-migrate/migrate/v4"
|
||||||
@@ -48,6 +49,18 @@ func main() {
|
|||||||
|
|
||||||
go scheduler.New(st, orch).Start(context.Background())
|
go scheduler.New(st, orch).Start(context.Background())
|
||||||
|
|
||||||
|
// Optional pprof endpoint on a separate, non-published listener so we can
|
||||||
|
// pull live goroutine dumps (docker compose exec app wget -qO-
|
||||||
|
// localhost:6060/debug/pprof/goroutine?debug=2) without killing the process.
|
||||||
|
if cfg.PprofAddr != "" {
|
||||||
|
go func() {
|
||||||
|
slog.Info("pprof listening", "addr", cfg.PprofAddr)
|
||||||
|
if err := http.ListenAndServe(cfg.PprofAddr, nil); err != nil {
|
||||||
|
slog.Error("pprof serve", "err", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
slog.Info("listening", "addr", cfg.HTTPAddr)
|
slog.Info("listening", "addr", cfg.HTTPAddr)
|
||||||
if err := http.ListenAndServe(cfg.HTTPAddr, srv.Router()); err != nil {
|
if err := http.ListenAndServe(cfg.HTTPAddr, srv.Router()); err != nil {
|
||||||
slog.Error("serve", "err", err)
|
slog.Error("serve", "err", err)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ services:
|
|||||||
ENC_KEY: ${ENC_KEY}
|
ENC_KEY: ${ENC_KEY}
|
||||||
SESSION_SECRET: ${SESSION_SECRET}
|
SESSION_SECRET: ${SESSION_SECRET}
|
||||||
WORKER_CONCURRENCY: ${WORKER_CONCURRENCY:-4}
|
WORKER_CONCURRENCY: ${WORKER_CONCURRENCY:-4}
|
||||||
|
PPROF_ADDR: ${PPROF_ADDR:-:6060}
|
||||||
depends_on:
|
depends_on:
|
||||||
postgres:
|
postgres:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ type Config struct {
|
|||||||
EncKey []byte
|
EncKey []byte
|
||||||
SessionSecret []byte
|
SessionSecret []byte
|
||||||
WorkerConcurrency int
|
WorkerConcurrency int
|
||||||
|
PprofAddr string // if non-empty, serve net/http/pprof here (e.g. ":6060")
|
||||||
}
|
}
|
||||||
|
|
||||||
func Load() (Config, error) {
|
func Load() (Config, error) {
|
||||||
@@ -25,6 +26,7 @@ func Load() (Config, error) {
|
|||||||
AuthPass: os.Getenv("AUTH_PASS"),
|
AuthPass: os.Getenv("AUTH_PASS"),
|
||||||
SessionSecret: []byte(os.Getenv("SESSION_SECRET")),
|
SessionSecret: []byte(os.Getenv("SESSION_SECRET")),
|
||||||
WorkerConcurrency: 4,
|
WorkerConcurrency: 4,
|
||||||
|
PprofAddr: os.Getenv("PPROF_ADDR"),
|
||||||
}
|
}
|
||||||
if v := os.Getenv("WORKER_CONCURRENCY"); v != "" {
|
if v := os.Getenv("WORKER_CONCURRENCY"); v != "" {
|
||||||
n, err := strconv.Atoi(v)
|
n, err := strconv.Atoi(v)
|
||||||
|
|||||||
Reference in New Issue
Block a user