]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: add go telemetry command and GOTELEMETRY, GOTELEMETRYDIR
authorMichael Matloob <matloob@golang.org>
Wed, 8 May 2024 19:54:12 +0000 (15:54 -0400)
committerMichael Matloob <matloob@golang.org>
Thu, 16 May 2024 20:16:39 +0000 (20:16 +0000)
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>

src/cmd/go/alldocs.go
src/cmd/go/internal/envcmd/env.go
src/cmd/go/internal/telemetrycmd/telemetry.go [new file with mode: 0644]
src/cmd/go/main.go
src/cmd/go/testdata/script/telemetry.txt [new file with mode: 0644]
src/cmd/internal/telemetry/telemetry.go
src/cmd/internal/telemetry/telemetry_bootstrap.go

index 9263be5a6bcc401ef497e091c98261f3574fd274..52fb4c25a82c9afe125381629aa997a17a31b370 100644 (file)
@@ -27,6 +27,7 @@
 //     mod         module maintenance
 //     work        workspace maintenance
 //     run         compile and run Go program
+//     telemetry   manage telemetry data and settings
 //     test        test packages
 //     tool        run specified go tool
 //     version     print Go version
 //
 // See also: go build.
 //
+// # Manage telemetry data and settings
+//
+// Usage:
+//
+//     go telemetry [off|local|on]
+//
+// Telemetry is used to manage Go telemetry data and settings.
+//
+// Telemetry can be in one of three modes: off, local, or on.
+//
+// When telemetry is in local mode, counter data is written to the local file
+// system, but will not be uploaded to remote servers.
+//
+// When telemetry is off, local counter data is neither collected nor uploaded.
+//
+// When telemetry is on, telemetry data is written to the local file system
+// and periodically sent to https://telemetry.go.dev/. Uploaded data is used to
+// help improve the Go toolchain and related tools, and it will be published as
+// part of a public dataset.
+//
+// For more details, see https://telemetry.go.dev/privacy.
+// This data is collected in accordance with the Google Privacy Policy
+// (https://policies.google.com/privacy).
+//
+// To view the current telemetry mode, run "go telemetry".
+// To disable telemetry uploading, but keep local data collection, run
+// "go telemetry local".
+// To enable both collection and uploading, run “go telemetry on”.
+// To disable both collection and uploading, run "go telemetry off".
+//
+// See https://go.dev/doc/telemetry for more information on telemetry.
+//
 // # Test packages
 //
 // Usage:
