Телеметрия в Go

Оглавление:

Основная информация
Обзор
Конфигурация
Счетчики
Отчеты и загрузка
Графики
Предложения по телеметрии
Подсказки в IDE
Часто задаваемые вопросы

Основная информация

Go телеметрия — это способ, с помощью которого программы инструментария Go могут собирать данные о своей производительности и использовании. Под «инструментарием Go» понимаются инструменты разработчика, поддерживаемые командой Go, включая команду go и дополнительные инструменты, такие как сервер языка Go gopls или инструмент безопасности Go govulncheck. Go телеметрия предназначена исключительно для использования в программах, поддерживаемых командой Go, и их выбранных зависимостях, таких как Delve.

По умолчанию данные телеметрии сохраняются только на локальном компьютере, но пользователи могут принять участие в загрузке одобренного подмножества данных телеметрии на telemetry.go.dev. Загруженные данные помогают команде Go улучшать язык Go и его инструменты, позволяя лучше понимать использование и возникающие проблемы.

Слово «телеметрия» приобрело негативную окраску в мире открытого программного обеспечения, и в многих случаях это вполне обосновано. Однако измерение пользовательского опыта является важным элементом современной инженерии программного обеспечения, а источники данных, такие как вопросы GitHub или ежегодные опросы, являются грубыми и отстающими индикаторами, недостаточными для ответов на вопросы, которые необходимо решить команде Go. Go телеметрия разработана таким образом, чтобы программы в инструментарии могли собирать полезные данные о надежности, производительности и использовании, сохраняя при этом прозрачность и конфиденциальность, которые пользователи ожидают от проекта Go. Чтобы узнать больше о процессе проектирования и мотивации для телеметрии, пожалуйста, ознакомьтесь с блог-постами о телеметрии. Чтобы узнать больше о телеметрии и конфиденциальности, пожалуйста, ознакомьтесь с политикой конфиденциальности телеметрии.

На этой странице подробно описывается, как работает Go телеметрия. Для быстрых ответов на часто задаваемые вопросы см. FAQ.

Используя Go 1.23 или более позднюю версию, чтобы включить загрузку данных телеметрии в команду Go, выполните:
go telemetry on
Чтобы полностью отключить телеметрию, включая локальную сборку, выполните:
go telemetry off
Чтобы вернуться к режиму по умолчанию — локальная телеметрия, выполните:
go telemetry local
До Go 1.23 это также можно сделать с помощью команды golang.org/x/telemetry/cmd/gotelemetry. Дополнительные сведения см. в разделе Конфигурация.

Обзор

Go телеметрия использует три основных типа данных:

  • Счетчики — это легковесные подсчеты именованных событий, которые инструментируются в программах инструментария. Если сбор данных включен (режим modelocal или on), счетчики записываются в файл с отображением в память в локальной файловой системе.
  • Отчеты — это агрегированные сводки счетчиков за определенную неделю. Если загрузка включена (режим modeon), отчеты по одобренным счетчикам загружаются на telemetry.go.dev, где они становятся публично доступными.
  • Графики — это сводка загруженных отчетов для всех пользователей. Графики можно просмотреть на telemetry.go.dev.

Все локальные данные телеметрии Go и конфигурация хранятся в каталоге os.UserConfigDir()/go/telemetry. Ниже мы будем ссылаться на этот каталог как на <gotelemetry>.

Диаграмма ниже иллюстрирует этот поток данных.

В остальной части данного документа мы рассмотрим компоненты этой диаграммы. Но сначала давайте узнаем больше о конфигурации, которая её контролирует.

Конфигурация

Поведение телеметрии Go управляется одним значением: режимом телеметрии. Возможные значения параметра modelocal (по умолчанию), on или off:

  • Когда mode равен local, данные телеметрии собираются и сохраняются на локальном компьютере, но никогда не загружаются на удалённые серверы.
  • Когда mode равен on, данные собираются, и могут быть загружены в зависимости от выборки.
  • Когда mode равен off, данные не собираются и не загружаются.

