Add pprof trace support

Add pprof trace support and --enable-contention-profiling to those
components that don't already have it.
This commit is contained in:
Andy Goldstein
2017-02-28 13:43:08 -05:00
parent 302aab9ba2
commit b011529d8a
16 changed files with 47 additions and 9 deletions

View File

@@ -22,6 +22,7 @@ import (
"net/http" "net/http"
"net/http/pprof" "net/http/pprof"
"os" "os"
goruntime "runtime"
"strconv" "strconv"
"time" "time"
@@ -111,6 +112,10 @@ func Run(s *options.CloudControllerManagerServer, cloud cloudprovider.Interface)
mux.HandleFunc("/debug/pprof/", pprof.Index) mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile) mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
if s.EnableContentionProfiling {
goruntime.SetBlockProfileRate(1)
}
} }
configz.InstallHandler(mux) configz.InstallHandler(mux)
mux.Handle("/metrics", prometheus.Handler()) mux.Handle("/metrics", prometheus.Handler())

View File

@@ -75,6 +75,7 @@ func (s *CloudControllerManagerServer) AddFlags(fs *pflag.FlagSet) {
fs.DurationVar(&s.RouteReconciliationPeriod.Duration, "route-reconciliation-period", s.RouteReconciliationPeriod.Duration, "The period for reconciling routes created for Nodes by cloud provider.") fs.DurationVar(&s.RouteReconciliationPeriod.Duration, "route-reconciliation-period", s.RouteReconciliationPeriod.Duration, "The period for reconciling routes created for Nodes by cloud provider.")
fs.BoolVar(&s.ConfigureCloudRoutes, "configure-cloud-routes", true, "Should CIDRs allocated by allocate-node-cidrs be configured on the cloud provider.") fs.BoolVar(&s.ConfigureCloudRoutes, "configure-cloud-routes", true, "Should CIDRs allocated by allocate-node-cidrs be configured on the cloud provider.")
fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/") fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/")
fs.BoolVar(&s.EnableContentionProfiling, "contention-profiling", false, "Enable lock contention profiling, if profiling is enabled")
fs.StringVar(&s.ClusterCIDR, "cluster-cidr", s.ClusterCIDR, "CIDR Range for Pods in cluster.") fs.StringVar(&s.ClusterCIDR, "cluster-cidr", s.ClusterCIDR, "CIDR Range for Pods in cluster.")
fs.BoolVar(&s.AllocateNodeCIDRs, "allocate-node-cidrs", false, "Should CIDRs for Pods be allocated and set on the cloud provider.") fs.BoolVar(&s.AllocateNodeCIDRs, "allocate-node-cidrs", false, "Should CIDRs for Pods be allocated and set on the cloud provider.")
fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig)") fs.StringVar(&s.Master, "master", s.Master, "The address of the Kubernetes API server (overrides any value in kubeconfig)")

View File

@@ -28,6 +28,7 @@ import (
"net/http" "net/http"
"net/http/pprof" "net/http/pprof"
"os" "os"
goruntime "runtime"
"strconv" "strconv"
"time" "time"
@@ -135,6 +136,10 @@ func Run(s *options.CMServer) error {
mux.HandleFunc("/debug/pprof/", pprof.Index) mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile) mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
if s.EnableContentionProfiling {
goruntime.SetBlockProfileRate(1)
}
} }
configz.InstallHandler(mux) configz.InstallHandler(mux)
mux.Handle("/metrics", prometheus.Handler()) mux.Handle("/metrics", prometheus.Handler())

View File

