Documentation
¶
Overview ¶
Package telemetry provides an opt-in telemetry framework with pluggable backends, privacy controls, and bounded buffering with disk spill.
Index ¶
- func HashedMachineID() string
- func ResolveDataDir(p *props.Props) string
- type Backend
- type Collector
- func (c *Collector) BackendInfo() string
- func (c *Collector) Close(ctx context.Context) error
- func (c *Collector) Drop() error
- func (c *Collector) Flush(ctx context.Context) error
- func (c *Collector) SetBackendInfo(info string)
- func (c *Collector) Track(eventType props.EventType, name string, extra map[string]string)
- func (c *Collector) TrackCommand(name string, durationMs int64, exitCode int, extra map[string]string)
- func (c *Collector) TrackCommandExtended(name string, args []string, durationMs int64, exitCode int, errMsg string, ...)
- type Config
- type DeletionRequestor
- type EmailDeletionRequestor
- type Event
- type EventDeletionRequestor
- type EventType
- type HTTPDeletionRequestor
- type OTelOption
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func HashedMachineID ¶
func HashedMachineID() string
HashedMachineID returns a privacy-preserving machine identifier derived from multiple system signals: OS machine ID, first non-loopback MAC address, hostname, and username. Each signal degrades gracefully if unavailable. The result is the first 8 bytes of the SHA-256 hash, encoded as 16 hex chars. Computed fresh on every invocation — not persisted to config.
func ResolveDataDir ¶
ResolveDataDir determines the directory for telemetry data files (spill files, local-only logs). Uses the config directory if it exists and is writable, otherwise falls back to os.TempDir().
Types ¶
type Backend ¶
Backend is the interface for telemetry data sinks. Implementations must be safe for concurrent use. Send must be non-blocking or short-timeout to avoid impacting CLI performance.
func NewFileBackend ¶
NewFileBackend returns a backend that appends events as newline-delimited JSON.
func NewHTTPBackend ¶
NewHTTPBackend returns a backend that POSTs events as JSON to the given endpoint. Non-2xx responses are logged at debug level via the provided logger. Network errors are silently dropped — telemetry must never block the user.
func NewNoopBackend ¶
func NewNoopBackend() Backend
NewNoopBackend returns a backend that silently discards all events.
func NewOTelBackend ¶
NewOTelBackend creates a Backend that exports events as OTel log records via OTLP/HTTP. endpoint is the full URL of the OTLP HTTP endpoint (e.g. "https://otlp-gateway-prod-eu-west-0.grafana.net/otlp"). The URL is parsed into host and path components — the SDK appends /v1/logs to the path automatically. A custom OTel error handler is registered to route SDK errors to the provided logger.
func NewStdoutBackend ¶
NewStdoutBackend returns a backend that writes events as pretty-printed JSON.
type Collector ¶
type Collector struct {
// contains filtered or unexported fields
}
Collector accumulates events and flushes to the backend. All methods are safe for concurrent use. When disabled, all operations are no-ops — callers do not need to check whether telemetry is enabled.
func NewCollector ¶
func NewCollector(cfg Config, backend Backend, toolName, version string, metadata map[string]string, log logger.Logger, dataDir string, deliveryMode props.DeliveryMode, extendedCollection bool) *Collector
NewCollector creates a Collector. When cfg.Enabled is false, returns a noop collector so callers never need to nil-check.
func (*Collector) BackendInfo ¶ added in v1.9.4
BackendInfo returns a human-readable description of the active backend.
func (*Collector) Close ¶ added in v1.9.1
Close flushes pending events and shuts down the backend gracefully. Must be called on process exit to ensure backends like OTLP flush their internal batch queues.
func (*Collector) Drop ¶
Drop clears all buffered events and deletes any spill files without sending. Called when the user disables telemetry to ensure immediate consent withdrawal.
func (*Collector) Flush ¶
Flush sends all buffered events to the backend, then clears the buffer. Checks for and sends spill files before flushing the current buffer.
func (*Collector) SetBackendInfo ¶ added in v1.9.4
SetBackendInfo sets the human-readable backend description. Called by the root command after backend selection.
func (*Collector) Track ¶
Track records a telemetry event. No-op when collector is disabled. When the in-memory buffer reaches maxBuffer, events are spilled to disk.
func (*Collector) TrackCommand ¶
func (c *Collector) TrackCommand(name string, durationMs int64, exitCode int, extra map[string]string)
TrackCommand records a command invocation event with duration and exit code. This is a convenience wrapper around Track for command lifecycle events.
func (*Collector) TrackCommandExtended ¶ added in v1.9.1
func (c *Collector) TrackCommandExtended(name string, args []string, durationMs int64, exitCode int, errMsg string, extra map[string]string)
TrackCommandExtended records a command invocation with full context. When ExtendedCollection is disabled on the collector, args and errMsg are silently dropped — callers do not need to check the flag themselves.
type Config ¶
Config holds runtime telemetry configuration read from the user's config file. Endpoints are not included — they are tool-author concerns set in props.TelemetryConfig, not user-configurable.
type DeletionRequestor ¶
DeletionRequestor sends a GDPR data deletion request for a given machine ID. Implementations should be best-effort — deletion cannot be guaranteed for all backend types.
func NewEmailDeletionRequestor ¶
func NewEmailDeletionRequestor(address, toolName string) DeletionRequestor
NewEmailDeletionRequestor creates a requestor that opens a pre-filled mailto: link for the user to send a deletion request.
func NewEventDeletionRequestor ¶
func NewEventDeletionRequestor(backend Backend) DeletionRequestor
NewEventDeletionRequestor creates a requestor that emits a deletion request event through the provided backend.
func NewHTTPDeletionRequestor ¶
func NewHTTPDeletionRequestor(endpoint string, log logger.Logger) DeletionRequestor
NewHTTPDeletionRequestor creates a requestor that POSTs a JSON deletion request to the given endpoint.
type EmailDeletionRequestor ¶
type EmailDeletionRequestor struct {
// contains filtered or unexported fields
}
EmailDeletionRequestor composes a deletion request email by opening the user's default mail client via a mailto: URL.
func (*EmailDeletionRequestor) RequestDeletion ¶
func (e *EmailDeletionRequestor) RequestDeletion(ctx context.Context, machineID string) error
type Event ¶
type Event struct {
Timestamp time.Time `json:"timestamp"`
Type EventType `json:"type"`
Name string `json:"name"`
MachineID string `json:"machine_id"`
ToolName string `json:"tool_name"`
Version string `json:"version"`
OS string `json:"os"`
Arch string `json:"arch"`
GoVersion string `json:"go_version"`
OSVersion string `json:"os_version"`
DurationMs int64 `json:"duration_ms,omitempty"`
ExitCode int `json:"exit_code,omitempty"`
Args []string `json:"args,omitempty"` // only populated when ExtendedCollection is enabled
Error string `json:"error,omitempty"` // only populated when ExtendedCollection is enabled
Metadata map[string]string `json:"metadata,omitempty"`
}
Event represents a single telemetry event.
type EventDeletionRequestor ¶
type EventDeletionRequestor struct {
// contains filtered or unexported fields
}
EventDeletionRequestor sends a data.deletion_request event through the existing telemetry backend. This is the universal fallback — works with any backend type.
func (*EventDeletionRequestor) RequestDeletion ¶
func (e *EventDeletionRequestor) RequestDeletion(ctx context.Context, machineID string) error
type EventType ¶
type EventType string
EventType identifies the category of telemetry event. Mirrored from pkg/props — since both resolve to string, values are interchangeable at the interface boundary.
const ( EventCommandInvocation EventType = "command.invocation" EventCommandError EventType = "command.error" EventFeatureUsed EventType = "feature.used" EventUpdateCheck EventType = "update.check" EventUpdateApplied EventType = "update.applied" EventDeletionRequest EventType = "data.deletion_request" )
type HTTPDeletionRequestor ¶
type HTTPDeletionRequestor struct {
// contains filtered or unexported fields
}
HTTPDeletionRequestor sends a deletion request via HTTP POST.
func (*HTTPDeletionRequestor) RequestDeletion ¶
func (h *HTTPDeletionRequestor) RequestDeletion(ctx context.Context, machineID string) error
type OTelOption ¶
type OTelOption func(*otelConfig)
OTelOption configures the OTLP backend.
func WithOTelHeaders ¶
func WithOTelHeaders(headers map[string]string) OTelOption
WithOTelHeaders sets HTTP headers sent with every OTLP request (e.g. auth tokens).
func WithOTelInsecure ¶
func WithOTelInsecure() OTelOption
WithOTelInsecure disables TLS — use only for local collectors.
func WithOTelLogger ¶
func WithOTelLogger(l logger.Logger) OTelOption
WithOTelLogger sets the logger for routing OTel SDK errors.
func WithOTelService ¶
func WithOTelService(name, version string) OTelOption
WithOTelService sets the service.name and service.version resource attributes. These appear as labels in Grafana/Loki and identify the tool in the telemetry data.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package datadog provides a telemetry backend that sends events to Datadog's HTTP Logs Intake API.
|
Package datadog provides a telemetry backend that sends events to Datadog's HTTP Logs Intake API. |
|
Package posthog provides a telemetry backend that sends events to PostHog's Capture API using the batch endpoint.
|
Package posthog provides a telemetry backend that sends events to PostHog's Capture API using the batch endpoint. |