internal/graphconfig: rename to chartconfig, and display at /config
This CL contains a few changes to improve the visibility and coherency
of the "graph config":
- rename to "chart config", since elsewhere we speak of telemetry.go.dev
as hosting charts, and "graph" is an overloaded term
- move the config.txt file into the chartconfig package, and expose it
via embedding
- display the chart config at the /config endpoint, since it is easier
to read than the upload config
- link to the current config in the overview of telemetry.go.dev
Fixes golang/go#63418
Change-Id: Ia3cef815cb18b0b78f9f7c4d2e8fc82297e82f75
Reviewed-on: https://go-review.googlesource.com/c/telemetry/+/572335
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/cmd/gotelemetry/internal/view/view.go b/cmd/gotelemetry/internal/view/view.go
index 4b29f97..25232d7 100644
--- a/cmd/gotelemetry/internal/view/view.go
+++ b/cmd/gotelemetry/internal/view/view.go
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// The view command is a server intended to be run on a user's machine to
-// display the local counters and time series graphs of counters.
+// display the local counters and time series charts of counters.
package view
import (
diff --git a/cmd/gotelemetry/internal/view/view_test.go b/cmd/gotelemetry/internal/view/view_test.go
index 1f4410c..b35395a 100644
--- a/cmd/gotelemetry/internal/view/view_test.go
+++ b/cmd/gotelemetry/internal/view/view_test.go
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// The view command is a server intended to be run on a users machine to
-// display the local counters and time series graphs of counters.
+// display the local counters and time series charts of counters.
package view
import (
diff --git a/godev/cmd/telemetrygodev/main.go b/godev/cmd/telemetrygodev/main.go
index be74d45..47411de 100644
--- a/godev/cmd/telemetrygodev/main.go
+++ b/godev/cmd/telemetrygodev/main.go
@@ -28,6 +28,7 @@
ilog "golang.org/x/telemetry/godev/internal/log"
"golang.org/x/telemetry/godev/internal/middleware"
"golang.org/x/telemetry/godev/internal/storage"
+ "golang.org/x/telemetry/internal/chartconfig"
tconfig "golang.org/x/telemetry/internal/config"
contentfs "golang.org/x/telemetry/internal/content"
"golang.org/x/telemetry/internal/telemetry"
@@ -230,6 +231,7 @@
}
func handleConfig(fsys fs.FS, ucfg *tconfig.Config) content.HandlerFunc {
+ ccfg := chartconfig.Raw()
cfg := ucfg.UploadConfig
version := "default"
@@ -240,10 +242,12 @@
}
data := struct {
Version string
- PrettyConfig string
+ ChartConfig string
+ UploadConfig string
}{
Version: version,
- PrettyConfig: string(cfgJSON),
+ ChartConfig: string(ccfg),
+ UploadConfig: string(cfgJSON),
}
return content.Template(w, fsys, "config.html", data, http.StatusOK)
}
diff --git a/godev/cmd/worker/main.go b/godev/cmd/worker/main.go
index cf2f840..81cb70b 100644
--- a/godev/cmd/worker/main.go
+++ b/godev/cmd/worker/main.go
@@ -283,7 +283,7 @@
)
for _, c := range p.Counters {
// TODO: add support for histogram counters by getting the counter type
- // from the graph config.
+ // from the chart config.
prog.Charts = append(prog.Charts,
partition(d, p.Name, c.Name, tconfig.Expand(c.Name), xs),
)
diff --git a/internal/graphconfig/graphconfig.go b/internal/chartconfig/chartconfig.go
similarity index 73%
rename from internal/graphconfig/graphconfig.go
rename to internal/chartconfig/chartconfig.go
index abab80b..6d5a11d 100644
--- a/internal/graphconfig/graphconfig.go
+++ b/internal/chartconfig/chartconfig.go
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// The graphconfig package defines the GraphConfig type, representing telemetry
-// graph configuration, as well as utilities for parsing and validating this
+// The chartconfig package defines the ChartConfig type, representing telemetry
+// chart configuration, as well as utilities for parsing and validating this
// configuration.
//
-// Graph configuration defines the set of aggregations active on the telemetry
+// Chart configuration defines the set of aggregations active on the telemetry
// server, and are used to derive which data needs to be uploaded by users.
// See the original blog post for more details:
//
@@ -24,20 +24,20 @@
// The following keys are supported. Any entry not marked as (optional) must be
// provided.
//
-// - title: the graph title.
-// - description: (optional) a longer description of the graph.
-// - issue: a go issue tracker URL proposing the graph configuration.
+// - title: the chart title.
+// - description: (optional) a longer description of the chart.
+// - issue: a go issue tracker URL proposing the chart configuration.
// Multiple issues may be provided by including additional 'issue:' lines.
// All proposals must be in the 'accepted' state.
-// - type: the graph type: currently only partition, histogram, and stack are
+// - type: the chart type: currently only partition, histogram, and stack are
// supported.
-// - program: the package path of the program for which this graph applies.
-// - version: (optional) the first version for which this graph applies. Must
+// - program: the package path of the program for which this chart applies.
+// - version: (optional) the first version for which this chart applies. Must
// be a valid semver value.
-// - counter: the primary counter this graph illustrates, including buckets
-// for histogram and partition graphs
+// - counter: the primary counter this chart illustrates, including buckets
+// for histogram and partition charts.
// - depth: (optional) stack counters only; the maximum stack depth to collect
-// - error: (optional) the desired error rate for this graph, which
+// - error: (optional) the desired error rate for this chart, which
// determines collection rate
//
// Multiple records are separated by "---" lines.
@@ -66,13 +66,13 @@
// type: stack
// program: golang.org/x/tools/gopls
// depth: 10
-package graphconfig
+package chartconfig
-// A GraphConfig defines the configuration for a single graph/collection on the
+// A ChartConfig defines the configuration for a single chart/collection on the
// telemetry server.
//
// See the package documentation for field definitions.
-type GraphConfig struct {
+type ChartConfig struct {
Title string
Description string
Issue []string
diff --git a/internal/configgen/config.txt b/internal/chartconfig/config.txt
similarity index 90%
rename from internal/configgen/config.txt
rename to internal/chartconfig/config.txt
index b4e697e..bd2bc21 100644
--- a/internal/configgen/config.txt
+++ b/internal/chartconfig/config.txt
@@ -1,5 +1,5 @@
-# Note: this is an approved graph config. This is embedded in the configgen program.
-# For the graph config file format, see golang.org/x/telemetry/internal/graphconfig.
+# Note: these are approved chart configs, used to generate the upload config.
+# For the chart config file format, see chartconfig.go.
title: Editor Distribution
counter: gopls/client:{vscode,vscodium,vscode-insiders,code-server,eglot,govim,neovim,coc.nvim,sublimetext,other}
diff --git a/internal/graphconfig/parse.go b/internal/chartconfig/load.go
similarity index 85%
rename from internal/graphconfig/parse.go
rename to internal/chartconfig/load.go
index f391130..e83cbab 100644
--- a/internal/graphconfig/parse.go
+++ b/internal/chartconfig/load.go
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package graphconfig
+package chartconfig
import (
+ _ "embed"
"fmt"
"reflect"
"sort"
@@ -12,21 +13,33 @@
"strings"
)
-// Parse parses GraphConfig records from the provided raw data, returning an
+//go:embed config.txt
+var chartConfig []byte
+
+func Raw() []byte {
+ return chartConfig
+}
+
+// Load loads and parses the current chart config.
+func Load() ([]ChartConfig, error) {
+ return Parse(chartConfig)
+}
+
+// Parse parses ChartConfig records from the provided raw data, returning an
// error if the config has invalid syntax. See the package documentation for a
// description of the record syntax.
//
-// Even with correct syntax, the resulting GraphConfig may not meet all the
+// Even with correct syntax, the resulting chart config may not meet all the
// requirements described in the package doc. Call [Validate] to check whether
// the config data is coherent.
-func Parse(data []byte) ([]GraphConfig, error) {
+func Parse(data []byte) ([]ChartConfig, error) {
// Collect field information for the record type.
var (
prefixes []string // for parse errors
fields = make(map[string]reflect.StructField) // key -> struct field
)
{
- typ := reflect.TypeOf(GraphConfig{})
+ typ := reflect.TypeOf(ChartConfig{})
for i := 0; i < typ.NumField(); i++ {
f := typ.Field(i)
key := strings.ToLower(f.Name)
@@ -41,15 +54,15 @@
// Read records, separated by '---'
var (
- records []GraphConfig
- inProgress = new(GraphConfig) // record value currently being parsed
+ records []ChartConfig
+ inProgress = new(ChartConfig) // record value currently being parsed
set = make(map[string]bool) // fields that are set so far; empty records are skipped
)
flushRecord := func() {
if len(set) > 0 { // only flush non-empty records
records = append(records, *inProgress)
}
- inProgress = new(GraphConfig)
+ inProgress = new(ChartConfig)
set = make(map[string]bool)
}
diff --git a/internal/graphconfig/parse_test.go b/internal/chartconfig/load_test.go
similarity index 85%
rename from internal/graphconfig/parse_test.go
rename to internal/chartconfig/load_test.go
index 19d74fc..b00acf2 100644
--- a/internal/graphconfig/parse_test.go
+++ b/internal/chartconfig/load_test.go
@@ -2,23 +2,23 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package graphconfig_test
+package chartconfig_test
import (
"reflect"
"testing"
- "golang.org/x/telemetry/internal/graphconfig"
+ "golang.org/x/telemetry/internal/chartconfig"
)
func TestParse(t *testing.T) {
tests := []struct {
name string
input string
- want []graphconfig.GraphConfig
+ want []chartconfig.ChartConfig
}{
{"empty", "", nil},
- {"single field", "title: A", []graphconfig.GraphConfig{{Title: "A"}}},
+ {"single field", "title: A", []chartconfig.ChartConfig{{Title: "A"}}},
{
"basic", `
title: A
@@ -32,7 +32,7 @@
error: 0.1
version: v2.0.0
`,
- []graphconfig.GraphConfig{{
+ []chartconfig.ChartConfig{{
Title: "A",
Description: "B",
Type: "C",
@@ -49,7 +49,7 @@
title: A
description: B
`,
- []graphconfig.GraphConfig{
+ []chartconfig.ChartConfig{
{Title: "A", Description: "B"},
},
},
@@ -64,7 +64,7 @@
`,
- []graphconfig.GraphConfig{
+ []chartconfig.ChartConfig{
{Title: "A", Description: "B"},
},
},
@@ -80,7 +80,7 @@
title: C
description: D
`,
- []graphconfig.GraphConfig{
+ []chartconfig.ChartConfig{
{Title: "A", Description: "B"},
{Title: "C", Description: "D"},
},
@@ -94,7 +94,7 @@
issue: TBD
program: golang.org/x/tools/gopls
`,
- []graphconfig.GraphConfig{
+ []chartconfig.ChartConfig{
{
Title: "Editor Distribution",
Description: "measure editor distribution for gopls users.",
@@ -109,7 +109,7 @@
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
- got, err := graphconfig.Parse([]byte(test.input))
+ got, err := chartconfig.Parse([]byte(test.input))
if err != nil {
t.Fatalf("Parse(...) failed: %v", err)
}
@@ -161,7 +161,7 @@
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
- _, err := graphconfig.Parse([]byte(test.input))
+ _, err := chartconfig.Parse([]byte(test.input))
if err == nil {
t.Fatalf("Parse(...) succeeded unexpectedly")
}
diff --git a/internal/graphconfig/validate.go b/internal/chartconfig/validate.go
similarity index 82%
rename from internal/graphconfig/validate.go
rename to internal/chartconfig/validate.go
index 15b7b71..74106b9 100644
--- a/internal/graphconfig/validate.go
+++ b/internal/chartconfig/validate.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package graphconfig
+package chartconfig
import (
"errors"
@@ -11,9 +11,9 @@
"golang.org/x/mod/semver"
)
-// Validate checks that a graph config is complete and coherent, returning an
+// Validate checks that a ChartConfig is complete and coherent, returning an
// error describing all problems encountered, or nil.
-func Validate(cfg GraphConfig) error {
+func Validate(cfg ChartConfig) error {
var errs []error
reportf := func(format string, args ...any) {
errs = append(errs, fmt.Errorf(format, args...))
@@ -37,7 +37,7 @@
reportf("invalid depth %d: must be non-negative", cfg.Depth)
}
if cfg.Depth != 0 && cfg.Type != "stack" {
- reportf("depth can only be set for \"stack\" graph types")
+ reportf("depth can only be set for \"stack\" chart types")
}
if cfg.Version != "" && !semver.IsValid(cfg.Version) {
reportf("%q is not valid semver", cfg.Version)
diff --git a/internal/graphconfig/validate_test.go b/internal/chartconfig/validate_test.go
similarity index 81%
rename from internal/graphconfig/validate_test.go
rename to internal/chartconfig/validate_test.go
index 25533ef..01fc557 100644
--- a/internal/graphconfig/validate_test.go
+++ b/internal/chartconfig/validate_test.go
@@ -2,17 +2,17 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package graphconfig_test
+package chartconfig_test
import (
"strings"
"testing"
- "golang.org/x/telemetry/internal/graphconfig"
+ "golang.org/x/telemetry/internal/chartconfig"
)
func TestValidateOK(t *testing.T) {
- // A minimally valid graph config.
+ // A minimally valid chart config.
const input = `
title: Editor Distribution
counter: gopls/editor:{emacs,vim,vscode,other}
@@ -20,14 +20,14 @@
issue: https://go.dev/issue/12345
program: golang.org/x/tools/gopls
`
- records, err := graphconfig.Parse([]byte(input))
+ records, err := chartconfig.Parse([]byte(input))
if err != nil {
t.Fatal(err)
}
if len(records) != 1 {
t.Fatalf("Parse(%q) returned %d records, want exactly 1", input, len(records))
}
- if err := graphconfig.Validate(records[0]); err != nil {
+ if err := chartconfig.Validate(records[0]); err != nil {
t.Errorf("Validate(%q) = %v, want nil", input, err)
}
}
@@ -45,14 +45,14 @@
}
for input, wantErrs := range tests {
- records, err := graphconfig.Parse([]byte(input))
+ records, err := chartconfig.Parse([]byte(input))
if err != nil {
t.Fatal(err)
}
if len(records) != 1 {
t.Fatalf("Parse(%q) returned %d records, want exactly 1", input, len(records))
}
- err = graphconfig.Validate(records[0])
+ err = chartconfig.Validate(records[0])
if err == nil {
t.Fatalf("Validate(%q) succeeded unexpectedly", input)
}
diff --git a/internal/configgen/main.go b/internal/configgen/main.go
index f49dd48..5658fc8 100644
--- a/internal/configgen/main.go
+++ b/internal/configgen/main.go
@@ -7,7 +7,7 @@
//go:build go1.21
// Package configgen generates the upload config file stored in the config.json
-// file of golang.org/x/telemetry/config based on the graphconfig stored in
+// file of golang.org/x/telemetry/config based on the chartconfig stored in
// config.txt.
package main
@@ -25,10 +25,8 @@
"sort"
"strings"
- _ "embed"
-
"golang.org/x/mod/semver"
- "golang.org/x/telemetry/internal/graphconfig"
+ "golang.org/x/telemetry/internal/chartconfig"
"golang.org/x/telemetry/internal/telemetry"
)
@@ -40,16 +38,18 @@
SamplingRate = 1.0
)
-//go:embed config.txt
-var graphConfig []byte
-
func main() {
flag.Parse()
+ gcfgs, err := chartconfig.Load()
+ if err != nil {
+ log.Fatal(err)
+ }
+
// The padding heuristics below are based on the example of gopls.
//
// The goal is to pad enough versions for a quarter.
- cfg, err := generate(graphConfig, padding{
+ uCfg, err := generate(gcfgs, padding{
// 6 releases into the future translates to approximately three months for gopls.
releases: 6,
// We may release gopls 1.0, but won't release 2.0 in a three month timespan!
@@ -66,7 +66,7 @@
if err != nil {
log.Fatal(err)
}
- cfgJSON, err := json.MarshalIndent(cfg, "", "\t")
+ cfgJSON, err := json.MarshalIndent(uCfg, "", "\t")
if err != nil {
log.Fatal(err)
}
@@ -87,7 +87,7 @@
log.Fatal(err)
}
// Guarantee that we have enough padding to do two patches releases tomorrow.
- minCfg, err := generate(graphConfig, padding{
+ minCfg, err := generate(gcfgs, padding{
releases: 2,
maj: 1,
majmin: 1, // we're not ever going to do more than one major/minor release in a day
@@ -138,9 +138,9 @@
return cfg, nil
}
-// generate computes the upload config from graph configs and module
+// generate computes the upload config from chart configs and module
// information, returning the resulting formatted JSON.
-func generate(graphConfig []byte, padding padding) (*telemetry.UploadConfig, error) {
+func generate(gcfgs []chartconfig.ChartConfig, padding padding) (*telemetry.UploadConfig, error) {
ucfg := &telemetry.UploadConfig{
GOOS: goos(),
GOARCH: goarch(),
@@ -153,16 +153,11 @@
return nil, fmt.Errorf("querying go info: %v", err)
}
- gcfgs, err := graphconfig.Parse(graphConfig)
- if err != nil {
- return nil, fmt.Errorf("parsing graph config records: %v", err)
- }
-
for i, r := range gcfgs {
- if err := graphconfig.Validate(r); err != nil {
+ if err := chartconfig.Validate(r); err != nil {
// TODO(rfindley): this is a poor way to identify the faulty record. We
- // should probably store position information in the GraphConfig.
- return nil, fmt.Errorf("graph config #%d (%q): %v", i, r.Title, err)
+ // should probably store position information in the ChartConfig.
+ return nil, fmt.Errorf("chart config #%d (%q): %v", i, r.Title, err)
}
}
diff --git a/internal/configgen/main_test.go b/internal/configgen/main_test.go
index 5764871..08d5c13 100644
--- a/internal/configgen/main_test.go
+++ b/internal/configgen/main_test.go
@@ -12,6 +12,7 @@
"sort"
"testing"
+ "golang.org/x/telemetry/internal/chartconfig"
"golang.org/x/telemetry/internal/telemetry"
)
@@ -23,7 +24,7 @@
"golang.org/toolchain": {"v0.0.1-go1.21.0.linux-arm", "v0.0.1-go1.20.linux-arm"},
"golang.org/x/tools/gopls": {"v0.13.0", "v0.14.0", "v0.15.0-pre.1", "v0.15.0"},
}
- const gcfg = `
+ const raw = `
title: Editor Distribution
counter: gopls/editor:{emacs,vim,vscode,other}
description: measure editor distribution for gopls users.
@@ -32,7 +33,11 @@
program: golang.org/x/tools/gopls
version: v0.14.0
`
- got, err := generate([]byte(gcfg), padding{2, 1, 1, 2, 2})
+ gcfgs, err := chartconfig.Parse([]byte(raw))
+ if err != nil {
+ t.Fatal(err)
+ }
+ got, err := generate(gcfgs, padding{2, 1, 1, 2, 2})
if err != nil {
t.Fatal(err)
}
diff --git a/internal/content/telemetrygodev/config.html b/internal/content/telemetrygodev/config.html
index a83659a..8790eaa 100644
--- a/internal/content/telemetrygodev/config.html
+++ b/internal/content/telemetrygodev/config.html
@@ -10,16 +10,29 @@
{{define "content"}}
<main id="main">
- <section class="Config">
- <h2 id="config">Config</h2>
- <p>
- The config contains the list of active counters for each program
- and allowed report metadata.
- </p>
- <label>
- Version: {{.Version}}
- </label>
- <pre style="max-height: 100rem">{{.PrettyConfig}}</pre>
- </section>
+ <section class="Chart Config">
+ <h2 id="config">Chart Config</h2>
+ <p>
+ The chart config contains the list of approved charts to display on
+ telemetry.go.dev. The chart config format is documented by the
+ <a href="https://pkg.go.dev/golang.org/x/telemetry/internal/chartconfig">
+ <code>chartconfig</code>
+ </a> package documentation.
+ </p>
+ <pre style="max-height: 100rem">{{.ChartConfig}}</pre>
+ </section>
+
+ <section class="Upload Config">
+ <h2 id="config">Upload Config</h2>
+ <p>
+ The upload config contains the list of active counters for each program
+ and allowed report metadata. This is generated from the chart config
+ above.
+ </p>
+ <label>
+ Version: {{.Version}}
+ </label>
+ <pre style="max-height: 100rem">{{.UploadConfig}}</pre>
+ </section>
</main>
-{{end}}
\ No newline at end of file
+{{end}}
diff --git a/internal/content/telemetrygodev/index.html b/internal/content/telemetrygodev/index.html
index 1412d75..c2d81f4 100644
--- a/internal/content/telemetrygodev/index.html
+++ b/internal/content/telemetrygodev/index.html
@@ -15,12 +15,22 @@
<h2>Overview</h2>
<p>
Go Telemetry is a way for Go toolchain programs to collect data about their
- performance and usage. Uploaded data is used to help improve the Go toolchain
- and related tools. Go Telemetry is not built into users' binaries.
- <a href="/privacy#collection">See what Go Telemetry collects</a>.
+ performance and usage. Uploaded data is used to help improve the Go
+ toolchain and related tools. Go Telemetry is not built into users'
+ binaries. Learn more about Go telemetry at
+ <a href="https://go.dev/doc/telemetry">go.dev/doc/telemetry</a>.
</p>
- </p>For privacy information about this service, see <a href="/privacy">telemetry.go.dev/privacy</a>.</p>
+ <p>
+ Users who have opted in will upload an approved subset of telemetry
+ data approximately once a week. This subset is determined by the current
+ <a href="/config">upload configuration</a>.
+ </p>
+
+ <p>
+ For privacy information about this service, see
+ <a href="/privacy">telemetry.go.dev/privacy</a>.
+ </p>
</section>
<section>
<h2>Charts</h2>
@@ -41,4 +51,4 @@
</ul>
</section>
</main>
-{{end}}
\ No newline at end of file
+{{end}}