@@ -178,6 +178,7 @@ func (s *CMServer) AddFlags(fs *pflag.FlagSet, allControllers []string, disabled
fs.StringVar(&s.ClusterSigningKeyFile, "cluster-signing-key-file", s.ClusterSigningKeyFile, "Filename containing a PEM-encoded RSA or ECDSA private key used to sign cluster-scoped certificates") fs.StringVar(&s.ClusterSigningKeyFile, "cluster-signing-key-file", s.ClusterSigningKeyFile, "Filename containing a PEM-encoded RSA or ECDSA private key used to sign cluster-scoped certificates")
fs.StringVar(&s.ApproveAllKubeletCSRsForGroup, "insecure-experimental-approve-all-kubelet-csrs-for-group", s.ApproveAllKubeletCSRsForGroup, "The group for which the controller-manager will auto approve all CSRs for kubelet client certificates.") fs.StringVar(&s.ApproveAllKubeletCSRsForGroup, "insecure-experimental-approve-all-kubelet-csrs-for-group", s.ApproveAllKubeletCSRsForGroup, "The group for which the controller-manager will auto approve all CSRs for kubelet client certificates.")
fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/") fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/")
fs.BoolVar(&s.EnableContentionProfiling, "contention-profiling", false, "Enable lock contention profiling, if profiling is enabled")
fs.StringVar(&s.ClusterName, "cluster-name", s.ClusterName, "The instance prefix for the cluster") fs.StringVar(&s.ClusterName, "cluster-name", s.ClusterName, "The instance prefix for the cluster")
fs.StringVar(&s.ClusterCIDR, "cluster-cidr", s.ClusterCIDR, "CIDR Range for Pods in cluster.") fs.StringVar(&s.ClusterCIDR, "cluster-cidr", s.ClusterCIDR, "CIDR Range for Pods in cluster.")
fs.StringVar(&s.ServiceCIDR, "service-cluster-ip-range", s.ServiceCIDR, "CIDR Range for Services in cluster.") fs.StringVar(&s.ServiceCIDR, "service-cluster-ip-range", s.ServiceCIDR, "CIDR Range for Services in cluster.")

View File