index c271353dc7c5d4f482afb5542481876ae0fa6e59..b25010a29a508a4cd171780edb8e10beea2d15e9 100644 (file)
@@ -29,6 +29,7 @@ import (
        "cmd/go/internal/modload"
        "cmd/go/internal/work"
        "cmd/internal/quoted"
+       "cmd/internal/telemetry"
 )
 
 var CmdEnv = &base.Command{
@@ -110,6 +111,8 @@ func MkEnv() []cfg.EnvVar {
                {Name: "GOVCS", Value: cfg.GOVCS},
                {Name: "GOVERSION", Value: runtime.Version()},
                {Name: "GODEBUG", Value: os.Getenv("GODEBUG")},
+               {Name: "GOTELEMETRY", Value: telemetry.Mode()},
+               {Name: "GOTELEMETRYDIR", Value: telemetry.Dir()},
        }
 
        for i := range env {
diff --git a/src/cmd/go/internal/telemetrycmd/telemetry.go b/src/cmd/go/internal/telemetrycmd/telemetry.go
new file mode 100644 (file)
index 0000000..5542a02
--- /dev/null
@@ -0,0 +1,92 @@
+// Copyright 2024 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 telemetrycmd implements the "go telemetry" command.
+package telemetrycmd
+
+import (
+       "context"
+       "fmt"
+       "os"
+
+       "cmd/go/internal/base"
+       "cmd/internal/telemetry"
+)
+
+var CmdTelemetry = &base.Command{
+       UsageLine: "go telemetry [off|local|on]",
+       Short:     "manage telemetry data and settings",
+       Long: `Telemetry is used to manage Go telemetry data and settings.
+
+Telemetry can be in one of three modes: off, local, or on.
+
+When telemetry is in local mode, counter data is written to the local file
+system, but will not be uploaded to remote servers.
+
+When telemetry is off, local counter data is neither collected nor uploaded.
+
+When telemetry is on, telemetry data is written to the local file system
+and periodically sent to https://telemetry.go.dev/. Uploaded data is used to
+help improve the Go toolchain and related tools, and it will be published as
+part of a public dataset.
+
+For more details, see https://telemetry.go.dev/privacy.
+This data is collected in accordance with the Google Privacy Policy
+(https://policies.google.com/privacy).
+
+To view the current telemetry mode, run "go telemetry".
+To disable telemetry uploading, but keep local data collection, run
+"go telemetry local".
+To enable both collection and uploading, run “go telemetry on”.
+To disable both collection and uploading, run "go telemetry off".
+
+See https://go.dev/doc/telemetry for more information on telemetry.
+`,
+       Run: runTelemetry,
+}
+
+func init() {
+       base.AddChdirFlag(&CmdTelemetry.Flag)
+}
+
+func runTelemetry(ctx context.Context, cmd *base.Command, args []string) {
+       if len(args) == 0 {
+               fmt.Println(telemetry.Mode())
+               return
+       }
+
+       if len(args) != 1 {
+               cmd.Usage()
+       }
+
+       mode := args[0]
+       if mode != "local" && mode != "off" && mode != "on" {
+               cmd.Usage()
+       }
+       if old := telemetry.Mode(); old == mode {
+               return
+       }
+
+       if err := telemetry.SetMode(mode); err != nil {
+               base.Fatalf("go: failed to set the telemetry mode to %s: %v", mode, err)
+       }
+       if mode == "on" {
+               fmt.Fprintln(os.Stderr, telemetryOnMessage())
+       }
+}
+
+func telemetryOnMessage() string {
+       return `Telemetry uploading is now enabled and data will be periodically sent to
+https://telemetry.go.dev/. Uploaded data is used to help improve the Go
+toolchain and related tools, and it will be published as part of a public
+dataset.
+
+For more details, see https://telemetry.go.dev/privacy.
+This data is collected in accordance with the Google Privacy Policy
+(https://policies.google.com/privacy).
+
+To disable telemetry uploading, but keep local data collection, run
+“go telemetry local”.
+To disable both collection and uploading, run “go telemetry off“.`
+}
index 3fe5cd4ee18f06be060436ca164ae091e3fadd9b..03395b87f9bf5d3d8523780891588358f3d71dd5 100644 (file)
@@ -34,6 +34,7 @@ import (
        "cmd/go/internal/modget"
        "cmd/go/internal/modload"
        "cmd/go/internal/run"
+       "cmd/go/internal/telemetrycmd"
        "cmd/go/internal/test"
        "cmd/go/internal/tool"
        "cmd/go/internal/toolchain"
@@ -61,6 +62,7 @@ func init() {
                modcmd.CmdMod,
                workcmd.CmdWork,
                run.CmdRun,
+               telemetrycmd.CmdTelemetry,
                test.CmdTest,
                tool.CmdTool,
                version.CmdVersion,
diff --git a/src/cmd/go/testdata/script/telemetry.txt b/src/cmd/go/testdata/script/telemetry.txt
new file mode 100644 (file)
index 0000000..e9aa0f1
--- /dev/null
@@ -0,0 +1,51 @@
+# Tests for the telemetry subcommand,
+
+# The script test framework sets TEST_TELEMETRY_DIR (overriding the
+# default telemetry dir location) and then checks that at least one
+# counter has been written per script tests.
+# Run go before unsetting TEST_TELEMETRY_DIR to make the tests happy.
+# We want to unset it so the environment we're testing is as close
+# to a user's environment.
+go help telemetry
+env TEST_TELEMETRY_DIR=
+
+# Set userconfig dir, which is determined by os.UserConfigDir.
+# The telemetry dir is determined using that.
+mkdir $WORK/userconfig
+env AppData=$WORK\userconfig # windows
+[GOOS:windows] env userconfig=$AppData
+env HOME=$WORK/userconfig # darwin,unix,ios
+[GOOS:darwin] env userconfig=$HOME'/Library/Application Support'
+[GOOS:ios] env userconfig=$HOME'/Library/Application Support'
+[!GOOS:windows] [!GOOS:darwin] [!GOOS:ios] [!GOOS:plan9] env userconfig=$HOME/.config
+env home=$WORK/userconfig # plan9
+[GOOS:plan9] env userconfig=$home/lib
+
+go telemetry
+stdout 'local'
+
+go telemetry off
+go telemetry
+stdout 'off'
+go env GOTELEMETRY
+stdout 'off'
+
+go telemetry local
+go telemetry
+stdout 'local'
+go env GOTELEMETRY
+stdout 'local'
+
+go telemetry on
+go telemetry
+stdout 'on'
+go env GOTELEMETRY
+stdout 'on'
+
+go env
+stdout 'GOTELEMETRY=''?on''?'
+stdout 'GOTELEMETRYDIR=''?'$userconfig'[\\/]go[\\/]telemetry''?'
+! go env -w GOTELEMETRY=off
+stderr '^go: unknown go command variable GOTELEMETRY$'
+! go env -w GOTELEMETRYDIR=foo
+stderr '^go: unknown go command variable GOTELEMETRYDIR$'
\ No newline at end of file
index 2420a077089b606fd59b3c9c01490458ebd4b65a..221b6a007d37286c84a07ab0a358bbaeb8d9f024 100644 (file)
@@ -74,3 +74,38 @@ func CountFlagValue(prefix string, flagSet flag.FlagSet, flagName string) {
                }
        })
 }
+
+// Mode returns the current telemetry mode.
+//
+// The telemetry mode is a global value that controls both the local collection
+// and uploading of telemetry data. Possible mode values are:
+//   - "on":    both collection and uploading is enabled
+//   - "local": collection is enabled, but uploading is disabled
+//   - "off":   both collection and uploading are disabled
+//
+// When mode is "on", or "local", telemetry data is written to the local file
+// system and may be inspected with the [gotelemetry] command.
+//
+// If an error occurs while reading the telemetry mode from the file system,
+// Mode returns the default value "local".
+//
+// [gotelemetry]: https://pkg.go.dev/golang.org/x/telemetry/cmd/gotelemetry
+func Mode() string {
+       return telemetry.Mode()
+}
+
+// SetMode sets the global telemetry mode to the given value.
+//
+// See the documentation of [Mode] for a description of the supported mode
+// values.
+//
+// An error is returned if the provided mode value is invalid, or if an error
+// occurs while persisting the mode value to the file system.
+func SetMode(mode string) error {
+       return telemetry.SetMode(mode)
+}
+
+// Dir returns the telemetry directory.
+func Dir() string {
+       return telemetry.Dir()
+}
index 01549b6970fee64097793ee3b8d7aa14fb106287..1740bdb7019d1190b115b46ab2f467fc88b74677 100644 (file)
@@ -19,3 +19,6 @@ func NewCounter(name string) dummyCounter                                 { retu
 func NewStackCounter(name string, depth int) dummyCounter                 { return dummyCounter{} }
 func CountFlags(name string, flagSet flag.FlagSet)                        {}
 func CountFlagValue(prefix string, flagSet flag.FlagSet, flagName string) {}
+func Mode() string                                                        { return "" }
+func SetMode(mode string) error                                           { return nil }
+func Dir() string                                                         { return "" }