diff --git a/CHANGELOG.md b/CHANGELOG.md index ca949f76..dc013797 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Digest: `TODO` * Initial prometheus metrics collection [#85](https://github.com/GoogleCloudPlatform/secrets-store-csi-driver-provider-gcp/pull/85) * `livenessProbe` [#85](https://github.com/GoogleCloudPlatform/secrets-store-csi-driver-provider-gcp/pull/85) * [Debugging documentation](https://github.com/GoogleCloudPlatform/secrets-store-csi-driver-provider-gcp/blob/v0.3.0/docs/debugging.md) [#85](https://github.com/GoogleCloudPlatform/secrets-store-csi-driver-provider-gcp/pull/85) +* Optional pprof debugging endpoint [#88](https://github.com/GoogleCloudPlatform/secrets-store-csi-driver-provider-gcp/pull/88) ## v0.2.0 diff --git a/docs/debugging.md b/docs/debugging.md index 483a8d0b..e5b897fe 100644 --- a/docs/debugging.md +++ b/docs/debugging.md @@ -126,6 +126,16 @@ kubectl port-forward csi-secrets-store-provider-gcp-vmqct --namespace=kube-syste curl localhost:8095/metrics ``` +## pprof + +Starting the plugin with `-enable-pprof=true` will enable a debug http endpoint +at `-debug_addr`. Accessing this will also require `port-forward`: + +```cli +kubectl port-forward csi-secrets-store-provider-gcp-vmqct --namespace=kube-system 6060:6060 +curl localhost:6060/debug/pprof +``` + ## Objects View `SecretProviderClass`s: diff --git a/main.go b/main.go index e221ed6d..e917289c 100644 --- a/main.go +++ b/main.go @@ -23,6 +23,7 @@ import ( "fmt" "net" "net/http" + "net/http/pprof" "os" "os/signal" "path/filepath" @@ -42,6 +43,8 @@ var ( kubeconfig = flag.String("kubeconfig", "", "absolute path to kubeconfig file") logFormatJSON = flag.Bool("log-format-json", true, "set log formatter to json") metricsAddr = flag.String("metrics_addr", ":8095", "configure http listener for reporting metrics") + enableProfile = flag.Bool("enable-pprof", false, "enable pprof profiling") + debugAddr = flag.String("debug_addr", "localhost:6060", "port for pprof profiling") version = "dev" ) @@ -85,8 +88,10 @@ func main() { go g.Serve(l) // initialize metrics and health http server + mux := http.NewServeMux() ms := http.Server{ - Addr: *metricsAddr, + Addr: *metricsAddr, + Handler: mux, } defer ms.Shutdown(ctx) @@ -98,8 +103,8 @@ func main() { if err := runtime.Start(runtime.WithMeterProvider(ex.MeterProvider())); err != nil { klog.ErrorS(err, "unable to start runtime metrics monitoring") } - http.HandleFunc("/metrics", ex.ServeHTTP) - http.HandleFunc("/live", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/metrics", ex.ServeHTTP) + mux.HandleFunc("/live", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) }) go func() { @@ -109,6 +114,26 @@ func main() { }() klog.InfoS("health server listening", "addr", *metricsAddr) + if *enableProfile { + dmux := http.NewServeMux() + dmux.HandleFunc("/debug/pprof/", pprof.Index) + dmux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) + dmux.HandleFunc("/debug/pprof/profile", pprof.Profile) + dmux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) + dmux.HandleFunc("/debug/pprof/trace", pprof.Trace) + ds := http.Server{ + Addr: *debugAddr, + Handler: dmux, + } + defer ds.Shutdown(ctx) + go func() { + if err := ds.ListenAndServe(); err != nil && err != http.ErrServerClosed { + klog.ErrorS(err, "debug http server error") + } + }() + klog.InfoS("debug server listening", "addr", *debugAddr) + } + <-ctx.Done() klog.InfoS("terminating") g.GracefulStop()