Skip to content

Commit f796361

Browse files
committed
gopls/internal/lsp: add tracing instrumentation for all Server methods
While debugging the gopls/internal/lsp tests, I noticed that I was not seeing useful user defined tasks in the trace viewer. The reasons for this were that (1) we were disabling all instrumentation of the event package, and (2) we didn't have top-level tasks for each jsonrcp2 method, because the tests call into the Server directly. Fix this by re-enabling the exporter in gopls/internal/lsp tests (using a debug.Instance to suppress logging to stderr), and by instrumenting all server methods with a top-level span. Some were already instrumented, but it was inconsistent. Another advantage to instrumenting server methods in addition to jsonrpc2 methods, is that they can add labels specific to the request, such as the text document URI. Also add some instrumentation of key snapshot methods. Change-Id: I992a6a86b175b766e6cbff8c2f2c4a5a35b5d0cf Reviewed-on: https://go-review.googlesource.com/c/tools/+/480198 Reviewed-by: Peter Weinberger <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Robert Findley <[email protected]>
1 parent e104501 commit f796361

31 files changed

+179
-33
lines changed

gopls/internal/lsp/cache/check.go

+15
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,9 @@ func (s *snapshot) getImportGraph(ctx context.Context) *importGraph {
188188
// resolveImportGraph should only be called from getImportGraph.
189189
func (s *snapshot) resolveImportGraph() (*importGraph, error) {
190190
ctx := s.backgroundCtx
191+
ctx, done := event.Start(event.Detach(ctx), "cache.resolveImportGraph")
192+
defer done()
193+
191194
if err := s.awaitLoaded(ctx); err != nil {
192195
return nil, err
193196
}
@@ -334,6 +337,9 @@ type (
334337
//
335338
// Both pre and post may be called concurrently.
336339
func (s *snapshot) forEachPackage(ctx context.Context, ids []PackageID, pre preTypeCheck, post postTypeCheck) error {
340+
ctx, done := event.Start(ctx, "cache.forEachPackage", tag.PackageCount.Of(len(ids)))
341+
defer done()
342+
337343
if len(ids) == 0 {
338344
return nil // short cut: many call sites do not handle empty ids
339345
}
@@ -534,6 +540,9 @@ func (b *typeCheckBatch) handleSyntaxPackage(ctx context.Context, i int, id Pack
534540
// importPackage loads the given package from its export data in p.exportData
535541
// (which must already be populated).
536542
func (b *typeCheckBatch) importPackage(ctx context.Context, m *source.Metadata, data []byte) (*types.Package, error) {
543+
ctx, done := event.Start(ctx, "cache.typeCheckBatch.importPackage", tag.Package.Of(string(m.ID)))
544+
defer done()
545+
537546
impMap := b.importMap(m.ID)
538547

539548
var firstErr error // TODO(rfindley): unused: revisit or remove.
@@ -580,6 +589,9 @@ func (b *typeCheckBatch) importPackage(ctx context.Context, m *source.Metadata,
580589
// checkPackageForImport type checks, but skips function bodies and does not
581590
// record syntax information.
582591
func (b *typeCheckBatch) checkPackageForImport(ctx context.Context, ph *packageHandle) (*types.Package, error) {
592+
ctx, done := event.Start(ctx, "cache.typeCheckBatch.checkPackageForImport", tag.Package.Of(string(ph.m.ID)))
593+
defer done()
594+
583595
onError := func(e error) {
584596
// Ignore errors for exporting.
585597
}
@@ -627,6 +639,9 @@ func (b *typeCheckBatch) checkPackageForImport(ctx context.Context, ph *packageH
627639

628640
// checkPackage "fully type checks" to produce a syntax package.
629641
func (b *typeCheckBatch) checkPackage(ctx context.Context, ph *packageHandle) (*Package, error) {
642+
ctx, done := event.Start(ctx, "cache.typeCheckBatch.checkPackage", tag.Package.Of(string(ph.m.ID)))
643+
defer done()
644+
630645
// TODO(rfindley): refactor to inline typeCheckImpl here. There is no need
631646
// for so many layers to build up the package
632647
// (checkPackage->typeCheckImpl->doTypeCheck).

gopls/internal/lsp/cache/load.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func (s *snapshot) load(ctx context.Context, allowNetwork bool, scopes ...loadSc
103103
}
104104
sort.Strings(query) // for determinism
105105

106-
ctx, done := event.Start(ctx, "cache.view.load", tag.Query.Of(query))
106+
ctx, done := event.Start(ctx, "cache.snapshot.load", tag.Query.Of(query))
107107
defer done()
108108

109109
flags := source.LoadWorkspace

gopls/internal/lsp/cache/mod_tidy.go

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ import (
2929
// ModTidy returns the go.mod file that would be obtained by running
3030
// "go mod tidy". Concurrent requests are combined into a single command.
3131
func (s *snapshot) ModTidy(ctx context.Context, pm *source.ParsedModule) (*source.TidiedModule, error) {
32+
ctx, done := event.Start(ctx, "cache.snapshot.ModTidy")
33+
defer done()
34+
3235
uri := pm.URI
3336
if pm.File == nil {
3437
return nil, fmt.Errorf("cannot tidy unparseable go.mod file: %v", uri)

gopls/internal/lsp/cache/parse.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,6 @@ func (s *snapshot) ParseGo(ctx context.Context, fh source.FileHandle, mode parse
3636

3737
// parseGoImpl parses the Go source file whose content is provided by fh.
3838
func parseGoImpl(ctx context.Context, fset *token.FileSet, fh source.FileHandle, mode parser.Mode) (*source.ParsedGoFile, error) {
39-
ctx, done := event.Start(ctx, "cache.parseGo", tag.File.Of(fh.URI().Filename()))
40-
defer done()
41-
4239
ext := filepath.Ext(fh.URI().Filename())
4340
if ext != ".go" && ext != "" { // files generated by cgo have no extension
4441
return nil, fmt.Errorf("cannot parse non-Go file %s", fh.URI())
@@ -59,6 +56,9 @@ func parseGoImpl(ctx context.Context, fset *token.FileSet, fh source.FileHandle,
5956
//
6057
// The provided ctx is used only for logging.
6158
func ParseGoSrc(ctx context.Context, fset *token.FileSet, uri span.URI, src []byte, mode parser.Mode) (res *source.ParsedGoFile, fixes []fixType) {
59+
ctx, done := event.Start(ctx, "cache.ParseGoSrc", tag.File.Of(uri.Filename()))
60+
defer done()
61+
6262
file, err := parser.ParseFile(fset, uri.Filename(), src, mode)
6363
var parseErr scanner.ErrorList
6464
if err != nil {

gopls/internal/lsp/cache/parse_cache.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ func (c *parseCache) startParse(mode parser.Mode, fhs ...source.FileHandle) ([]*
161161
}
162162

163163
uri := fh.URI()
164-
promise := memoize.NewPromise(fmt.Sprintf("parse(%s)", uri), func(ctx context.Context, _ interface{}) interface{} {
164+
promise := memoize.NewPromise("parseCache.parse", func(ctx context.Context, _ interface{}) interface{} {
165165
// Allocate 2*len(content)+parsePadding to allow for re-parsing once
166166
// inside of parseGoSrc without exceeding the allocated space.
167167
base, nextBase := c.allocateSpace(2*len(content) + parsePadding)

gopls/internal/lsp/cache/snapshot.go

+13-1
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,9 @@ const (
657657
)
658658

659659
func (s *snapshot) PackageDiagnostics(ctx context.Context, ids ...PackageID) (map[span.URI][]*source.Diagnostic, error) {
660+
ctx, done := event.Start(ctx, "cache.snapshot.PackageDiagnostics")
661+
defer done()
662+
660663
var mu sync.Mutex
661664
perFile := make(map[span.URI][]*source.Diagnostic)
662665
collect := func(diags []*source.Diagnostic) {
@@ -685,6 +688,9 @@ func (s *snapshot) PackageDiagnostics(ctx context.Context, ids ...PackageID) (ma
685688
}
686689

687690
func (s *snapshot) References(ctx context.Context, ids ...PackageID) ([]source.XrefIndex, error) {
691+
ctx, done := event.Start(ctx, "cache.snapshot.References")
692+
defer done()
693+
688694
indexes := make([]source.XrefIndex, len(ids))
689695
pre := func(i int, ph *packageHandle) bool {
690696
data, err := filecache.Get(xrefsKind, ph.key)
@@ -713,6 +719,9 @@ func (index XrefIndex) Lookup(targets map[PackagePath]map[objectpath.Path]struct
713719
}
714720

715721
func (s *snapshot) MethodSets(ctx context.Context, ids ...PackageID) ([]*methodsets.Index, error) {
722+
ctx, done := event.Start(ctx, "cache.snapshot.MethodSets")
723+
defer done()
724+
716725
indexes := make([]*methodsets.Index, len(ids))
717726
pre := func(i int, ph *packageHandle) bool {
718727
data, err := filecache.Get(methodSetsKind, ph.key)
@@ -731,6 +740,9 @@ func (s *snapshot) MethodSets(ctx context.Context, ids ...PackageID) ([]*methods
731740
}
732741

733742
func (s *snapshot) MetadataForFile(ctx context.Context, uri span.URI) ([]*source.Metadata, error) {
743+
ctx, done := event.Start(ctx, "cache.snapshot.MetadataForFile")
744+
defer done()
745+
734746
s.mu.Lock()
735747

736748
// Start with the set of package associations derived from the last load.
@@ -1689,7 +1701,7 @@ func (ac *unappliedChanges) ReadFile(ctx context.Context, uri span.URI) (source.
16891701
}
16901702

16911703
func (s *snapshot) clone(ctx, bgCtx context.Context, changes map[span.URI]*fileChange, forceReloadMetadata bool) (*snapshot, func()) {
1692-
ctx, done := event.Start(ctx, "snapshot.clone")
1704+
ctx, done := event.Start(ctx, "cache.snapshot.clone")
16931705
defer done()
16941706

16951707
reinit := false

gopls/internal/lsp/call_hierarchy.go

+10
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@ import (
99

1010
"golang.org/x/tools/gopls/internal/lsp/protocol"
1111
"golang.org/x/tools/gopls/internal/lsp/source"
12+
"golang.org/x/tools/internal/event"
1213
)
1314

1415
func (s *Server) prepareCallHierarchy(ctx context.Context, params *protocol.CallHierarchyPrepareParams) ([]protocol.CallHierarchyItem, error) {
16+
ctx, done := event.Start(ctx, "lsp.Server.prepareCallHierarchy")
17+
defer done()
18+
1519
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go)
1620
defer release()
1721
if !ok {
@@ -22,6 +26,9 @@ func (s *Server) prepareCallHierarchy(ctx context.Context, params *protocol.Call
2226
}
2327

2428
func (s *Server) incomingCalls(ctx context.Context, params *protocol.CallHierarchyIncomingCallsParams) ([]protocol.CallHierarchyIncomingCall, error) {
29+
ctx, done := event.Start(ctx, "lsp.Server.incomingCalls")
30+
defer done()
31+
2532
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.Item.URI, source.Go)
2633
defer release()
2734
if !ok {
@@ -32,6 +39,9 @@ func (s *Server) incomingCalls(ctx context.Context, params *protocol.CallHierarc
3239
}
3340

3441
func (s *Server) outgoingCalls(ctx context.Context, params *protocol.CallHierarchyOutgoingCallsParams) ([]protocol.CallHierarchyOutgoingCall, error) {
42+
ctx, done := event.Start(ctx, "lsp.Server.outgoingCalls")
43+
defer done()
44+
3545
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.Item.URI, source.Go)
3646
defer release()
3747
if !ok {

gopls/internal/lsp/code_action.go

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import (
2121
)
2222

2323
func (s *Server) codeAction(ctx context.Context, params *protocol.CodeActionParams) ([]protocol.CodeAction, error) {
24+
ctx, done := event.Start(ctx, "lsp.Server.codeAction")
25+
defer done()
26+
2427
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind)
2528
defer release()
2629
if !ok {

gopls/internal/lsp/code_lens.go

+4
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@ import (
1414
"golang.org/x/tools/gopls/internal/lsp/protocol"
1515
"golang.org/x/tools/gopls/internal/lsp/source"
1616
"golang.org/x/tools/internal/event"
17+
"golang.org/x/tools/internal/event/tag"
1718
)
1819

1920
func (s *Server) codeLens(ctx context.Context, params *protocol.CodeLensParams) ([]protocol.CodeLens, error) {
21+
ctx, done := event.Start(ctx, "lsp.Server.codeLens", tag.URI.Of(params.TextDocument.URI))
22+
defer done()
23+
2024
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind)
2125
defer release()
2226
if !ok {

gopls/internal/lsp/command.go

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ import (
3737
)
3838

3939
func (s *Server) executeCommand(ctx context.Context, params *protocol.ExecuteCommandParams) (interface{}, error) {
40+
ctx, done := event.Start(ctx, "lsp.Server.executeCommand")
41+
defer done()
42+
4043
var found bool
4144
for _, name := range s.session.Options().SupportedCommands {
4245
if name == params.Command {

gopls/internal/lsp/completion.go

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ import (
1919
)
2020

2121
func (s *Server) completion(ctx context.Context, params *protocol.CompletionParams) (*protocol.CompletionList, error) {
22+
ctx, done := event.Start(ctx, "lsp.Server.completion", tag.URI.Of(params.TextDocument.URI))
23+
defer done()
24+
2225
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind)
2326
defer release()
2427
if !ok {

gopls/internal/lsp/definition.go

+8
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@ import (
1212
"golang.org/x/tools/gopls/internal/lsp/protocol"
1313
"golang.org/x/tools/gopls/internal/lsp/source"
1414
"golang.org/x/tools/gopls/internal/lsp/template"
15+
"golang.org/x/tools/internal/event"
16+
"golang.org/x/tools/internal/event/tag"
1517
)
1618

1719
func (s *Server) definition(ctx context.Context, params *protocol.DefinitionParams) ([]protocol.Location, error) {
20+
ctx, done := event.Start(ctx, "lsp.Server.definition", tag.URI.Of(params.TextDocument.URI))
21+
defer done()
22+
1823
// TODO(rfindley): definition requests should be multiplexed across all views.
1924
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind)
2025
defer release()
@@ -37,6 +42,9 @@ func (s *Server) definition(ctx context.Context, params *protocol.DefinitionPara
3742
}
3843

3944
func (s *Server) typeDefinition(ctx context.Context, params *protocol.TypeDefinitionParams) ([]protocol.Location, error) {
45+
ctx, done := event.Start(ctx, "lsp.Server.typeDefinition", tag.URI.Of(params.TextDocument.URI))
46+
defer done()
47+
4048
// TODO(rfindley): type definition requests should be multiplexed across all views.
4149
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go)
4250
defer release()

gopls/internal/lsp/folding_range.go

+5
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@ import (
99

1010
"golang.org/x/tools/gopls/internal/lsp/protocol"
1111
"golang.org/x/tools/gopls/internal/lsp/source"
12+
"golang.org/x/tools/internal/event"
13+
"golang.org/x/tools/internal/event/tag"
1214
)
1315

1416
func (s *Server) foldingRange(ctx context.Context, params *protocol.FoldingRangeParams) ([]protocol.FoldingRange, error) {
17+
ctx, done := event.Start(ctx, "lsp.Server.foldingRange", tag.URI.Of(params.TextDocument.URI))
18+
defer done()
19+
1520
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go)
1621
defer release()
1722
if !ok {

gopls/internal/lsp/format.go

+5
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,14 @@ import (
1111
"golang.org/x/tools/gopls/internal/lsp/protocol"
1212
"golang.org/x/tools/gopls/internal/lsp/source"
1313
"golang.org/x/tools/gopls/internal/lsp/work"
14+
"golang.org/x/tools/internal/event"
15+
"golang.org/x/tools/internal/event/tag"
1416
)
1517

1618
func (s *Server) formatting(ctx context.Context, params *protocol.DocumentFormattingParams) ([]protocol.TextEdit, error) {
19+
ctx, done := event.Start(ctx, "lsp.Server.formatting", tag.URI.Of(params.TextDocument.URI))
20+
defer done()
21+
1722
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind)
1823
defer release()
1924
if !ok {

gopls/internal/lsp/general.go

+12
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ import (
2626
)
2727

2828
func (s *Server) initialize(ctx context.Context, params *protocol.ParamInitialize) (*protocol.InitializeResult, error) {
29+
ctx, done := event.Start(ctx, "lsp.Server.initialize")
30+
defer done()
31+
2932
s.stateMu.Lock()
3033
if s.state >= serverInitializing {
3134
defer s.stateMu.Unlock()
@@ -192,6 +195,9 @@ See https://github.com/golang/go/issues/45732 for more information.`,
192195
}
193196

194197
func (s *Server) initialized(ctx context.Context, params *protocol.InitializedParams) error {
198+
ctx, done := event.Start(ctx, "lsp.Server.initialized")
199+
defer done()
200+
195201
s.stateMu.Lock()
196202
if s.state >= serverInitialized {
197203
defer s.stateMu.Unlock()
@@ -585,6 +591,9 @@ func (s *Server) beginFileRequest(ctx context.Context, pURI protocol.DocumentURI
585591
// shutdown implements the 'shutdown' LSP handler. It releases resources
586592
// associated with the server and waits for all ongoing work to complete.
587593
func (s *Server) shutdown(ctx context.Context) error {
594+
ctx, done := event.Start(ctx, "lsp.Server.shutdown")
595+
defer done()
596+
588597
s.stateMu.Lock()
589598
defer s.stateMu.Unlock()
590599
if s.state < serverInitialized {
@@ -604,6 +613,9 @@ func (s *Server) shutdown(ctx context.Context) error {
604613
}
605614

606615
func (s *Server) exit(ctx context.Context) error {
616+
ctx, done := event.Start(ctx, "lsp.Server.exit")
617+
defer done()
618+
607619
s.stateMu.Lock()
608620
defer s.stateMu.Unlock()
609621

gopls/internal/lsp/highlight.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@ package lsp
77
import (
88
"context"
99

10-
"golang.org/x/tools/internal/event"
11-
"golang.org/x/tools/internal/event/tag"
1210
"golang.org/x/tools/gopls/internal/lsp/protocol"
1311
"golang.org/x/tools/gopls/internal/lsp/source"
1412
"golang.org/x/tools/gopls/internal/lsp/template"
13+
"golang.org/x/tools/internal/event"
14+
"golang.org/x/tools/internal/event/tag"
1515
)
1616

1717
func (s *Server) documentHighlight(ctx context.Context, params *protocol.DocumentHighlightParams) ([]protocol.DocumentHighlight, error) {
18+
ctx, done := event.Start(ctx, "lsp.Server.documentHighlight", tag.URI.Of(params.TextDocument.URI))
19+
defer done()
20+
1821
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go)
1922
defer release()
2023
if !ok {
@@ -27,7 +30,7 @@ func (s *Server) documentHighlight(ctx context.Context, params *protocol.Documen
2730

2831
rngs, err := source.Highlight(ctx, snapshot, fh, params.Position)
2932
if err != nil {
30-
event.Error(ctx, "no highlight", err, tag.URI.Of(params.TextDocument.URI))
33+
event.Error(ctx, "no highlight", err)
3134
}
3235
return toProtocolHighlight(rngs), nil
3336
}

gopls/internal/lsp/hover.go

+5
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,14 @@ import (
1212
"golang.org/x/tools/gopls/internal/lsp/source"
1313
"golang.org/x/tools/gopls/internal/lsp/template"
1414
"golang.org/x/tools/gopls/internal/lsp/work"
15+
"golang.org/x/tools/internal/event"
16+
"golang.org/x/tools/internal/event/tag"
1517
)
1618

1719
func (s *Server) hover(ctx context.Context, params *protocol.HoverParams) (*protocol.Hover, error) {
20+
ctx, done := event.Start(ctx, "lsp.Server.hover", tag.URI.Of(params.TextDocument.URI))
21+
defer done()
22+
1823
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind)
1924
defer release()
2025
if !ok {

gopls/internal/lsp/implementation.go

+5
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@ import (
99

1010
"golang.org/x/tools/gopls/internal/lsp/protocol"
1111
"golang.org/x/tools/gopls/internal/lsp/source"
12+
"golang.org/x/tools/internal/event"
13+
"golang.org/x/tools/internal/event/tag"
1214
)
1315

1416
func (s *Server) implementation(ctx context.Context, params *protocol.ImplementationParams) ([]protocol.Location, error) {
17+
ctx, done := event.Start(ctx, "lsp.Server.implementation", tag.URI.Of(params.TextDocument.URI))
18+
defer done()
19+
1520
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go)
1621
defer release()
1722
if !ok {

gopls/internal/lsp/inlay_hint.go

+5
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@ import (
1010
"golang.org/x/tools/gopls/internal/lsp/mod"
1111
"golang.org/x/tools/gopls/internal/lsp/protocol"
1212
"golang.org/x/tools/gopls/internal/lsp/source"
13+
"golang.org/x/tools/internal/event"
14+
"golang.org/x/tools/internal/event/tag"
1315
)
1416

1517
func (s *Server) inlayHint(ctx context.Context, params *protocol.InlayHintParams) ([]protocol.InlayHint, error) {
18+
ctx, done := event.Start(ctx, "lsp.Server.inlayHint", tag.URI.Of(params.TextDocument.URI))
19+
defer done()
20+
1621
snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind)
1722
defer release()
1823
if !ok {

0 commit comments

Comments
 (0)