diff --git a/cmd/cmdmain.go b/cmd/cmdmain.go index 90ba28cd155..c7b79e3b8a0 100644 --- a/cmd/cmdmain.go +++ b/cmd/cmdmain.go @@ -1,8 +1,15 @@ package main import ( + "fmt" "os" + "os/signal" "path/filepath" + "runtime/pprof" + "syscall" + "time" + + "k8s.io/klog/v2" "github.com/kubeovn/kube-ovn/cmd/controller" "github.com/kubeovn/kube-ovn/cmd/controller_health_check" @@ -24,18 +31,65 @@ const ( CmdOvnLeaderChecker = "kube-ovn-leader-checker" ) +const timeFormat = "2006-01-02_15:04:05" + +func dumpProfile() { + ch1 := make(chan os.Signal, 1) + ch2 := make(chan os.Signal, 1) + signal.Notify(ch1, syscall.SIGUSR1) + signal.Notify(ch2, syscall.SIGUSR2) + go func() { + for { + <-ch1 + name := fmt.Sprintf("cpu-profile-%s.pprof", time.Now().Format(timeFormat)) + f, err := os.Create(filepath.Join(os.TempDir(), name)) // #nosec G303,G304 + if err != nil { + klog.Errorf("failed to create cpu profile file: %v", err) + return + } + defer f.Close() + if err = pprof.StartCPUProfile(f); err != nil { + klog.Errorf("failed to start cpu profile: %v", err) + return + } + time.Sleep(30 * time.Second) + pprof.StopCPUProfile() + } + }() + go func() { + for { + <-ch2 + name := fmt.Sprintf("mem-profile-%s.pprof", time.Now().Format(timeFormat)) + f, err := os.Create(filepath.Join(os.TempDir(), name)) // #nosec G303,G304 + if err != nil { + klog.Errorf("failed to create memory profile file: %v", err) + return + } + defer f.Close() + if err = pprof.WriteHeapProfile(f); err != nil { + klog.Errorf("failed to write memory profile file: %v", err) + } + } + }() +} + func main() { cmd := filepath.Base(os.Args[0]) switch cmd { case CmdController: + dumpProfile() controller.CmdMain() case CmdDaemon: + dumpProfile() daemon.CmdMain() case CmdMonitor: + dumpProfile() ovn_monitor.CmdMain() case CmdPinger: + dumpProfile() pinger.CmdMain() case CmdSpeaker: + dumpProfile() speaker.CmdMain() case CmdControllerHealthCheck: controller_health_check.CmdMain()