Skip to content

Commit 036e93b

Browse files
committed
cmd/go: add go telemetry command and GOTELEMETRY, GOTELEMETRYDIR
Add the go telemetry command to support setting and viewing the telemetry mode. Also add the non-settable GOTELEMETRY and GOTELEMETRYDIR variables to go env, which contain the mode and telemetry dir. For #67111 Change-Id: Id7e89cefe30acfe3d865fa467315fe7cda975de9 Reviewed-on: https://go-review.googlesource.com/c/go/+/584535 Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: Sam Thanawalla <samthanawalla@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
1 parent 26ed052 commit 036e93b

File tree

7 files changed

+219
-0
lines changed

7 files changed

+219
-0
lines changed

src/cmd/go/alldocs.go

Lines changed: 33 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/go/internal/envcmd/env.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"cmd/go/internal/modload"
3030
"cmd/go/internal/work"
3131
"cmd/internal/quoted"
32+
"cmd/internal/telemetry"
3233
)
3334

3435
var CmdEnv = &base.Command{
@@ -110,6 +111,8 @@ func MkEnv() []cfg.EnvVar {
110111
{Name: "GOVCS", Value: cfg.GOVCS},
111112
{Name: "GOVERSION", Value: runtime.Version()},
112113
{Name: "GODEBUG", Value: os.Getenv("GODEBUG")},
114+
{Name: "GOTELEMETRY", Value: telemetry.Mode()},
115+
{Name: "GOTELEMETRYDIR", Value: telemetry.Dir()},
113116
}
114117

115118
for i := range env {
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright 2024 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// Package telemetrycmd implements the "go telemetry" command.
6+
package telemetrycmd
7+
8+
import (
9+
"context"
10+
"fmt"
11+
"os"
12+
13+
"cmd/go/internal/base"
14+
"cmd/internal/telemetry"
15+
)
16+
17+
var CmdTelemetry = &base.Command{
18+
UsageLine: "go telemetry [off|local|on]",
19+
Short: "manage telemetry data and settings",
20+
Long: `Telemetry is used to manage Go telemetry data and settings.
21+
22+
Telemetry can be in one of three modes: off, local, or on.
23+
24+
When telemetry is in local mode, counter data is written to the local file
25+
system, but will not be uploaded to remote servers.
26+
27+
When telemetry is off, local counter data is neither collected nor uploaded.
28+
29+
When telemetry is on, telemetry data is written to the local file system
30+
and periodically sent to https://telemetry.go.dev/. Uploaded data is used to
31+
help improve the Go toolchain and related tools, and it will be published as
32+
part of a public dataset.
33+
34+
For more details, see https://telemetry.go.dev/privacy.
35+
This data is collected in accordance with the Google Privacy Policy
36+
(https://policies.google.com/privacy).
37+
38+
To view the current telemetry mode, run "go telemetry".
39+
To disable telemetry uploading, but keep local data collection, run
40+
"go telemetry local".
41+
To enable both collection and uploading, run “go telemetry on”.
42+
To disable both collection and uploading, run "go telemetry off".
43+
44+
See https://go.dev/doc/telemetry for more information on telemetry.
45+
`,
46+
Run: runTelemetry,
47+
}
48+
49+
func init() {
50+
base.AddChdirFlag(&CmdTelemetry.Flag)
51+
}
52+
53+
func runTelemetry(ctx context.Context, cmd *base.Command, args []string) {
54+
if len(args) == 0 {
55+
fmt.Println(telemetry.Mode())
56+
return
57+
}
58+
59+
if len(args) != 1 {
60+
cmd.Usage()
61+
}
62+
63+
mode := args[0]
64+
if mode != "local" && mode != "off" && mode != "on" {
65+
cmd.Usage()
66+
}
67+
if old := telemetry.Mode(); old == mode {
68+
return
69+
}
70+
71+
if err := telemetry.SetMode(mode); err != nil {
72+
base.Fatalf("go: failed to set the telemetry mode to %s: %v", mode, err)
73+
}
74+
if mode == "on" {
75+
fmt.Fprintln(os.Stderr, telemetryOnMessage())
76+
}
77+
}
78+
79+
func telemetryOnMessage() string {
80+
return `Telemetry uploading is now enabled and data will be periodically sent to
81+
https://telemetry.go.dev/. Uploaded data is used to help improve the Go
82+
toolchain and related tools, and it will be published as part of a public
83+
dataset.
84+
85+
For more details, see https://telemetry.go.dev/privacy.
86+
This data is collected in accordance with the Google Privacy Policy
87+
(https://policies.google.com/privacy).
88+
89+
To disable telemetry uploading, but keep local data collection, run
90+
“go telemetry local”.
91+
To disable both collection and uploading, run “go telemetry off“.`
92+
}

src/cmd/go/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"cmd/go/internal/modget"
3535
"cmd/go/internal/modload"
3636
"cmd/go/internal/run"
37+
"cmd/go/internal/telemetrycmd"
3738
"cmd/go/internal/test"
3839
"cmd/go/internal/tool"
3940
"cmd/go/internal/toolchain"
@@ -61,6 +62,7 @@ func init() {
6162
modcmd.CmdMod,
6263
workcmd.CmdWork,
6364
run.CmdRun,
65+
telemetrycmd.CmdTelemetry,
6466
test.CmdTest,
6567
tool.CmdTool,
6668
version.CmdVersion,
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Tests for the telemetry subcommand,
2+
3+
# The script test framework sets TEST_TELEMETRY_DIR (overriding the
4+
# default telemetry dir location) and then checks that at least one
5+
# counter has been written per script tests.
6+
# Run go before unsetting TEST_TELEMETRY_DIR to make the tests happy.
7+
# We want to unset it so the environment we're testing is as close
8+
# to a user's environment.
9+
go help telemetry
10+
env TEST_TELEMETRY_DIR=
11+
12+
# Set userconfig dir, which is determined by os.UserConfigDir.
13+
# The telemetry dir is determined using that.
14+
mkdir $WORK/userconfig
15+
env AppData=$WORK\userconfig # windows
16+
[GOOS:windows] env userconfig=$AppData
17+
env HOME=$WORK/userconfig # darwin,unix,ios
18+
[GOOS:darwin] env userconfig=$HOME'/Library/Application Support'
19+
[GOOS:ios] env userconfig=$HOME'/Library/Application Support'
20+
[!GOOS:windows] [!GOOS:darwin] [!GOOS:ios] [!GOOS:plan9] env userconfig=$HOME/.config
21+
env home=$WORK/userconfig # plan9
22+
[GOOS:plan9] env userconfig=$home/lib
23+
24+
go telemetry
25+
stdout 'local'
26+
27+
go telemetry off
28+
go telemetry
29+
stdout 'off'
30+
go env GOTELEMETRY
31+
stdout 'off'
32+
33+
go telemetry local
34+
go telemetry
35+
stdout 'local'
36+
go env GOTELEMETRY
37+
stdout 'local'
38+
39+
go telemetry on
40+
go telemetry
41+
stdout 'on'
42+
go env GOTELEMETRY
43+
stdout 'on'
44+
45+
go env
46+
stdout 'GOTELEMETRY=''?on''?'
47+
stdout 'GOTELEMETRYDIR=''?'$userconfig'[\\/]go[\\/]telemetry''?'
48+
! go env -w GOTELEMETRY=off
49+
stderr '^go: unknown go command variable GOTELEMETRY$'
50+
! go env -w GOTELEMETRYDIR=foo
51+
stderr '^go: unknown go command variable GOTELEMETRYDIR$'

src/cmd/internal/telemetry/telemetry.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,38 @@ func CountFlagValue(prefix string, flagSet flag.FlagSet, flagName string) {
7474
}
7575
})
7676
}
77+
78+
// Mode returns the current telemetry mode.
79+
//
80+
// The telemetry mode is a global value that controls both the local collection
81+
// and uploading of telemetry data. Possible mode values are:
82+
// - "on": both collection and uploading is enabled
83+
// - "local": collection is enabled, but uploading is disabled
84+
// - "off": both collection and uploading are disabled
85+
//
86+
// When mode is "on", or "local", telemetry data is written to the local file
87+
// system and may be inspected with the [gotelemetry] command.
88+
//
89+
// If an error occurs while reading the telemetry mode from the file system,
90+
// Mode returns the default value "local".
91+
//
92+
// [gotelemetry]: https://pkg.go.dev/golang.org/x/telemetry/cmd/gotelemetry
93+
func Mode() string {
94+
return telemetry.Mode()
95+
}
96+
97+
// SetMode sets the global telemetry mode to the given value.
98+
//
99+
// See the documentation of [Mode] for a description of the supported mode
100+
// values.
101+
//
102+
// An error is returned if the provided mode value is invalid, or if an error
103+
// occurs while persisting the mode value to the file system.
104+
func SetMode(mode string) error {
105+
return telemetry.SetMode(mode)
106+
}
107+
108+
// Dir returns the telemetry directory.
109+
func Dir() string {
110+
return telemetry.Dir()
111+
}

src/cmd/internal/telemetry/telemetry_bootstrap.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@ func NewCounter(name string) dummyCounter { retu
1919
func NewStackCounter(name string, depth int) dummyCounter { return dummyCounter{} }
2020
func CountFlags(name string, flagSet flag.FlagSet) {}
2121
func CountFlagValue(prefix string, flagSet flag.FlagSet, flagName string) {}
22+
func Mode() string { return "" }
23+
func SetMode(mode string) error { return nil }
24+
func Dir() string { return "" }

0 commit comments

Comments
 (0)