From 4b271f9c7195c9e700572e4ea43cf1121b12e6ee Mon Sep 17 00:00:00 2001 From: "Hana (Hyang-Ah) Kim" Date: Wed, 19 Jul 2023 14:18:26 -0400 Subject: [PATCH] gopls: add gopls/client telemetry counters These counters are incremented once per session when the LSP initialize message is received. This cl adds a new dependency on x/telemetry. Note that writing to the disk will be enabled when GOPLS_TELEMETRY_EXP is set. We plan to remove this condition once we are ready. Updates golang/go#61038 Change-Id: Ibb8ebbd039ab5ffbaa869dee01bee0ba5450f350 Reviewed-on: https://go-review.googlesource.com/c/tools/+/506635 Reviewed-by: Jamal Carvalho Reviewed-by: Alan Donovan Reviewed-by: Robert Findley TryBot-Result: Gopher Robot Run-TryBot: Hyang-Ah Hana Kim --- gopls/go.mod | 1 + gopls/go.sum | 3 ++ gopls/internal/lsp/general.go | 3 ++ gopls/internal/telemetry/telemetry.go | 52 +++++++++++++++++++++++++++ gopls/main.go | 2 ++ 5 files changed, 61 insertions(+) create mode 100644 gopls/internal/telemetry/telemetry.go diff --git a/gopls/go.mod b/gopls/go.mod index b3b6de4aa2b..d69f5f79169 100644 --- a/gopls/go.mod +++ b/gopls/go.mod @@ -10,6 +10,7 @@ require ( golang.org/x/mod v0.12.0 golang.org/x/sync v0.3.0 golang.org/x/sys v0.10.0 + golang.org/x/telemetry v0.0.0-20230728182230-e84a26264b60 golang.org/x/text v0.11.0 golang.org/x/tools v0.6.0 golang.org/x/vuln v0.0.0-20230110180137-6ad3e3d07815 diff --git a/gopls/go.sum b/gopls/go.sum index a35f816f93b..c139139a72f 100644 --- a/gopls/go.sum +++ b/gopls/go.sum @@ -54,6 +54,7 @@ golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -74,6 +75,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/telemetry v0.0.0-20230728182230-e84a26264b60 h1:OCiXqf7/gdoaS7dKppAtPxi783Ke/JIb+r20ZYGiEFg= +golang.org/x/telemetry v0.0.0-20230728182230-e84a26264b60/go.mod h1:kO7uNSGGmqCHII6C0TYfaLwSBIfcyhj53//nu0+Fy4A= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= diff --git a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go index 7486f24904a..b57992fed5e 100644 --- a/gopls/internal/lsp/general.go +++ b/gopls/internal/lsp/general.go @@ -22,6 +22,7 @@ import ( "golang.org/x/tools/gopls/internal/lsp/protocol" "golang.org/x/tools/gopls/internal/lsp/source" "golang.org/x/tools/gopls/internal/span" + "golang.org/x/tools/gopls/internal/telemetry" "golang.org/x/tools/internal/event" "golang.org/x/tools/internal/jsonrpc2" ) @@ -30,6 +31,8 @@ func (s *Server) initialize(ctx context.Context, params *protocol.ParamInitializ ctx, done := event.Start(ctx, "lsp.Server.initialize") defer done() + telemetry.RecordClientInfo(params) + s.stateMu.Lock() if s.state >= serverInitializing { defer s.stateMu.Unlock() diff --git a/gopls/internal/telemetry/telemetry.go b/gopls/internal/telemetry/telemetry.go new file mode 100644 index 00000000000..67ab45adb41 --- /dev/null +++ b/gopls/internal/telemetry/telemetry.go @@ -0,0 +1,52 @@ +// Copyright 2023 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 telemetry + +import ( + "os" + + "golang.org/x/telemetry/counter" + "golang.org/x/tools/gopls/internal/lsp/protocol" +) + +// Start starts telemetry instrumentation. +func Start() { + if os.Getenv("GOPLS_TELEMETRY_EXP") != "" { + counter.Open() + // TODO: add upload logic. + } +} + +// RecordClientInfo records gopls client info. +func RecordClientInfo(params *protocol.ParamInitialize) { + client := "gopls/client:other" + if params != nil && params.ClientInfo != nil { + switch params.ClientInfo.Name { + case "Visual Studio Code": + client = "gopls/client:vscode" + case "VSCodium": + client = "gopls/client:vscodium" + case "code-server": + // https://github.com/coder/code-server/blob/3cb92edc76ecc2cfa5809205897d93d4379b16a6/ci/build/build-vscode.sh#L19 + client = "gopls/client:code-server" + case "Eglot": + // https://lists.gnu.org/archive/html/bug-gnu-emacs/2023-03/msg00954.html + client = "gopls/client:eglot" + case "govim": + // https://github.com/govim/govim/pull/1189 + client = "gopls/client:govim" + case "Neovim": + // https://github.com/neovim/neovim/blob/42333ea98dfcd2994ee128a3467dfe68205154cd/runtime/lua/vim/lsp.lua#L1361 + client = "gopls/client:neovim" + case "coc.nvim": + // https://github.com/neoclide/coc.nvim/blob/3dc6153a85ed0f185abec1deb972a66af3fbbfb4/src/language-client/client.ts#L994 + client = "gopls/client:coc.nvim" + case "Sublime Text LSP": + // https://github.com/sublimelsp/LSP/blob/e608f878e7e9dd34aabe4ff0462540fadcd88fcc/plugin/core/sessions.py#L493 + client = "gopls/client:sublimetext" + } + } + counter.Inc(client) +} diff --git a/gopls/main.go b/gopls/main.go index 41c7cdbff84..32507f25e7f 100644 --- a/gopls/main.go +++ b/gopls/main.go @@ -19,10 +19,12 @@ import ( "golang.org/x/tools/gopls/internal/hooks" "golang.org/x/tools/gopls/internal/lsp/cmd" + "golang.org/x/tools/gopls/internal/telemetry" "golang.org/x/tools/internal/tool" ) func main() { + telemetry.Start() ctx := context.Background() tool.Main(ctx, cmd.New("gopls", "", nil, hooks.Options), os.Args[1:]) }