@@ -150,6 +150,7 @@ func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) {
fs.Int32Var(&s.EventBurst, "event-burst", s.EventBurst, "Maximum size of a bursty event records, temporarily allows event records to burst to this number, while still not exceeding event-qps. Only used if --event-qps > 0") fs.Int32Var(&s.EventBurst, "event-burst", s.EventBurst, "Maximum size of a bursty event records, temporarily allows event records to burst to this number, while still not exceeding event-qps. Only used if --event-qps > 0")
fs.BoolVar(&s.RunOnce, "runonce", s.RunOnce, "If true, exit after spawning pods from local manifests or remote urls. Exclusive with --api-servers, and --enable-server") fs.BoolVar(&s.RunOnce, "runonce", s.RunOnce, "If true, exit after spawning pods from local manifests or remote urls. Exclusive with --api-servers, and --enable-server")
fs.BoolVar(&s.EnableDebuggingHandlers, "enable-debugging-handlers", s.EnableDebuggingHandlers, "Enables server endpoints for log collection and local running of containers and commands") fs.BoolVar(&s.EnableDebuggingHandlers, "enable-debugging-handlers", s.EnableDebuggingHandlers, "Enables server endpoints for log collection and local running of containers and commands")
fs.BoolVar(&s.EnableContentionProfiling, "contention-profiling", false, "Enable lock contention profiling, if profiling is enabled")
fs.DurationVar(&s.MinimumGCAge.Duration, "minimum-container-ttl-duration", s.MinimumGCAge.Duration, "Minimum age for a finished container before it is garbage collected. Examples: '300ms', '10s' or '2h45m'") fs.DurationVar(&s.MinimumGCAge.Duration, "minimum-container-ttl-duration", s.MinimumGCAge.Duration, "Minimum age for a finished container before it is garbage collected. Examples: '300ms', '10s' or '2h45m'")
fs.MarkDeprecated("minimum-container-ttl-duration", "Use --eviction-hard or --eviction-soft instead. Will be removed in a future version.") fs.MarkDeprecated("minimum-container-ttl-duration", "Use --eviction-hard or --eviction-soft instead. Will be removed in a future version.")
fs.Int32Var(&s.MaxPerPodContainerCount, "maximum-dead-containers-per-container", s.MaxPerPodContainerCount, "Maximum number of old instances to retain per container. Each container takes up some disk space. Default: 1.") fs.Int32Var(&s.MaxPerPodContainerCount, "maximum-dead-containers-per-container", s.MaxPerPodContainerCount, "Maximum number of old instances to retain per container. Each container takes up some disk space. Default: 1.")

View File

@@ -878,7 +878,7 @@ func startKubelet(k kubelet.KubeletBootstrap, podCfg *config.PodConfig, kubeCfg
// start the kubelet server // start the kubelet server
if kubeCfg.EnableServer { if kubeCfg.EnableServer {
go wait.Until(func() { go wait.Until(func() {
k.ListenAndServe(net.ParseIP(kubeCfg.Address), uint(kubeCfg.Port), kubeDeps.TLSOptions, kubeDeps.Auth, kubeCfg.EnableDebuggingHandlers) k.ListenAndServe(net.ParseIP(kubeCfg.Address), uint(kubeCfg.Port), kubeDeps.TLSOptions, kubeDeps.Auth, kubeCfg.EnableDebuggingHandlers, kubeCfg.EnableContentionProfiling)
}, 0, wait.NeverStop) }, 0, wait.NeverStop)
} }
if kubeCfg.ReadOnlyPort > 0 { if kubeCfg.ReadOnlyPort > 0 {

View File

@@ -24,6 +24,7 @@ import (
"net" "net"
"net/http" "net/http"
"net/http/pprof" "net/http/pprof"
goruntime "runtime"
"strconv" "strconv"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -131,6 +132,10 @@ func Run(s *options.CMServer) error {
mux.HandleFunc("/debug/pprof/", pprof.Index) mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile) mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
if s.EnableContentionProfiling {
goruntime.SetBlockProfileRate(1)
}
} }
mux.Handle("/metrics", prometheus.Handler()) mux.Handle("/metrics", prometheus.Handler())

View File

@@ -64,6 +64,8 @@ type ControllerManagerConfiguration struct {
APIServerBurst int `json:"federatedAPIBurst"` APIServerBurst int `json:"federatedAPIBurst"`
// enableProfiling enables profiling via web interface host:port/debug/pprof/ // enableProfiling enables profiling via web interface host:port/debug/pprof/
EnableProfiling bool `json:"enableProfiling"` EnableProfiling bool `json:"enableProfiling"`
// enableContentionProfiling enables lock contention profiling, if enableProfiling is true.
EnableContentionProfiling bool `json:"enableContentionProfiling"`
// leaderElection defines the configuration of leader election client. // leaderElection defines the configuration of leader election client.
LeaderElection componentconfig.LeaderElectionConfiguration `json:"leaderElection"` LeaderElection componentconfig.LeaderElectionConfiguration `json:"leaderElection"`
// contentType is contentType of requests sent to apiserver. // contentType is contentType of requests sent to apiserver.
@@ -115,6 +117,7 @@ func (s *CMServer) AddFlags(fs *pflag.FlagSet) {
fs.IntVar(&s.ConcurrentReplicaSetSyncs, "concurrent-replicaset-syncs", s.ConcurrentReplicaSetSyncs, "The number of ReplicaSets syncing operations that will be done concurrently. Larger number = faster endpoint updating, but more CPU (and network) load") fs.IntVar(&s.ConcurrentReplicaSetSyncs, "concurrent-replicaset-syncs", s.ConcurrentReplicaSetSyncs, "The number of ReplicaSets syncing operations that will be done concurrently. Larger number = faster endpoint updating, but more CPU (and network) load")
fs.DurationVar(&s.ClusterMonitorPeriod.Duration, "cluster-monitor-period", s.ClusterMonitorPeriod.Duration, "The period for syncing ClusterStatus in ClusterController.") fs.DurationVar(&s.ClusterMonitorPeriod.Duration, "cluster-monitor-period", s.ClusterMonitorPeriod.Duration, "The period for syncing ClusterStatus in ClusterController.")
fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/") fs.BoolVar(&s.EnableProfiling, "profiling", true, "Enable profiling via web interface host:port/debug/pprof/")
fs.BoolVar(&s.EnableContentionProfiling, "contention-profiling", false, "Enable lock contention profiling, if profiling is enabled")
fs.StringVar(&s.Master, "master", s.Master, "The address of the federation API server (overrides any value in kubeconfig)") fs.StringVar(&s.Master, "master", s.Master, "The address of the federation API server (overrides any value in kubeconfig)")
fs.StringVar(&s.Kubeconfig, "kubeconfig", s.Kubeconfig, "Path to kubeconfig file with authorization and master location information.") fs.StringVar(&s.Kubeconfig, "kubeconfig", s.Kubeconfig, "Path to kubeconfig file with authorization and master location information.")
fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "ContentType of requests sent to apiserver. Passing application/vnd.kubernetes.protobuf is an experimental feature now.") fs.StringVar(&s.ContentType, "kube-api-content-type", s.ContentType, "ContentType of requests sent to apiserver. Passing application/vnd.kubernetes.protobuf is an experimental feature now.")

View File

@@ -210,6 +210,8 @@ type KubeletConfiguration struct {
// enableDebuggingHandlers enables server endpoints for log collection // enableDebuggingHandlers enables server endpoints for log collection
// and local running of containers and commands // and local running of containers and commands
EnableDebuggingHandlers bool EnableDebuggingHandlers bool
// enableContentionProfiling enables lock contention profiling, if enableDebuggingHandlers is true.
EnableContentionProfiling bool
// minimumGCAge is the minimum age for a finished container before it is // minimumGCAge is the minimum age for a finished container before it is
// garbage collected. // garbage collected.
MinimumGCAge metav1.Duration MinimumGCAge metav1.Duration
@@ -757,6 +759,8 @@ type KubeControllerManagerConfiguration struct {
ApproveAllKubeletCSRsForGroup string ApproveAllKubeletCSRsForGroup string
// enableProfiling enables profiling via web interface host:port/debug/pprof/ // enableProfiling enables profiling via web interface host:port/debug/pprof/
EnableProfiling bool EnableProfiling bool
// enableContentionProfiling enables lock contention profiling, if enableProfiling is true.
EnableContentionProfiling bool
// clusterName is the instance prefix for the cluster. // clusterName is the instance prefix for the cluster.
ClusterName string ClusterName string
// clusterCIDR is CIDR Range for Pods in cluster. // clusterCIDR is CIDR Range for Pods in cluster.

View File

@@ -264,6 +264,8 @@ type KubeletConfiguration struct {
// enableDebuggingHandlers enables server endpoints for log collection // enableDebuggingHandlers enables server endpoints for log collection
// and local running of containers and commands // and local running of containers and commands
EnableDebuggingHandlers *bool `json:"enableDebuggingHandlers"` EnableDebuggingHandlers *bool `json:"enableDebuggingHandlers"`
// enableContentionProfiling enables lock contention profiling, if enableDebuggingHandlers is true.
EnableContentionProfiling bool `json:"enableContentionProfiling"`
// minimumGCAge is the minimum age for a finished container before it is // minimumGCAge is the minimum age for a finished container before it is
// garbage collected. // garbage collected.
MinimumGCAge metav1.Duration `json:"minimumGCAge"` MinimumGCAge metav1.Duration `json:"minimumGCAge"`

View File

@@ -180,7 +180,7 @@ type KubeletBootstrap interface {
GetConfiguration() componentconfig.KubeletConfiguration GetConfiguration() componentconfig.KubeletConfiguration
BirthCry() BirthCry()
StartGarbageCollection() StartGarbageCollection()
ListenAndServe(address net.IP, port uint, tlsOptions *server.TLSOptions, auth server.AuthInterface, enableDebuggingHandlers bool) ListenAndServe(address net.IP, port uint, tlsOptions *server.TLSOptions, auth server.AuthInterface, enableDebuggingHandlers, enableContentionProfiling bool)
ListenAndServeReadOnly(address net.IP, port uint) ListenAndServeReadOnly(address net.IP, port uint)
Run(<-chan kubetypes.PodUpdate) Run(<-chan kubetypes.PodUpdate)
RunOnce(<-chan kubetypes.PodUpdate) ([]RunPodResult, error) RunOnce(<-chan kubetypes.PodUpdate) ([]RunPodResult, error)
@@ -2120,8 +2120,8 @@ func (kl *Kubelet) ResyncInterval() time.Duration {
} }
// ListenAndServe runs the kubelet HTTP server. // ListenAndServe runs the kubelet HTTP server.
func (kl *Kubelet) ListenAndServe(address net.IP, port uint, tlsOptions *server.TLSOptions, auth server.AuthInterface, enableDebuggingHandlers bool) { func (kl *Kubelet) ListenAndServe(address net.IP, port uint, tlsOptions *server.TLSOptions, auth server.AuthInterface, enableDebuggingHandlers, enableContentionProfiling bool) {
server.ListenAndServeKubeletServer(kl, kl.resourceAnalyzer, address, port, tlsOptions, auth, enableDebuggingHandlers, kl.containerRuntime, kl.criHandler) server.ListenAndServeKubeletServer(kl, kl.resourceAnalyzer, address, port, tlsOptions, auth, enableDebuggingHandlers, enableContentionProfiling, kl.containerRuntime, kl.criHandler)
} }
// ListenAndServeReadOnly runs the kubelet HTTP server in read-only mode. // ListenAndServeReadOnly runs the kubelet HTTP server in read-only mode.

View File

@@ -25,6 +25,7 @@ import (
"net/http/pprof" "net/http/pprof"
"net/url" "net/url"
"reflect" "reflect"
goruntime "runtime"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@@ -119,11 +120,12 @@ func ListenAndServeKubeletServer(
port uint, port uint,
tlsOptions *TLSOptions, tlsOptions *TLSOptions,
auth AuthInterface, auth AuthInterface,
enableDebuggingHandlers bool, enableDebuggingHandlers,
enableContentionProfiling bool,
runtime kubecontainer.Runtime, runtime kubecontainer.Runtime,
criHandler http.Handler) { criHandler http.Handler) {
glog.Infof("Starting to listen on %s:%d", address, port) glog.Infof("Starting to listen on %s:%d", address, port)
handler := NewServer(host, resourceAnalyzer, auth, enableDebuggingHandlers, runtime, criHandler) handler := NewServer(host, resourceAnalyzer, auth, enableDebuggingHandlers, enableContentionProfiling, runtime, criHandler)
s := &http.Server{ s := &http.Server{
Addr: net.JoinHostPort(address.String(), strconv.FormatUint(uint64(port), 10)), Addr: net.JoinHostPort(address.String(), strconv.FormatUint(uint64(port), 10)),
Handler: &handler, Handler: &handler,
@@ -140,7 +142,7 @@ func ListenAndServeKubeletServer(
// ListenAndServeKubeletReadOnlyServer initializes a server to respond to HTTP network requests on the Kubelet. // ListenAndServeKubeletReadOnlyServer initializes a server to respond to HTTP network requests on the Kubelet.
func ListenAndServeKubeletReadOnlyServer(host HostInterface, resourceAnalyzer stats.ResourceAnalyzer, address net.IP, port uint, runtime kubecontainer.Runtime) { func ListenAndServeKubeletReadOnlyServer(host HostInterface, resourceAnalyzer stats.ResourceAnalyzer, address net.IP, port uint, runtime kubecontainer.Runtime) {
glog.V(1).Infof("Starting to listen read-only on %s:%d", address, port) glog.V(1).Infof("Starting to listen read-only on %s:%d", address, port)
s := NewServer(host, resourceAnalyzer, nil, false, runtime, nil) s := NewServer(host, resourceAnalyzer, nil, false, false, runtime, nil)
server := &http.Server{ server := &http.Server{
Addr: net.JoinHostPort(address.String(), strconv.FormatUint(uint64(port), 10)), Addr: net.JoinHostPort(address.String(), strconv.FormatUint(uint64(port), 10)),
@@ -192,7 +194,8 @@ func NewServer(
host HostInterface, host HostInterface,
resourceAnalyzer stats.ResourceAnalyzer, resourceAnalyzer stats.ResourceAnalyzer,
auth AuthInterface, auth AuthInterface,
enableDebuggingHandlers bool, enableDebuggingHandlers,
enableContentionProfiling bool,
runtime kubecontainer.Runtime, runtime kubecontainer.Runtime,
criHandler http.Handler) Server { criHandler http.Handler) Server {
server := Server{ server := Server{
@@ -208,6 +211,9 @@ func NewServer(
server.InstallDefaultHandlers() server.InstallDefaultHandlers()
if enableDebuggingHandlers { if enableDebuggingHandlers {
server.InstallDebuggingHandlers(criHandler) server.InstallDebuggingHandlers(criHandler)
if enableContentionProfiling {
goruntime.SetBlockProfileRate(1)
}
} }
return server return server
} }
@@ -381,6 +387,8 @@ func (s *Server) InstallDebuggingHandlers(criHandler http.Handler) {
pprof.Symbol(resp, req.Request) pprof.Symbol(resp, req.Request)
case "cmdline": case "cmdline":
pprof.Cmdline(resp, req.Request) pprof.Cmdline(resp, req.Request)
case "trace":
pprof.Trace(resp, req.Request)
default: default:
pprof.Index(resp, req.Request) pprof.Index(resp, req.Request)
} }

View File

@@ -240,6 +240,7 @@ func newServerTest() *serverTestFramework {
stats.NewResourceAnalyzer(fw.fakeKubelet, time.Minute, &kubecontainertesting.FakeRuntime{}), stats.NewResourceAnalyzer(fw.fakeKubelet, time.Minute, &kubecontainertesting.FakeRuntime{}),
fw.fakeAuth, fw.fakeAuth,
true, true,
false,
&kubecontainertesting.Mock{}, &kubecontainertesting.Mock{},
fw.criHandler) fw.criHandler)
fw.serverUnderTest = &server fw.serverUnderTest = &server

View File

@@ -146,6 +146,7 @@ func startHTTP(s *options.SchedulerServer) {
mux.HandleFunc("/debug/pprof/", pprof.Index) mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile) mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol) mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
if s.EnableContentionProfiling { if s.EnableContentionProfiling {
goruntime.SetBlockProfileRate(1) goruntime.SetBlockProfileRate(1)
} }

View File

@@ -42,7 +42,7 @@ func (o *FeatureOptions) AddFlags(fs *pflag.FlagSet) {
fs.BoolVar(&o.EnableProfiling, "profiling", o.EnableProfiling, fs.BoolVar(&o.EnableProfiling, "profiling", o.EnableProfiling,
"Enable profiling via web interface host:port/debug/pprof/") "Enable profiling via web interface host:port/debug/pprof/")
fs.BoolVar(&o.EnableContentionProfiling, "contention-profiling", o.EnableContentionProfiling, fs.BoolVar(&o.EnableContentionProfiling, "contention-profiling", o.EnableContentionProfiling,
"Enable contention profiling. Requires --profiling to be set to work.") "Enable lock contention profiling, if profiling is enabled")
fs.BoolVar(&o.EnableSwaggerUI, "enable-swagger-ui", o.EnableSwaggerUI, fs.BoolVar(&o.EnableSwaggerUI, "enable-swagger-ui", o.EnableSwaggerUI,
"Enables swagger ui on the apiserver at /swagger-ui") "Enables swagger ui on the apiserver at /swagger-ui")
} }

View File

@@ -30,4 +30,5 @@ func (d Profiling) Install(c *mux.APIContainer) {
c.UnlistedRoutes.HandleFunc("/debug/pprof/", pprof.Index) c.UnlistedRoutes.HandleFunc("/debug/pprof/", pprof.Index)
c.UnlistedRoutes.HandleFunc("/debug/pprof/profile", pprof.Profile) c.UnlistedRoutes.HandleFunc("/debug/pprof/profile", pprof.Profile)
c.UnlistedRoutes.HandleFunc("/debug/pprof/symbol", pprof.Symbol) c.UnlistedRoutes.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
c.UnlistedRoutes.HandleFunc("/debug/pprof/trace", pprof.Trace)
} }