From 314ba7db0369e3cb8ba8b6a446f749c3ed55dae2 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Mon, 15 Apr 2019 16:12:59 +0200 Subject: [PATCH] lntest/harness: add method SaveProfilesPages SaveProfilesPages will write the active goroutines to files pprof-n-*.log. Co-authored-by: taketa <853211b@gmail.com> --- lntest/harness.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/lntest/harness.go b/lntest/harness.go index f2a486c8..210af104 100644 --- a/lntest/harness.go +++ b/lntest/harness.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "io/ioutil" + "net/http" "os" "strings" "sync" @@ -648,6 +649,60 @@ func (n *NetworkHarness) StopNode(node *HarnessNode) error { return node.stop() } +// SaveProfilesPages hits profiles pages of all active nodes and writes it to +// disk using a similar naming scheme as to the regular set of logs. +func (n *NetworkHarness) SaveProfilesPages() { + for _, node := range n.activeNodes { + if err := saveProfilesPage(node); err != nil { + fmt.Println(err) + } + } +} + +// saveProfilesPage saves the profiles page for the given node to file. +func saveProfilesPage(node *HarnessNode) error { + resp, err := http.Get( + fmt.Sprintf( + "http://localhost:%d/debug/pprof/goroutine?debug=1", + node.cfg.ProfilePort, + ), + ) + if err != nil { + return fmt.Errorf("Failed to get profile page "+ + "(node_id=%d, name=%s): %v\n", + node.NodeID, node.cfg.Name, err) + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return fmt.Errorf("Failed to read profile page "+ + "(node_id=%d, name=%s): %v\n", + node.NodeID, node.cfg.Name, err) + } + + fileName := fmt.Sprintf( + "pprof-%d-%s-%s.log", node.NodeID, node.cfg.Name, + hex.EncodeToString(node.PubKey[:logPubKeyBytes]), + ) + + logFile, err := os.Create(fileName) + if err != nil { + return fmt.Errorf("Failed to create file for profile page "+ + "(node_id=%d, name=%s): %v\n", + node.NodeID, node.cfg.Name, err) + } + defer logFile.Close() + + _, err = logFile.Write(body) + if err != nil { + return fmt.Errorf("Failed to save profile page "+ + "(node_id=%d, name=%s): %v\n", + node.NodeID, node.cfg.Name, err) + } + return nil +} + // TODO(roasbeef): add a WithChannel higher-order function? // * python-like context manager w.r.t using a channel within a test // * possibly adds more funds to the target wallet if the funds are not