Skip to content

Commit

Permalink
Merge pull request #489 from JiaweiGithub/feat/pprof
Browse files Browse the repository at this point in the history
add pprof for agent and gateway
  • Loading branch information
kubeedge-bot authored Aug 28, 2023
2 parents afb564b + c6356c2 commit 3d3c919
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 0 deletions.
4 changes: 4 additions & 0 deletions cmd/edgemesh-agent/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/kubeedge/edgemesh/pkg/apis/module"
"github.com/kubeedge/edgemesh/pkg/clients"
"github.com/kubeedge/edgemesh/pkg/dns"
"github.com/kubeedge/edgemesh/pkg/profile"
"github.com/kubeedge/edgemesh/pkg/proxy"
"github.com/kubeedge/edgemesh/pkg/tunnel"
"github.com/kubeedge/edgemesh/pkg/util"
Expand Down Expand Up @@ -139,6 +140,9 @@ func registerModules(c *v1alpha1.EdgeMeshAgentConfig, cli *clients.Clients) []er

// prepareRun prepares edgemesh-agent to run
func prepareRun(c *v1alpha1.EdgeMeshAgentConfig) error {
// start pprof server
profile.ListenAndServer(c.CommonConfig.PprofConfig)

// Enter manual mode if user set Master or KubeConfig
if c.KubeAPIConfig.Master != "" || c.KubeAPIConfig.KubeConfig != "" {
c.KubeAPIConfig.Mode = defaults.ManualMode
Expand Down
4 changes: 4 additions & 0 deletions cmd/edgemesh-gateway/app/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/kubeedge/edgemesh/pkg/apis/module"
"github.com/kubeedge/edgemesh/pkg/clients"
"github.com/kubeedge/edgemesh/pkg/gateway"
"github.com/kubeedge/edgemesh/pkg/profile"
"github.com/kubeedge/edgemesh/pkg/tunnel"
"github.com/kubeedge/edgemesh/pkg/util"
kubeedgeutil "github.com/kubeedge/kubeedge/pkg/util"
Expand Down Expand Up @@ -134,6 +135,9 @@ func registerModules(c *v1alpha1.EdgeMeshGatewayConfig, cli *clients.Clients) []

// prepareRun prepares edgemesh-gateway to run
func prepareRun(c *v1alpha1.EdgeMeshGatewayConfig) error {
// start pprof server
profile.ListenAndServer(c.PprofConfig)

// Enter manual mode if user set Master or KubeConfig
if c.KubeAPIConfig.Master != "" || c.KubeAPIConfig.KubeConfig != "" {
c.KubeAPIConfig.Mode = defaults.ManualMode
Expand Down
13 changes: 13 additions & 0 deletions pkg/apis/config/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ type EdgeMeshGatewayConfig struct {
// Modules indicates EdgeMeshAgent modules config
// +Required
Modules *GatewayModules `json:"modules,omitempty"`
// PprofConfig provides configuration for pprof monitoring
PprofConfig *PprofConfig `json:"pprofConfig,omitempty"`
}

// GatewayModules indicates the modules of EdgeMeshGateway will be use
Expand Down Expand Up @@ -116,6 +118,8 @@ type CommonConfig struct {
// BridgeDeviceIP indicates the IP bound to the bridge device
// default "169.254.96.16"
BridgeDeviceIP string `json:"bridgeDeviceIP,omitempty"`
// PprofConfig provides configuration for pprof monitoring tools
PprofConfig *PprofConfig `json:"pprofConfig,omitempty"`
}

// EdgeDNSConfig indicates the EdgeDNS config
Expand Down Expand Up @@ -320,3 +324,12 @@ type TunnelLimitConfig struct {
// default:1024
TunnelPeerBaseStreamOut int `json:"tunnelPeerBaseStreamOut,omitempty"`
}

type PprofConfig struct {
// Enables pprof at profilingAddress:profilingPort/debug/pprof.
EnableProfiling bool `json:"enableProfiling,omitempty"`
// ProfilingAddress is the IP address for the profiling server to serve on.
ProfilingAddress string `json:"profilingAddress,omitempty"`
// ProfilingPort is the port of the localhost profiling endpoint
ProfilingPort int `json:"profilingPort,omitempty"`
}
56 changes: 56 additions & 0 deletions pkg/profile/profile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package profile

import (
"net"
"net/http"
"net/http/pprof"
"os"
"strconv"
"time"

"k8s.io/klog/v2"

"github.com/kubeedge/edgemesh/pkg/apis/config/v1alpha1"
)

const (
// ReadHeaderTimeout is the amount of time allowed to read
// request headers.
// HTTP timeouts are necessary to expire inactive connections
// and failing to do so might make the application vulnerable
// to attacks like slowloris which work by sending data very slow,
// which in case of no timeout will keep the connection active
// eventually leading to a denial-of-service (DoS) attack.
// References:
// - https://en.wikipedia.org/wiki/Slowloris_(computer_security)
ReadHeaderTimeout = 32 * time.Second
)

func installHandlerForPProf(mux *http.ServeMux) {
mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
}

// ListenAndServer start a http server to enable pprof.
func ListenAndServer(pprofconfig *v1alpha1.PprofConfig) {
if pprofconfig != nil && pprofconfig.EnableProfiling {
mux := http.NewServeMux()
installHandlerForPProf(mux)
addr := net.JoinHostPort(pprofconfig.ProfilingAddress, strconv.Itoa(pprofconfig.ProfilingPort))
klog.Infof("Starting profiling on address %s", addr)
go func() {
httpServer := http.Server{
Addr: addr,
Handler: mux,
ReadHeaderTimeout: ReadHeaderTimeout,
}
if err := httpServer.ListenAndServe(); err != nil {
klog.Errorf("Failed to start profiling server: %v", err)
os.Exit(1)
}
}()
}
}

0 comments on commit 3d3c919

Please sign in to comment.