Help us shape the future of Go! Take the 2026 Go Developer Survey

telemetry

package
v0.51.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 26, 2026 License: Apache-2.0 Imports: 30 Imported by: 0

Documentation

Overview

Package telemetry records one usage event per CLI invocation and sends it to the Volcano API, which forwards it to product analytics (volcano-hosting POST /cli/telemetry).

What is sent is fixed by Event: command path, the names of flags the user set, the selected project and the resource names the command addressed (see resources), CLI version, platform, CI vendor, whether stdin is a terminal, the coding agent that ran the CLI, whether the Volcano plugin is installed for that agent, the exit code and duration, and for failed runs the error type, API status and code, and the redacted error message.

Telemetry is on by default. VOLCANO_TELEMETRY_DISABLED or `volcano telemetry disable` turn it off. The settings live in the telemetry block of ~/.volcano/config.json, read once when the process starts: a change applies from the next command. The first recorded invocation prints a one-time notice. Sending happens in a detached `volcano telemetry flush` process so a command never waits on the network.

Index

Constants

View Source
const (
	// EnvDisabled turns telemetry off.
	EnvDisabled = "VOLCANO_TELEMETRY_DISABLED"
	// EnvFeedbackDisabled turns `volcano feedback` reports off, even after
	// `volcano feedback enable`.
	EnvFeedbackDisabled = "VOLCANO_FEEDBACK_DISABLED"
	// EnvDebug prints each event to stderr instead of sending it. Off unless
	// set.
	EnvDebug = "VOLCANO_TELEMETRY_DEBUG"
	// EnvFeedbackDebug appends each `volcano feedback` report to
	// ~/.volcano/feedback.jsonl instead of sending it. Nothing else changes,
	// including the output. For maintainers only, so it is not documented.
	EnvFeedbackDebug = "VOLCANO_FEEDBACK_DEBUG"
)

Environment variables that control telemetry.

View Source
const SkipAnnotation = "telemetry.skip"

SkipAnnotation marks a command whose invocations, and its subcommands', are never recorded (`volcano telemetry`, so an opt-out is not itself reported).

Variables

This section is empty.

Functions

func CIVendor

func CIVendor(getenv func(string) string) string

CIVendor returns the CI vendor id, "generic" when only CI is set, and "" outside CI.

func CanSendFeedback added in v0.51.0

func CanSendFeedback(token string) bool

CanSendFeedback reports whether token can send a feedback report: it is set and is not a project access token.

func DisabledByEnv

func DisabledByEnv(getenv func(string) string) bool

DisabledByEnv reports whether VOLCANO_TELEMETRY_DISABLED turns telemetry off.

func FeedbackDebugByEnv added in v0.51.0

func FeedbackDebugByEnv(getenv func(string) string) bool

FeedbackDebugByEnv reports whether VOLCANO_FEEDBACK_DEBUG saves reports locally instead of sending them.

func FeedbackDisabledByEnv added in v0.51.0

func FeedbackDisabledByEnv(getenv func(string) string) bool

FeedbackDisabledByEnv reports whether VOLCANO_FEEDBACK_DISABLED turns feedback off.

func Flush

func Flush(ctx context.Context, r io.Reader, client *http.Client) error

Flush reads one event payload from r and posts it to the cloud API's /cli/telemetry endpoint, with the saved login token when there is one. The server accepts the event without a token. The opt-out is not checked again: the process that built the event already did.

func IsUsageError added in v0.51.0

func IsUsageError(err error) bool

IsUsageError matches cobra's own argument and flag parsing errors, which are plain errors with fixed message prefixes.

func ScrubText added in v0.51.0

func ScrubText(s, home string) string

ScrubText prepares free text, such as a feedback report, for sending: the home directory replaced with "~", terminal escapes removed, control characters and Unicode spaces other than newlines turned into a space, secrets redacted as in error messages, and surrounding whitespace trimmed. Unlike error messages, line breaks are kept. Spaces are normalized before redacting so a Unicode space cannot hide a secret from the patterns.

Types

type Client added in v0.51.0

type Client struct {
	// Anonymous asks the server not to attribute the report to the user.
	Anonymous       bool
	DeviceID        string
	CLIVersion      string
	OS              string
	Arch            string
	Agent           string
	AgentSource     string
	PluginInstalled bool
	PluginVersion   string
	ProjectID       string
}

Client describes this machine and the coding agent that ran the CLI, with the same values a usage event carries. `volcano feedback` attaches it to each report, so the server can join a report to the usage events of the same device. While telemetry is off, the report is anonymous: DeviceID and ProjectID are empty, since either one ties a report to this machine or to the account that owns the project.

type Event

type Event struct {
	DeviceID        string   `json:"device_id"`
	InvocationID    string   `json:"invocation_id"`
	Timestamp       string   `json:"timestamp"`
	Command         string   `json:"command"`
	Flags           []string `json:"flags"`
	CLIVersion      string   `json:"cli_version"`
	OS              string   `json:"os"`
	Arch            string   `json:"arch"`
	CPUs            int      `json:"cpus"`
	CIVendor        string   `json:"ci_vendor"`
	StdinTTY        bool     `json:"stdin_tty"`
	Agent           string   `json:"agent"`
	AgentSource     string   `json:"agent_source"`
	AgentMarkers    []string `json:"agent_markers"`
	PluginInstalled bool     `json:"plugin_installed"`
	PluginVersion   string   `json:"plugin_version"`
	ExitCode        int      `json:"exit_code"`
	DurationMS      int64    `json:"duration_ms"`
	ErrorKind       string   `json:"error_kind,omitempty"`
	ErrorStatus     int      `json:"error_status,omitempty"`
	ErrorCode       string   `json:"error_code,omitempty"`
	ErrorMessage    string   `json:"error_message,omitempty"`
	ProjectID       string   `json:"project_id,omitempty"`
	// Resources maps a usage-line placeholder or flag name to the resource
	// name or ID the command was given.
	Resources map[string]string `json:"resources,omitempty"`
}

