From 56d44609eaa23212c0bf09d5284c9d782aaeccfc Mon Sep 17 00:00:00 2001 From: crapStone Date: Tue, 30 Apr 2024 19:50:03 +0000 Subject: [PATCH] Add option to start http server for profiling (#323) https://rafallorenz.com/go/go-profiling-http-service-with-pprof-and-expvar/ Reviewed-on: https://codeberg.org/Codeberg/pages-server/pulls/323 Co-authored-by: crapStone Co-committed-by: crapStone --- Justfile | 4 ++-- README.md | 15 +++++++++++++++ cli/flags.go | 12 ++++++++++++ server/profiling.go | 21 +++++++++++++++++++++ server/startup.go | 8 ++++---- 5 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 server/profiling.go diff --git a/Justfile b/Justfile index 0bf38a3..231df7f 100644 --- a/Justfile +++ b/Justfile @@ -1,13 +1,13 @@ CGO_FLAGS := '-extldflags "-static" -linkmode external' TAGS := 'sqlite sqlite_unlock_notify netgo' -dev: +dev *FLAGS: #!/usr/bin/env bash set -euxo pipefail set -a # automatically export all variables source .env-dev set +a - go run -tags '{{TAGS}}' . + go run -tags '{{TAGS}}' . {{FLAGS}} build: CGO_ENABLED=1 go build -tags '{{TAGS}}' -ldflags '-s -w {{CGO_FLAGS}}' -v -o build/codeberg-pages-server ./ diff --git a/README.md b/README.md index c23d86a..a1d6424 100644 --- a/README.md +++ b/README.md @@ -124,3 +124,18 @@ now these pages should work: - - - + +### Profiling + +> This section is just a collection of commands for quick reference. If you want to learn more about profiling read [this](https://go.dev/doc/diagnostics) article or google `golang profiling`. + +First enable profiling by supplying the cli arg `--enable-profiling` or using the environment variable `EENABLE_PROFILING`. + +Get cpu and mem stats: + +```bash +go tool pprof -raw -output=cpu.txt 'http://localhost:9999/debug/pprof/profile?seconds=60' & +curl -so mem.txt 'http://localhost:9999/debug/pprof/heap?seconds=60' +``` + +More endpoints are documented here: diff --git a/cli/flags.go b/cli/flags.go index 52e1c1c..f7a7dc8 100644 --- a/cli/flags.go +++ b/cli/flags.go @@ -139,6 +139,18 @@ var ( EnvVars: []string{"CONFIG_FILE"}, }, + &cli.BoolFlag{ + Name: "enable-profiling", + Usage: "enables the go http profiling endpoints", + EnvVars: []string{"ENABLE_PROFILING"}, + }, + &cli.StringFlag{ + Name: "profiling-address", + Usage: "specify ip address and port the profiling server should listen on", + EnvVars: []string{"PROFILING_ADDRESS"}, + Value: "localhost:9999", + }, + // ############################ // ### ACME Client Settings ### // ############################ diff --git a/server/profiling.go b/server/profiling.go new file mode 100644 index 0000000..7d20926 --- /dev/null +++ b/server/profiling.go @@ -0,0 +1,21 @@ +package server + +import ( + "net/http" + _ "net/http/pprof" + + "github.com/rs/zerolog/log" +) + +func StartProfilingServer(listeningAddress string) { + server := &http.Server{ + Addr: listeningAddress, + Handler: http.DefaultServeMux, + } + + log.Info().Msgf("Starting debug server on %s", listeningAddress) + + go func() { + log.Fatal().Err(server.ListenAndServe()).Msg("Failed to start debug server") + }() +} diff --git a/server/startup.go b/server/startup.go index 149a07d..fd89803 100644 --- a/server/startup.go +++ b/server/startup.go @@ -3,7 +3,6 @@ package server import ( "context" "crypto/tls" - "encoding/json" "fmt" "net" "net/http" @@ -43,9 +42,6 @@ func Serve(ctx *cli.Context) error { } log.Logger = zerolog.New(zerolog.ConsoleWriter{Out: os.Stderr}).With().Timestamp().Logger().Level(logLevel) - foo, _ := json.Marshal(cfg) - log.Trace().RawJSON("config", foo).Msg("starting server with config") - listeningSSLAddress := fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port) listeningHTTPAddress := fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.HttpPort) @@ -133,6 +129,10 @@ func Serve(ctx *cli.Context) error { }() } + if ctx.IsSet("enable-profiling") { + StartProfilingServer(ctx.String("profiling-address")) + } + // Create ssl handler based on settings sslHandler := handler.Handler(cfg.Server, giteaClient, dnsLookupCache, canonicalDomainCache, redirectsCache)