Начиная с Go 1.23, следующие команды взаимодействуют с режимом телеметрии:

  • go telemetry: показывает текущий режим.
  • go telemetry on: устанавливает режим в on.
  • go telemetry off: устанавливает режим в off.
  • go telemetry local: устанавливает режим в local.

Информация о конфигурации телеметрии также доступна через доступные только для чтения переменные среды Go:

  • go env GOTELEMETRY сообщает о режиме телеметрии.
  • go env GOTELEMETRYDIR сообщает о каталоге, содержащем конфигурацию и данные телеметрии.

Команда gotelemetry также может использоваться для настройки режима телеметрии, а также для проверки локальных данных телеметрии. Используйте эту команду для её установки:

<code>go install golang.org/x/telemetry/cmd/gotelemetry@latest
</code>

Полная информация об использовании командной строки инструмента gotelemetry доступна в документации пакета.

Счетчики

Как упоминалось выше, телеметрия Go реализована через счетчики. Счетчики представляют собой два варианта: базовые счетчики и стековые счетчики.

Базовые счетчики

Базовый счетчик — это увеличиваемое значение с именем, описывающим событие, которое он отслеживает. Например, счетчик gopls/client:vscode записывает количество запусков сеанса gopls, инициированных VS Code. Вместе с этим счетчиком мы можем иметь gopls/client:neovim, gopls/client:eglot и так далее, чтобы записывать сеансы с различными редакторами или клиентами языка. Если вы использовали несколько редакторов в течение недели, вы можете записать следующие данные счетчиков:

<code>gopls/client:vscode 8
gopls/client:neovim 5
gopls/client:eglot  2
</code>

Когда счетчики связаны таким образом, мы иногда называем часть до : названием диаграммы (gopls/client в данном случае), а часть после : называем названием бакета (vscode). Мы увидим, почему это важно при обсуждении диаграмм.

Базовые счетчики также могут представлять гистограмму. Например, счетчик gopls/completion/latency:<50ms записывает количество случаев, когда автозавершение занимает менее 50 мс.

gopls/completion/latency:<10ms
gopls/completion/latency:<50ms
gopls/completion/latency:<100ms
...

Этот шаблон записи данных гистограммы является соглашением: нет ничего особенного в названии бакета <50ms. Такие типы счетчиков часто используются для измерения производительности.

Счётчики стека

Счётчик стека — это счётчик, который также записывает текущий стек вызовов программы инструментария Go при увеличении счётчика. Например, счётчик стека crash/crash записывает стек вызовов при аварийном завершении программы инструментария:

<code>crash/crash
golang.org/x/tools/gopls/internal/golang.hoverBuiltin:+22
golang.org/x/tools/gopls/internal/golang.Hover:+94
golang.org/x/tools/gopls/internal/server.Hover:+42
...
</code>

Счётчики стека обычно измеряют события, в которых нарушаются инварианты программы. Наиболее распространённым примером является сбой (crash), но другим примером является счётчик стека gopls/bug, который подсчитывает необычные ситуации, выявленные заранее программистом, такие как восстановленный panic или ошибка, которая «не должна происходить». Счётчики стека включают только имена и номера строк функций внутри программ инструментария Go. Они не включают никакой информации о пользовательских входных данных, например, имена или содержимое исходного кода пользователя.

Счётчики стека могут помочь выявить редкие или сложные ошибки, которые не сообщаются другими способами. После введения счётчика gopls/bug, мы обнаружили десятки случаев «недоступного» кода, который на практике всё же выполнялся, и выявление этих исключений привело к обнаружению (и исправлению) множества ошибок, видимых для пользователей, которые либо не были очевидны для пользователя, либо были слишком сложны для отчёта. Особенно при тестировании предрелизных версий счётчики стека могут помочь нам улучшить продукт более эффективно, чем без автоматизации.

Файлы счётчиков

Все данные счётчиков записываются в каталог <gotelemetry>/local в файлах, имена которых формируются по следующей схеме:

