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
- func CIVendor(getenv func(string) string) string
- func CanSendFeedback(token string) bool
- func DisabledByEnv(getenv func(string) string) bool
- func FeedbackDebugByEnv(getenv func(string) string) bool
- func FeedbackDisabledByEnv(getenv func(string) string) bool
- func Flush(ctx context.Context, r io.Reader, client *http.Client) error
- func IsUsageError(err error) bool
- func ScrubText(s, home string) string
- type Client
- type Event
- type FeedbackState
- type Invocation
- type Recorder
- type State
Constants ¶
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.
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 ¶
CIVendor returns the CI vendor id, "generic" when only CI is set, and "" outside CI.
func CanSendFeedback ¶ added in v0.51.0
CanSendFeedback reports whether token can send a feedback report: it is set and is not a project access token.
func DisabledByEnv ¶
DisabledByEnv reports whether VOLCANO_TELEMETRY_DISABLED turns telemetry off.
func FeedbackDebugByEnv ¶ added in v0.51.0
FeedbackDebugByEnv reports whether VOLCANO_FEEDBACK_DEBUG saves reports locally instead of sending them.
func FeedbackDisabledByEnv ¶ added in v0.51.0
FeedbackDisabledByEnv reports whether VOLCANO_FEEDBACK_DISABLED turns feedback off.
func Flush ¶
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
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
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
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
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
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
Home returns the home directory to pass to ScrubText, or "" when it is unknown.
func (*Recorder) LoggedIn ¶ added in v0.51.0
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 ¶
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.