aboutsummaryrefslogtreecommitdiff
path: root/internal/lsp/debug
diff options
context:
space:
mode:
authorHeschi Kreinick <heschi@google.com>2020-06-18 18:42:34 -0400
committerHeschi Kreinick <heschi@google.com>2020-06-19 18:00:37 +0000
commit8b7669898d7c1172aa248c0626ff2e5a3f33ced7 (patch)
tree204fe390e9353b9ac1a75b3c4a44143a2863e628 /internal/lsp/debug
parent6023b8da91ed4093207e7f49f7a48e0cde121f9b (diff)
downloadgolang-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.go46
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}}
`))