<code>[имя программы]@[версия программы]-[версия go]-[GOOS]-[GOARCH]-[дата].v1.count
</code>
  • Имя программы — это базовое имя пути пакета программы, как указано в debug.BuildInfo.
  • Версия программы и версия go также предоставляются debug.BuildInfo.
  • Значения GOOS и GOARCH предоставляются runtime.GOOS и runtime.GOARCH.
  • Дата — это дата создания файла счётчика в формате YYYY-MM-DD.

Эти файлы сопоставляются с памятью в каждом запущенном экземпляре инструментированных программ. Использование сопоставленного с памятью файла означает, что даже если программа немедленно аварийно завершится, или несколько копий инструментированных инструментов запущены одновременно, счётчики будут записаны безопасно.

Отчёты и загрузка

Примерно раз в неделю данные счётчиков агрегируются в отчёты с именами <дата>.json в каталоге <gotelemetry>/local. Эти отчёты суммируют все значения счётчиков за предыдущую неделю, сгруппированные по тем же идентификаторам программ, которые используются для файлов счётчиков (имя программы, версия программы, версия go, GOOS и GOARCH).

Локальные отчёты можно просматривать в виде графиков с помощью команды gotelemetry view. Вот пример сводки счётчика gopls/completion/latency:

Загрузка

Если загрузка телеметрии включена, еженедельный процесс формирования отчётов также будет генерировать отчёты, содержащие подмножество счётчиков, указанных в конфигурации загрузки. Эти счётчики должны быть одобрены публичным процессом рассмотрения, описанным в следующем разделе. После успешной загрузки копия загруженных отчётов сохраняется в каталоге <gotelemetry>/upload.

Как только достаточно пользователей примут участие в загрузке телеметрических данных, процесс загрузки будет случайным образом пропускать загрузку для части отчетов, чтобы снизить объемы сбора и повысить конфиденциальность, сохранив при этом статистическую значимость.

Диаграммы

Помимо приема загрузок, веб-сайт telemetry.go.dev делает загруженные данные общедоступными. Каждый день загруженные отчеты обрабатываются и преобразуются в два выходных формата, которые доступны на главной странице telemetry.go.dev.

  • merged — объединенные счетчики из всех загрузок, полученных в указанный день.
  • charts — отображают загруженные данные в соответствии с конфигурацией диаграммы, определенной в [chart config], которая была создана как часть процесса предложения. Помните, что в обсуждении счетчиков говорилось, что имена счетчиков, такие как foo:bar, разбиваются на имя диаграммы foo и имя бакета bar. Каждая диаграмма агрегирует счетчики с одинаковым именем диаграммы в соответствующие бакеты.

Диаграммы задаются в формате пакета chartconfig. Например, вот конфигурация диаграммы для gopls/client.

<code>title: Editor Distribution
counter: gopls/client:{vscode,vscodium,vscode-insiders,code-server,eglot,govim,neovim,coc.nvim,sublimetext,other}
description: measure editor distribution for gopls users.
type: partition
issue: https://go.dev/issue/61038
issue: https://go.dev/issue/62214 # add vscode-insiders
program: golang.org/x/tools/gopls
version: v0.13.0 # temporarily back-version to demonstrate config generation.
</code>

Эта конфигурация описывает создаваемую диаграмму, перечисляет набор счетчиков для агрегации и указывает версии программ, к которым применяется диаграмма. Кроме того, процесс предложения требует, чтобы принятое предложение было связано с диаграммой. Вот диаграмма, полученная в результате этой конфигурации:

Процесс предложения телеметрии

Изменения конфигурации загрузки или набора диаграмм на telemetry.go.dev должны проходить через процесс предложения телеметрии, который предназначен для обеспечения прозрачности изменений в конфигурации телеметрии.

