aboutsummaryrefslogtreecommitdiff
path: root/internal/lsp/debug/rpc.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/lsp/debug/rpc.go')
-rw-r--r--internal/lsp/debug/rpc.go239
1 files changed, 0 insertions, 239 deletions
diff --git a/internal/lsp/debug/rpc.go b/internal/lsp/debug/rpc.go
deleted file mode 100644
index 033ee3797..000000000
--- a/internal/lsp/debug/rpc.go
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package debug
-
-import (
- "context"
- "fmt"
- "html/template"
- "net/http"
- "sort"
- "sync"
- "time"
-
- "golang.org/x/tools/internal/event"
- "golang.org/x/tools/internal/event/core"
- "golang.org/x/tools/internal/event/export"
- "golang.org/x/tools/internal/event/label"
- "golang.org/x/tools/internal/lsp/debug/tag"
-)
-
-var RPCTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(`
-{{define "title"}}RPC Information{{end}}
-{{define "body"}}
- <H2>Inbound</H2>
- {{template "rpcSection" .Inbound}}
- <H2>Outbound</H2>
- {{template "rpcSection" .Outbound}}
-{{end}}
-{{define "rpcSection"}}
- {{range .}}<P>
- <b>{{.Method}}</b> {{.Started}} <a href="/trace/{{.Method}}">traces</a> ({{.InProgress}} in progress)
- <br>
- <i>Latency</i> {{with .Latency}}{{.Mean}} ({{.Min}}<{{.Max}}){{end}}
- <i>By bucket</i> 0s {{range .Latency.Values}}{{if gt .Count 0}}<b>{{.Count}}</b> {{.Limit}} {{end}}{{end}}
- <br>
- <i>Received</i> {{.Received}} (avg. {{.ReceivedMean}})
- <i>Sent</i> {{.Sent}} (avg. {{.SentMean}})
- <br>
- <i>Result codes</i> {{range .Codes}}{{.Key}}={{.Count}} {{end}}
- </P>
- {{end}}
-{{end}}
-`))
-
-type Rpcs struct { // exported for testing
- mu sync.Mutex
- Inbound []*rpcStats // stats for incoming lsp rpcs sorted by method name
- Outbound []*rpcStats // stats for outgoing lsp rpcs sorted by method name
-}
-
-type rpcStats struct {
- Method string
- Started int64
- Completed int64
-
- Latency rpcTimeHistogram
- Received byteUnits
- Sent byteUnits
- Codes []*rpcCodeBucket
-}
-
-type rpcTimeHistogram struct {
- Sum timeUnits
- Count int64
- Min timeUnits
- Max timeUnits
- Values []rpcTimeBucket
-}
-
-type rpcTimeBucket struct {
- Limit timeUnits
- Count int64
-}
-
-type rpcCodeBucket struct {
- Key string
- Count int64
-}
-
-func (r *Rpcs) ProcessEvent(ctx context.Context, ev core.Event, lm label.Map) context.Context {
- r.mu.Lock()
- defer r.mu.Unlock()
- switch {
- case event.IsStart(ev):
- if _, stats := r.getRPCSpan(ctx, ev); stats != nil {
- stats.Started++
- }
- case event.IsEnd(ev):
- span, stats := r.getRPCSpan(ctx, ev)
- if stats != nil {
- endRPC(ctx, ev, span, stats)
- }
- case event.IsMetric(ev):
- sent := byteUnits(tag.SentBytes.Get(lm))
- rec := byteUnits(tag.ReceivedBytes.Get(lm))
- if sent != 0 || rec != 0 {
- if _, stats := r.getRPCSpan(ctx, ev); stats != nil {
- stats.Sent += sent
- stats.Received += rec
- }
- }
- }
- return ctx
-}
-
-func endRPC(ctx context.Context, ev core.Event, span *export.Span, stats *rpcStats) {
- // update the basic counts
- stats.Completed++
-
- // get and record the status code
- if status := getStatusCode(span); status != "" {
- var b *rpcCodeBucket
- for c, entry := range stats.Codes {
- if entry.Key == status {
- b = stats.Codes[c]
- break
- }
- }
- if b == nil {
- b = &rpcCodeBucket{Key: status}
- stats.Codes = append(stats.Codes, b)
- sort.Slice(stats.Codes, func(i int, j int) bool {
- return stats.Codes[i].Key < stats.Codes[j].Key
- })
- }
- b.Count++
- }
-
- // calculate latency if this was an rpc span
- elapsedTime := span.Finish().At().Sub(span.Start().At())
- latencyMillis := timeUnits(elapsedTime) / timeUnits(time.Millisecond)
- if stats.Latency.Count == 0 {
- stats.Latency.Min = latencyMillis
- stats.Latency.Max = latencyMillis
- } else {
- if stats.Latency.Min > latencyMillis {
- stats.Latency.Min = latencyMillis
- }
- if stats.Latency.Max < latencyMillis {
- stats.Latency.Max = latencyMillis
- }
- }
- stats.Latency.Count++
- stats.Latency.Sum += latencyMillis
- for i := range stats.Latency.Values {
- if stats.Latency.Values[i].Limit > latencyMillis {
- stats.Latency.Values[i].Count++
- break
- }
- }
-}
-
-func (r *Rpcs) getRPCSpan(ctx context.Context, ev core.Event) (*export.Span, *rpcStats) {
- // get the span
- span := export.GetSpan(ctx)
- if span == nil {
- return nil, nil
- }
- // use the span start event look up the correct stats block
- // we do this because it prevents us matching a sub span
- return span, r.getRPCStats(span.Start())
-}
-
-func (r *Rpcs) getRPCStats(lm label.Map) *rpcStats {
- method := tag.Method.Get(lm)
- if method == "" {
- return nil
- }
- set := &r.Inbound
- if tag.RPCDirection.Get(lm) != tag.Inbound {
- set = &r.Outbound
- }
- // get the record for this method
- index := sort.Search(len(*set), func(i int) bool {
- return (*set)[i].Method >= method
- })
-
- if index < len(*set) && (*set)[index].Method == method {
- return (*set)[index]
- }
-
- old := *set
- *set = make([]*rpcStats, len(old)+1)
- copy(*set, old[:index])
- copy((*set)[index+1:], old[index:])
- stats := &rpcStats{Method: method}
- stats.Latency.Values = make([]rpcTimeBucket, len(millisecondsDistribution))
- for i, m := range millisecondsDistribution {
- stats.Latency.Values[i].Limit = timeUnits(m)
- }
- (*set)[index] = stats
- return stats
-}
-
-func (s *rpcStats) InProgress() int64 { return s.Started - s.Completed }
-func (s *rpcStats) SentMean() byteUnits { return s.Sent / byteUnits(s.Started) }
-func (s *rpcStats) ReceivedMean() byteUnits { return s.Received / byteUnits(s.Started) }
-
-func (h *rpcTimeHistogram) Mean() timeUnits { return h.Sum / timeUnits(h.Count) }
-
-func getStatusCode(span *export.Span) string {
- for _, ev := range span.Events() {
- if status := tag.StatusCode.Get(ev); status != "" {
- return status
- }
- }
- return ""
-}
-
-func (r *Rpcs) getData(req *http.Request) interface{} {
- return r
-}
-
-func units(v float64, suffixes []string) string {
- s := ""
- for _, s = range suffixes {
- n := v / 1000
- if n < 1 {
- break
- }
- v = n
- }
- return fmt.Sprintf("%.2f%s", v, s)
-}
-
-type timeUnits float64
-
-func (v timeUnits) String() string {
- v = v * 1000 * 1000
- return units(float64(v), []string{"ns", "μs", "ms", "s"})
-}
-
-type byteUnits float64
-
-func (v byteUnits) String() string {
- return units(float64(v), []string{"B", "KB", "MB", "GB", "TB"})
-}