diff options
author | Heschi Kreinick <heschi@google.com> | 2020-06-18 18:42:34 -0400 |
---|---|---|
committer | Heschi Kreinick <heschi@google.com> | 2020-06-19 18:00:37 +0000 |
commit | 8b7669898d7c1172aa248c0626ff2e5a3f33ced7 (patch) | |
tree | 204fe390e9353b9ac1a75b3c4a44143a2863e628 /internal/lsp/debug | |
parent | 6023b8da91ed4093207e7f49f7a48e0cde121f9b (diff) | |
download | golang-x-tools-8b7669898d7c1172aa248c0626ff2e5a3f33ced7.tar.gz |
internal/lsp/debug: save per-package stats in memory debug files
The per-package stats have proven pretty useful, and I don't want to
have to teach users how to save them. Create zip files and add them in.
Since some users may be sensitive about revealing any information about
the code, generate two variants: one with package names, and one
without.
Change-Id: Icc5631b4cebbbabfdd2fcea4a4cdf4f205dbcab9
Reviewed-on: https://go-review.googlesource.com/c/tools/+/239037
Run-TryBot: Heschi Kreinick <heschi@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'internal/lsp/debug')
-rw-r--r-- | internal/lsp/debug/serve.go | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/internal/lsp/debug/serve.go b/internal/lsp/debug/serve.go index deb8becb5..ea5a544b0 100644 --- a/internal/lsp/debug/serve.go +++ b/internal/lsp/debug/serve.go @@ -5,6 +5,7 @@ package debug import ( + "archive/zip" "bytes" "context" "fmt" @@ -410,36 +411,61 @@ func (i *Instance) MonitorMemory(ctx context.Context) { if mem.HeapAlloc < nextThresholdGiB*1<<30 { continue } - i.writeMemoryDebug(nextThresholdGiB) + if err := i.writeMemoryDebug(nextThresholdGiB, true); err != nil { + event.Error(ctx, "writing memory debug info", err) + } + if err := i.writeMemoryDebug(nextThresholdGiB, false); err != nil { + event.Error(ctx, "writing memory debug info", err) + } event.Log(ctx, fmt.Sprintf("Wrote memory usage debug info to %v", os.TempDir())) nextThresholdGiB++ } }() } -func (i *Instance) writeMemoryDebug(threshold uint64) error { - fname := func(t string) string { - return fmt.Sprintf("gopls.%d-%dGiB-%s", os.Getpid(), threshold, t) +func (i *Instance) writeMemoryDebug(threshold uint64, withNames bool) error { + suffix := "withnames" + if !withNames { + suffix = "nonames" + } + + filename := fmt.Sprintf("gopls.%d-%dGiB-%s.zip", os.Getpid(), threshold, suffix) + zipf, err := os.OpenFile(filepath.Join(os.TempDir(), filename), os.O_CREATE|os.O_RDWR, 0644) + if err != nil { + return err } + zipw := zip.NewWriter(zipf) - f, err := os.Create(filepath.Join(os.TempDir(), fname("heap.pb.gz"))) + f, err := zipw.Create("heap.pb.gz") if err != nil { return err } - defer f.Close() if err := rpprof.Lookup("heap").WriteTo(f, 0); err != nil { return err } - f, err = os.Create(filepath.Join(os.TempDir(), fname("goroutines.txt"))) + f, err = zipw.Create("goroutines.txt") if err != nil { return err } - defer f.Close() if err := rpprof.Lookup("goroutine").WriteTo(f, 1); err != nil { return err } - return nil + + for _, cache := range i.State.Caches() { + cf, err := zipw.Create(fmt.Sprintf("cache-%v.html", cache.ID())) + if err != nil { + return err + } + if _, err := cf.Write([]byte(cache.PackageStats(withNames))); err != nil { + return err + } + } + + if err := zipw.Close(); err != nil { + return err + } + return zipf.Close() } func makeGlobalExporter(stderr io.Writer) event.Exporter { @@ -687,7 +713,7 @@ var cacheTmpl = template.Must(template.Must(baseTemplate.Clone()).Parse(` <h2>memoize.Store entries</h2> <ul>{{range $k,$v := .MemStats}}<li>{{$k}} - {{$v}}</li>{{end}}</ul> <h2>Per-package usage - not accurate, for guidance only</h2> -{{.PackageStats}} +{{.PackageStats true}} {{end}} `)) |