Заметно, что в этом процессе на самом деле нет различия между конфигурацией загрузки и конфигурацией диаграммы. Конфигурация загрузки сама по себе выражается через агрегации, которые мы хотим отобразить на telemetry.go.dev, основываясь на принципе, что мы должны собирать только те данные, которые хотим видеть.

Процесс предложения выглядит следующим образом:

  1. Инициатор предложения создает CL, изменяющий config.txt пакета chartconfig, чтобы он содержал нужные новые агрегации счетчиков.
  2. Инициатор предложения подает предложение на слияние этого CL.
  3. После завершения обсуждения по вопросу, предложение одобряется или отклоняется членом команды Go.
  4. Автоматический процесс пересоздает конфигурацию загрузки, чтобы разрешить загрузку счетчиков, необходимых для новой диаграммы. Этот процесс также регулярно добавляет новые версии соответствующих программ в конфигурацию загрузки по мере их выхода.

Чтобы новая диаграмма могла быть одобрена, она не должна содержать конфиденциальной информации о пользователях, а также должна быть полезной и осуществимой. Чтобы быть полезной, диаграмма должна иметь конкретную цель с действенными результатами. Чтобы быть осуществимой, должно быть возможно надежно собирать необходимые данные, и полученные измерения должны быть статистически значимыми. Чтобы продемонстрировать осуществимость, инициатору может быть предложено инструментировать целевую программу счетчиками и собирать их локально в первую очередь.

Полный набор таких предложений доступен в проекте proposal project на GitHub.

Подсказки для IDE

Для того чтобы телеметрия могла отвечать на типы вопросов, которые мы хотим задать ей, набор пользователей, opting in в загрузку, не обязательно должен быть большим — примерно 16 000 участников позволят получить статистически значимые измерения на желаемом уровне детализации. Однако, даже при этом всё же существует стоимость сбора такой здоровой выборки: нам нужно будет запросить у большого числа разработчиков на Go, хотят ли они принять участие.

Кроме того, даже если большое количество пользователей решит принять участие сейчас (возможно, после прочтения статьи в блоге Go), эти пользователи могут быть смещены в сторону опытных разработчиков на Go, и со временем начальная выборка будет становиться ещё более смещенной. Также, когда люди заменяют свои компьютеры, им необходимо снова активно выбрать участие. В серии блогов о телеметрии это называется “campaign cost” модели opt-in.

Чтобы помочь сохранить выборку активных участников свежей, сервер языка Go gopls поддерживает подсказку, которая запрашивает у пользователей согласие на участие в телеметрии Go. Вот как это выглядит в VS Code:

Если пользователи выберут «Да», их режим телеметрии mode будет установлен в on, так же, как если бы они выполнили gotelemetry on. Таким образом, принять участие максимально просто, и мы можем постоянно достигать большой и разнообразной выборки разработчиков на Go.

Часто задаваемые вопросы

В: Как включить или отключить телеметрию Go?

О: Используйте команду gotelemetry, которую можно установить с помощью go install golang.org/x/telemetry/cmd/gotelemetry@latest. Запустите gotelemetry off, чтобы отключить всё, даже локальную сборку. Запустите gotelemetry on, чтобы включить всё, включая загрузку одобренных счетчиков на telemetry.go.dev. См. раздел Configuration для дополнительной информации.

В: Где хранятся локальные данные?

О: В каталоге os.UserConfigDir()/go/telemetry.

В: Как часто загружаются данные, если вы приняли участие?

О: Примерно раз в неделю.

В: Какие данные загружаются, если вы приняли участие?

О: Только счетчики, перечисленные в upload config. Этот файл генерируется из [chart config], который может быть более читаемым.

В: Как добавляются счетчики в конфигурацию загрузки?

О: Через публичный процесс предложений.

В: Где можно посмотреть загруженные данные телеметрии?

О: Загруженные данные доступны в виде графиков или объединённых сводок на telemetry.go.dev.

В: Где находится исходный код телеметрии Go?

О: На golang.org/x/telemetry.

GoRu.dev Golang на русском

На сайте представлена адаптированная под русский язык документация языка программирования Golang