diff --git a/.golangci.yml b/.golangci.yml index e74df5d..96037d5 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -36,7 +36,7 @@ linters-settings: dupl: threshold: 150 funlen: - lines: 120 + lines: 150 statements: 60 goconst: min-len: 2 diff --git a/README.md b/README.md index 0a7ecc3..2349687 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,8 @@ docker build . * `NSM_OPEN_TELEMETRY_ENDPOINT` - OpenTelemetry Collector Endpoint (default: "otel-collector.observability.svc.cluster.local:4317") * `NSM_METRICS_EXPORT_INTERVAL` - interval between mertics exports (default: "10s") * `NSM_KUBELET_QPS` - kubelet config settings (default: "205") +* `NSM_ENABLE_PROFILER` - Enable pprof package HTTP server for profiling runtime data. +* `NSM_PROFILER_HTTP_PORT` - Profiling server HTTP port providing data in the format expected by the pprof visualization tool. # Testing diff --git a/main.go b/main.go index 2e8bd9a..c6e519d 100644 --- a/main.go +++ b/main.go @@ -24,6 +24,7 @@ package main import ( "context" "crypto/tls" + "fmt" "net/url" "os" "os/signal" @@ -52,6 +53,9 @@ import ( "github.com/networkservicemesh/sdk/pkg/tools/grpcutils" "github.com/networkservicemesh/sdk/pkg/tools/log" "github.com/networkservicemesh/sdk/pkg/tools/log/logruslogger" + + "net/http" + _ "net/http/pprof" // #nosec ) // Config is configuration for cmd-registry-memory @@ -70,7 +74,9 @@ type Config struct { // FWD Refreshes: 1 refresh per sec. * 5 fwds // NSC Refreshes: 4 finds (in 1 refresh) per sec. * 40 nscs // Total: = 205 - KubeletQPS int `default:"205" desc:"kubelet config settings" split_words:"true"` + KubeletQPS int `default:"205" desc:"kubelet config settings" split_words:"true"` + EnableProfiler bool `default:"false" desc:"Enable pprof package HTTP server for profiling runtime data. The handled paths all begin with /debug/pprof/." split_words:"true"` + ProfilerHTTPPort uint16 `default:"6060" desc:"Profiling server HTTP port providing data in the format expected by the pprof visualization tool." split_words:"true"` } func main() { @@ -113,6 +119,25 @@ func main() { logrus.SetLevel(l) log.FromContext(ctx).Infof("Config: %#v", config) + // Enable profiling server + if config.EnableProfiler { + go func() { + log.FromContext(ctx).Infof("Profiler is enabled. Starting HTTP server on %d", config.ProfilerHTTPPort) + + address := fmt.Sprintf("localhost:%d", config.ProfilerHTTPPort) + + server := &http.Server{ + Addr: address, + ReadTimeout: 10 * time.Second, + WriteTimeout: 10 * time.Second, + } + + if err = server.ListenAndServe(); err != nil { + log.FromContext(ctx).Errorf("Failed to start profiler: %s", err.Error()) + } + }() + } + // Configure Open Telemetry if opentelemetry.IsEnabled() { collectorAddress := config.OpenTelemetryEndpoint diff --git a/pkg/internal/imports/imports_linux.go b/pkg/internal/imports/imports_linux.go index 0b99e48..98040e9 100644 --- a/pkg/internal/imports/imports_linux.go +++ b/pkg/internal/imports/imports_linux.go @@ -23,6 +23,8 @@ import ( _ "github.com/spiffe/go-spiffe/v2/workloadapi" _ "google.golang.org/grpc" _ "google.golang.org/grpc/credentials" + _ "net/http" + _ "net/http/pprof" _ "net/url" _ "os" _ "os/signal"