Event is the request body of POST /cli/telemetry. Field names are the wire contract with volcano-hosting; the server re-validates every value.

type FeedbackState added in v0.51.0

type FeedbackState int

FeedbackState says whether the feedback setting is on, and if not, why.

const (
	// FeedbackSettingOn means enabled with `volcano feedback enable`, or never
	// chosen while telemetry is on.
	FeedbackSettingOn FeedbackState = iota
	// FeedbackOffByEnv means VOLCANO_FEEDBACK_DISABLED is set.
	FeedbackOffByEnv
	// FeedbackOffByUser means turned off with `volcano feedback disable`.
	FeedbackOffByUser
	// FeedbackOffWithTelemetry means never chosen, and telemetry is off.
	FeedbackOffWithTelemetry
)

func FeedbackSetting added in v0.51.0

func FeedbackSetting(cfg *config.Config, getenv func(string) string) FeedbackState

FeedbackSetting returns the feedback setting for cfg, which may be nil for a home with no config. VOLCANO_FEEDBACK_DISABLED turns feedback off. Otherwise `volcano feedback enable` or `disable` decides, and when the user chose neither, feedback follows telemetry: a telemetry opt-out, in the config or by VOLCANO_TELEMETRY_DISABLED, also turns feedback off.

type Invocation

type Invocation struct {
	Command  *cobra.Command // the executed command (cobra ExecuteC); may be nil
	Err      error
	ExitCode int
	Start    time.Time
	Stderr   io.Writer // receives the first-run notice and debug output
	StdinTTY bool
	// Args are the raw command-line arguments, checked for --offline when
	// flag parsing failed before cobra read it.
	Args []string
}

Invocation is what the entry point knows about the command that just ran.

type Recorder

type Recorder struct {
	Getenv    func(string) string
	LookupEnv func(string) (string, bool)
	Now       func() time.Time
	// LoadConfig reads the CLI config (config.Load). When the working
	// directory's project link cannot be used, it returns the
	// *config.LinkError together with the config read without the link, so
	// feedback, which does not need the link, still works.
	LoadConfig func() (*config.Config, error)
	// UpdateConfig changes the config under its lock (config.Update).
	UpdateConfig func(mutate func(*config.Config) (bool, error)) error
	// HomeDir is replaced with "~" in error messages (os.UserHomeDir).
	HomeDir func() (string, error)
	Send    func(payload []byte) error
	// PluginStatus reports whether the Volcano plugin is installed for a
	// setup harness name; see setup.PluginStatus.
	PluginStatus func(harness string) (bool, string)
	// contains filtered or unexported fields
}

Recorder records the invocation of one CLI process. It reads the config once, on first use, and answers both Reporting and Record from that read. The zero value uses the real environment, config, and flush process; tests replace the fields. A Recorder must not be copied after first use.

func (*Recorder) AnnounceFeedback added in v0.51.0

func (r *Recorder) AnnounceFeedback(w io.Writer) bool

AnnounceFeedback shows the first-run notice now, when the feedback setting is on and feedback was not announced yet, and reports whether the config records the feedback notice, so a report from the next process is sent. It is false when the setting is off, the config cannot be read, or the notice cannot be saved, such as in a read-only home. `volcano feedback status` calls it so that its answer holds for the next command; Record in the same process then shows nothing again.

func (*Recorder) Client added in v0.51.0

func (r *Recorder) Client() Client

Client returns what this process may report about the machine and the coding agent with a feedback report. The device ID and the project ID are set only while telemetry is on and was announced (see Reporting); otherwise the report is anonymous. A project link that cannot be used leaves the project ID out, since the project it names is unknown, and does not make the report anonymous. A machine that has seen the notice but has no device ID yet, such as after `volcano telemetry enable` on a fresh home, gets one now.

func (*Recorder) FeedbackOn added in v0.51.0

func (r *Recorder) FeedbackOn() bool

FeedbackOn reports whether `volcano feedback` may send a report: the config is readable, the feedback setting is on (see FeedbackSetting), and an earlier process showed the first-run notice for feedback. A project link that cannot be used does not turn feedback off: a report does not need it, and a broken link is a problem worth reporting.

func (*Recorder) Home added in v0.51.0

func (r *Recorder) Home() string

Home returns the home directory to pass to ScrubText, or "" when it is unknown.

func (*Recorder) LoggedIn added in v0.51.0

func (r *Recorder) LoggedIn() bool

LoggedIn reports whether the config holds a login token that can send a feedback report. `volcano feedback` sends nothing without one. A project access token does not count: the server takes reports only from an account.

func (*Recorder) Record

func (r *Recorder) Record(inv Invocation)

Record records one invocation and shows the first-run notice. It never fails the command: every error is swallowed, since telemetry must not change what the CLI does.

The notice covers usage data and feedback reports, and each has its own "shown" record. It is printed when either one is on and has not been announced yet. Feedback is off while telemetry is, unless the user ran `volcano feedback enable`, so a telemetry opt-out prints no notice and writes no config.

func (*Recorder) Reporting

func (r *Recorder) Reporting() bool

Reporting reports whether this process may send usage data, including the agent request headers: no env opt-out, not turned off with `volcano telemetry disable`, and the first-run notice already shown by an earlier process. A config that cannot be read, or a run before the notice (including every run in a home where the notice can never be saved), counts as off.

type State

type State = config.TelemetryConfig

State is the telemetry block of ~/.volcano/config.json.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL