Skip to content

Commit 29629ec

Browse files
findleyrgopherbot
authored andcommitted
_content/doc: add documentation for Go telemetry
Add documentation for Go telemetry, aimed at Go users who want to understand telemetry better. This article goes into some detail about the telemetry data flow, but doesn't get into details about x/telemetry APIs, as those are mostly interesting only for Go toolchain developers, and therefore belong in x/telemetry documentation. For golang/go#63883 Change-Id: Ie7e82960a2dbe5e0c0c81e46dc0b0c86174365fe Reviewed-on: https://go-review.googlesource.com/c/website/+/558196 Reviewed-by: Alan Donovan <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Russ Cox <[email protected]> Auto-Submit: Robert Findley <[email protected]>
1 parent e2bd64a commit 29629ec

File tree

5 files changed

+376
-0
lines changed

5 files changed

+376
-0
lines changed

_content/doc/telemetry.md

Lines changed: 376 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,376 @@
1+
---
2+
title: "Go Telemetry"
3+
layout: article
4+
breadcrumb: true
5+
date: 2024-02-07:00:00Z
6+
---
7+
8+
Table of Contents:
9+
10+
[Background](#background)\
11+
[Overview](#overview)\
12+
[Configuration](#config)\
13+
[Counters](#counters)\
14+
[Reporting and Uploading](#reports)\
15+
[Charts](#charts) \
16+
[IDE Prompting](#ide) \
17+
[Frequently Asked Questions](#faq)
18+
19+
## Background {#background}
20+
21+
Go telemetry is a way for Go toolchain programs to collect data about their
22+
performance and usage. Here "Go toolchain" means developer tools maintained
23+
by the Go team, including the `go` command and supplemental tools such as the
24+
Go language server `gopls` or Go security tool `govulncheck`. Go telemetry is
25+
only intended for use in programs maintained by the Go team.
26+
27+
By default, telemetry data is kept only on the local computer, but users may
28+
opt in to uploading an approved subset of telemetry data to [telemetry.go.dev].
29+
Uploaded data helps the Go team improve the Go language and its tools,
30+
by helping us understand usage and breakages.
31+
32+
The word "telemetry" has acquired negative connotations in the world of open
33+
source software, in many cases deservedly so. Yet measuring the user experience
34+
is an important element of modern software engineering, and data sources such
35+
as GitHub issues or annual surveys are coarse and lagging indicators,
36+
insufficient for the types of questions the Go team needs to be able to answer.
37+
Go telemetry is designed to help programs in the toolchain collect useful data
38+
about their reliability, performance, and usage, while maintaining the
39+
transparency and privacy that users expect from the Go project. To learn more
40+
about the design process and motivation for telemetry, please see the
41+
[telemetry blog posts](https://research.swtch.com/telemetry).
42+
To learn more about telemetry and privacy, please see the
43+
[telemetry privacy policy](https://telemetry.go.dev/privacy).
44+
45+
This page explains how Go telemetry works, in some detail. For quick answers to
46+
frequently asked questions, see the [FAQ](#faq).
47+
48+
## Overview {#overview}
49+
50+
Go telemetry uses three core data types:
51+
52+
- [_Counters_](#counters) are lightweight counts of named events, instrumented
53+
in the toolchain program. If collection is enabled (the [mode](#config)
54+
is **local** or **on**), counters are written to a memory-mapped file in the
55+
local file system.
56+
- [_Reports_](#reports) are aggregated summaries of counters for a given week.
57+
If uploading is enabled (the [mode](#config) is **on**), reports for
58+
[approved counters](#proposals) are uploaded to [telemetry.go.dev], where
59+
they are publicly accessible.
60+
- [_Charts_](#charts) summarize uploaded reports for all users.
61+
Charts can be viewed at [telemetry.go.dev].
62+
63+
All local Go telemetry data and configuration is stored in the directory
64+
<code>[os.UserConfigDir()](/pkg/os#UserConfigDir)/go/telemetry</code>
65+
directory. Below, we'll refer to this directory as `<gotelemetry>`.
66+
67+
The diagram below illustrates this data flow.
68+
69+
<div class="image">
70+
<center>
71+
<img max-width="800px" src="/doc/telemetry/dataflow.png" />
72+
</center>
73+
</div>
74+
75+
In the rest of this document, we'll explore the components of this diagram. But
76+
first, let's learn more about the configuration that controls it.
77+
78+
## Configuration {#config}
79+
80+
The behavior of Go telemetry is controlled by a single value: the telemetry
81+
_mode_. The possible values for `mode` are `local` (the default), `on`, or
82+
`off`:
83+
84+
- When `mode` is `local`, telemetry data is collected and stored on the local
85+
computer, but never uploaded to remote servers.
86+
- When `mode` is `on`, data is collected, and may be uploaded depending on
87+
[sampling](#uploads).
88+
- When `mode` is `off`, data is neither collected nor uploaded.
89+
90+
The [`gotelemetry`](/pkg/golang.org/x/telemetry/cmd/gotelemetry) command
91+
configures the telemetry mode and manages local telemetry data. Use this
92+
command to install it:
93+
94+
```
95+
go install golang.org/x/telemetry/cmd/gotelemetry@latest
96+
```
97+
98+
The following commands interact with the telemetry mode:
99+
100+
- `gotelemetry local`: set the mode to `local`.
101+
- `gotelemetry on`: set the mode to `on`.
102+
- `gotelemetry off`: set the mode to `off`.
103+
- `gotelemetry env`: see the current mode.
104+
105+
For the complete usage information of the `gotelemetry` command line tool,
106+
see its [package documentation](/pkg/golang.org/x/telemetry/cmd/gotelemetry).
107+
108+
Telemetry may also be enabled by accepting an [IDE prompt](#ide).
109+
110+
## Counters {#counters}
111+
112+
As mentioned above, Go telemetry is instrumented via _counters_. Counters come
113+
in two variants: basic counters and stack counters.
114+
115+
### Basic counters
116+
117+
A _basic counter_ is an incrementable value with a name that describes the
118+
event that it counts. For example, the `gopls/client:vscode` counter records
119+
the number of times a `gopls` session is initiated by VS Code. Alongside this
120+
counter we may have `gopls/client:neovim`, `gopls/client:eglot`, and so on, to
121+
record sessions with different editors or language clients. If you used
122+
multiple editors throughout the week, you might record the following counter
123+
data:
124+
125+
gopls/client:vscode 8
126+
gopls/client:neovim 5
127+
gopls/client:eglot 2
128+
129+
When counters are related in this way, we sometimes refer to the part before
130+
the `:` the _chart name_ (`gopls/client` in this case), and the part after `:`
131+
as the _bucket name_ (`vscode`). We'll see why this matters when we discuss
132+
[charts](#charts).
133+
134+
Basic counters can also represent a _histogram_. For example, the {{raw
135+
`<code>gopls/completion/latency:&lt;50ms</code>`}} counter records the number
136+
of times an autocompletion takes less than 50ms.
137+
138+
{{raw `
139+
<pre>
140+
gopls/completion/latency:&lt;10ms
141+
gopls/completion/latency:&lt;50ms
142+
gopls/completion/latency:&lt;100ms
143+
...
144+
</pre>
145+
`}}
146+
147+
This pattern for recording histogram data is a convention: there's nothing
148+
special about the {{raw `<code>&lt;50ms</code>`}} bucket name. These types of
149+
counters are commonly used to measure performance.
150+
151+
### Stack counters
152+
153+
A _stack counter_ is a counter that also records the current call stack of the
154+
Go toolchain program when the count is incremented. For example, the
155+
`crash/crash` stack counter records the call stack when a toolchain program
156+
crashes:
157+
158+
crash/crash
159+
golang.org/x/tools/gopls/internal/golang.hoverBuiltin:+22
160+
golang.org/x/tools/gopls/internal/golang.Hover:+94
161+
golang.org/x/tools/gopls/internal/server.Hover:+42
162+
...
163+
164+
Stack counters typically measure events where program invariants are violated.
165+
The most common example of this is a crash, but another example is the
166+
`gopls/bug` stack counter, which counts unusual situations identified in
167+
advance by the programmer, such as a recovered panic or an error that "can't
168+
happen". Stack counters include only the names and line numbers of functions
169+
within Go toolchain programs. They don't include any information about user
170+
inputs, such as the names or contents of a user's source code.
171+
172+
Stack counters can help track down rare or tricky bugs that don't get reported
173+
by other means. Since introducing the `gopls/bug` counter, we've found
174+
[dozens of instances](https://github.com/golang/go/issues?q=label%3Agopls%2Ftelemetry-wins)
175+
of "unreachable" code that was reached in practice, and tracking down these
176+
exceptions has led to the discovery (and fix) of many user-visible bugs that
177+
were either not obvious to the user or too difficult to report. Especially with
178+
prerelease testing, stack counters can help us improve the product more
179+
efficiently than we could without automation.
180+
181+
### Counter files
182+
183+
All counter data is written to the `<gotelemetry>/local` directory, in
184+
files named according to the following schema:
185+
186+
```
187+
[program name]@[program version]-[go version]-[GOOS]-[GOARCH]-[date].v1.count
188+
```
189+
190+
- The **program name** is the basename of the program's package path, as reported
191+
by [debug.BuildInfo].
192+
- The **program version** and **go version** are also reported by [debug.BuildInfo].
193+
- The **GOOS** and **GOARCH** values are reported by
194+
[`runtime.GOOS`](/pkg/runtime#GOOS) and
195+
[`runtime.GOARCH`](/pkg/runtime#GOARCH).
196+
- The **date** is the date the counter file was created, in `YYYY-MM-DD` format.
197+
198+
These files are memory mapped into each running instance of the instrumented
199+
programs. The use of a memory-mapped file means that even if the program
200+
immediately crashes, or several copies of instrumented tools are running
201+
simultaneously, the counters are recorded safely.
202+
203+
## Reporting and uploading {#reports}
204+
205+
Approximately once a week, counter data gets aggregated into reports named
206+
`<date>.json` in the `<gotelemetry>/local` directory. These reports sum all of
207+
counts for the previous week, grouped by the same program identifiers used for
208+
the counter file (program name, program version, go version, GOOS, and GOARCH).
209+
210+
Local reports can be viewed as charts with the
211+
[`gotelemetry view`](/pkg/golang.org/x/telemetry/cmd/gotelemetry) command.
212+
Here's an example summary of the `gopls/completion/latency` counter:
213+
214+
<div class="image">
215+
<center>
216+
<img max-width="800px" src="/doc/telemetry/gopls-latency.png" />
217+
</center>
218+
</div>
219+
220+
### Uploading {#uploads}
221+
222+
If telemetry uploading is enabled, the weekly reporting process will also
223+
generate reports containing the subset of counters present in the
224+
[upload config](https://telemetry.go.dev/config). These counters must be
225+
approved by the public review process described in the next section. After it
226+
has been successfully uploaded, a copy of the uploaded reports are stored in
227+
the `<gotelemetry>/upload` directory.
228+
229+
Once enough users opt in to uploading telemetry data, the upload process will
230+
randomly skip uploading for a fraction of reports, to reduce collection amounts
231+
and increase privacy while maintaining statistical significance.
232+
233+
### The telemetry proposal process {#proposals}
234+
235+
Counters may be added to the upload configuration only through the _telemetry
236+
proposal process_, which proceeds as follows:
237+
238+
1. The proposer files a [proposal] to upload new data. This is expressed in the
239+
form of a specific [chart](#charts) that will be displayed on
240+
[telemetry.go.dev].
241+
2. Once discussion on the issue resolves, the proposal is approved or declined
242+
by a member of the Go team.
243+
3. The proposer sends a CL modifying the internal
244+
[chart config](https://go.googlesource.com/telemetry/+/refs/heads/master/internal/configgen/config.txt)
245+
to include the new chart.
246+
4. An automatic process regenerates the upload config to allow uploading of the
247+
counters required for the new chart. This process will also regularly add
248+
new versions of the relevant programs to the upload config as they are
249+
released.
250+
251+
In order to be approved, new charts cannot carry sensitive user information,
252+
and additionally must be both useful and feasible. In order to be _useful_,
253+
charts must serve a specific purpose, with actionable outcomes, that can't be
254+
served by other means. For example, in order to collect a counter that measures
255+
the latency of a given operation, it must be shown that this latency can't
256+
reasonably be measured via benchmarking, and that knowing the latency
257+
distribution will help meaningfully improve future versions of the program in
258+
question. In order to be _feasible_, it must be possible to reliably collect
259+
the requisite data, and the resulting measurements must be statistically
260+
significant. To demonstrate feasibility, the proposer may be asked to instrument
261+
the target program with counters and collect them locally first.
262+
263+
The full set of such proposals is available at the
264+
[proposal project](https://github.com/orgs/golang/projects/29) on GitHub.
265+
266+
## Charts {#charts}
267+
268+
In addition to accepting uploads, the [telemetry.go.dev] website makes uploaded
269+
data publicly available. Each day, uploaded reports are processed into two
270+
outputs, which are available on the [telemetry.go.dev] homepage.
271+
272+
- _merged_ reports merged counters from all uploads received on the given day.
273+
- _charts_ plot uploaded data as specified in the [chart config], which was
274+
produced as part of the proposal process. Recall from the discussion of
275+
[counters](#counters) that counter names such as `foo:bar` are decomposed
276+
into the chart name `foo` and bucket name `bar`. Each chart aggregates
277+
counters with the same chart name into the corresponding buckets.
278+
279+
Charts are specified in the [chart config] format. For example, here's the
280+
chart config for the `gopls/client` chart.
281+
282+
title: Editor Distribution
283+
counter: gopls/client:{vscode,vscodium,vscode-insiders,code-server,eglot,govim,neovim,coc.nvim,sublimetext,other}
284+
description: measure editor distribution for gopls users.
285+
type: partition
286+
issue: https://go.dev/issue/61038
287+
issue: https://go.dev/issue/62214 # add vscode-insiders
288+
program: golang.org/x/tools/gopls
289+
version: v0.13.0 # temporarily back-version to demonstrate config generation.
290+
291+
This configuration describes the chart to be produced, enumerates the set of
292+
counters to be aggregated, and specifies the program versions to which the
293+
chart applies. Additionally, the [proposal process](#proposals) requires that
294+
an accepted proposal be associated with the chart. Here's the chart resulting
295+
from that config:
296+
297+
<div class="image">
298+
<center>
299+
<img src="/doc/telemetry/gopls-clients.png" />
300+
</center>
301+
</div>
302+
303+
## IDE Prompting {#ide}
304+
305+
For telemetry to answer the types of questions we want to ask of it, the set of
306+
users opting in to uploading need not be large--approximately 16,000
307+
participants would allow for statistically significant measurements at the
308+
desired level of granularity. However, there is still a cost to assembling this
309+
healthy sample: we need to ask a large number of Go developers if they want to
310+
opt in.
311+
312+
Furthermore, even if a large number of users choose to opt in _now_ (perhaps
313+
after reading a Go blog post), those users may be skewed toward experienced Go
314+
developers, and over time that initial sample will grow even more skewed.
315+
Also, as people replace their computers, they must actively choose to opt in
316+
again. In the telemetry blog post series, this is referred to as the
317+
["campaign cost"](https://research.swtch.com/telemetry-opt-in#campaign) of
318+
the opt-in model.
319+
320+
To help keep the sample of participating users fresh, the Go language server
321+
[`gopls`] supports a prompt that asks users to opt in to Go telemetry.
322+
Here's what that looks like from VS Code:
323+
324+
<div class="image">
325+
<center>
326+
<img width="600px" src="/doc/telemetry/prompt.png" />
327+
</center>
328+
</div>
329+
330+
If users choose "Yes", their telemetry [mode](#config) will be set to `on`,
331+
just as if they had run
332+
[`gotelemetry on`](/pkg/golang.org/x/telemetry/cmd/gotelemetry). In this way,
333+
opting in is as easy as possible, and we can continually reach a large and
334+
stratified sample of Go developers.
335+
336+
## Frequently Asked Question {#faq}
337+
338+
**Q: How do I enable or disable Go telemetry?**
339+
340+
A: Use the `gotelemetry` command, which can be installed with `go install
341+
golang.org/x/telemetry/cmd/gotelemetry@latest`. Run `gotelemetry off` to
342+
disable everything, even local collection. Run `gotelemetry on` to enable
343+
everything, including uploading approved counters to [telemetry.go.dev]. See
344+
the [Configuration](#config) section for more info.
345+
346+
**Q: Where does local data get stored?**
347+
348+
A: In the <code>[os.UserConfigDir()](/pkg/os#UserConfigDir)/go/telemetry</code> directory.
349+
350+
**Q: How often does data get uploaded, if I opt in?**
351+
352+
A: Approximately once a week.
353+
354+
**Q: What data gets uploaded, if I opt in?**
355+
356+
A: Only counters that are listed in the
357+
[upload config](https://telemetry.go.dev/config) may be uploaded.
358+
This is generated from the [chart config], which may be more readable.
359+
360+
**Q: How do counters get added to the upload config?**
361+
362+
A: Through the [public proposal process](#proposals).
363+
364+
**Q: Where can I see telemetry data that has been uploaded?**
365+
366+
A: Uploaded data is available as charts or merged summaries at [telemetry.go.dev].
367+
368+
**Q: Where is the source code for Go telemetry?**
369+
370+
A: At [golang.org/x/telemetry](/pkg/golang.org/x/telemetry).
371+
372+
[`gopls`]: /pkg/golang.org/x/tools/gopls
373+
[debug.BuildInfo]: /pkg/runtime/debug#BuildInfo
374+
[proposal]: /issue/new?assignees=&labels=Telemetry-Proposal&projects=golang%2F29&template=12-telemetry.yml&title=x%2Ftelemetry%2Fconfig%3A+proposal+title
375+
[telemetry.go.dev]: https://telemetry.go.dev
376+
[chart config]: /pkg/golang.org/x/telemetry/internal/graphconfig
59.6 KB
Loading
27 KB
Loading
30.2 KB
Loading

_content/doc/telemetry/prompt.png

37.8 KB
Loading

0 commit comments

Comments
 (0)