telemetry_events.rs

  1//! See [Telemetry in Zed](https://zed.dev/docs/telemetry) for additional information.
  2
  3use semantic_version::SemanticVersion;
  4use serde::{Deserialize, Serialize};
  5use std::{fmt::Display, sync::Arc, time::Duration};
  6
  7#[derive(Serialize, Deserialize, Debug)]
  8pub struct EventRequestBody {
  9    /// Identifier unique to each system Zed is installed on
 10    pub system_id: Option<String>,
 11    /// Identifier unique to each Zed installation (differs for stable, preview, dev)
 12    pub installation_id: Option<String>,
 13    /// Identifier unique to each logged in Zed user (randomly generated on first sign in)
 14    /// Identifier unique to each Zed session (differs for each time you open Zed)
 15    pub session_id: Option<String>,
 16    pub metrics_id: Option<String>,
 17    /// True for Zed staff, otherwise false
 18    pub is_staff: Option<bool>,
 19    /// Zed version number
 20    pub app_version: String,
 21    pub os_name: String,
 22    pub os_version: Option<String>,
 23    pub architecture: String,
 24    /// Zed release channel (stable, preview, dev)
 25    pub release_channel: Option<String>,
 26    pub events: Vec<EventWrapper>,
 27}
 28
 29impl EventRequestBody {
 30    pub fn semver(&self) -> Option<SemanticVersion> {
 31        self.app_version.parse().ok()
 32    }
 33}
 34
 35#[derive(Serialize, Deserialize, Debug)]
 36pub struct EventWrapper {
 37    pub signed_in: bool,
 38    /// Duration between this event's timestamp and the timestamp of the first event in the current batch
 39    pub milliseconds_since_first_event: i64,
 40    /// The event itself
 41    #[serde(flatten)]
 42    pub event: Event,
 43}
 44
 45#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
 46#[serde(rename_all = "snake_case")]
 47pub enum AssistantKind {
 48    Panel,
 49    Inline,
 50}
 51impl Display for AssistantKind {
 52    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 53        write!(
 54            f,
 55            "{}",
 56            match self {
 57                Self::Panel => "panel",
 58                Self::Inline => "inline",
 59            }
 60        )
 61    }
 62}
 63
 64#[derive(Default, Clone, Debug, PartialEq, Serialize, Deserialize)]
 65#[serde(rename_all = "snake_case")]
 66pub enum AssistantPhase {
 67    #[default]
 68    Response,
 69    Invoked,
 70    Accepted,
 71    Rejected,
 72}
 73
 74impl Display for AssistantPhase {
 75    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 76        write!(
 77            f,
 78            "{}",
 79            match self {
 80                Self::Response => "response",
 81                Self::Invoked => "invoked",
 82                Self::Accepted => "accepted",
 83                Self::Rejected => "rejected",
 84            }
 85        )
 86    }
 87}
 88
 89#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
 90#[serde(tag = "type")]
 91pub enum Event {
 92    Editor(EditorEvent),
 93    Copilot(CopilotEvent), // Needed for clients sending old copilot_event types
 94    InlineCompletion(InlineCompletionEvent),
 95    Call(CallEvent),
 96    Assistant(AssistantEvent),
 97    Cpu(CpuEvent),
 98    Memory(MemoryEvent),
 99    App(AppEvent),
100    Setting(SettingEvent),
101    Extension(ExtensionEvent),
102    Edit(EditEvent),
103    Action(ActionEvent),
104    Repl(ReplEvent),
105}
106
107#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
108pub struct EditorEvent {
109    /// The editor operation performed (open, save)
110    pub operation: String,
111    /// The extension of the file that was opened or saved
112    pub file_extension: Option<String>,
113    /// Whether the user is in vim mode or not
114    pub vim_mode: bool,
115    /// Whether the user has copilot enabled or not
116    pub copilot_enabled: bool,
117    /// Whether the user has copilot enabled for the language of the file opened or saved
118    pub copilot_enabled_for_language: bool,
119}
120
121/// Deprecated since Zed v0.137.0 (2024-05-29). Replaced by InlineCompletionEvent.
122// Needed for clients sending old copilot_event types
123#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
124pub struct CopilotEvent {
125    pub suggestion_id: Option<String>,
126    pub suggestion_accepted: bool,
127    pub file_extension: Option<String>,
128}
129
130#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
131pub struct InlineCompletionEvent {
132    /// Provider of the completion suggestion (e.g. copilot, supermaven)
133    pub provider: String,
134    pub suggestion_accepted: bool,
135    pub file_extension: Option<String>,
136}
137
138#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
139pub struct CallEvent {
140    /// Operation performed: invite/join call; begin/end screenshare; share/unshare project; etc
141    pub operation: String,
142    pub room_id: Option<u64>,
143    pub channel_id: Option<u64>,
144}
145
146#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
147pub struct AssistantEvent {
148    /// Unique random identifier for each assistant tab (None for inline assist)
149    pub conversation_id: Option<String>,
150    /// The kind of assistant (Panel, Inline)
151    pub kind: AssistantKind,
152    #[serde(default)]
153    pub phase: AssistantPhase,
154    /// Name of the AI model used (gpt-4o, claude-3-5-sonnet, etc)
155    pub model: String,
156    pub response_latency: Option<Duration>,
157    pub error_message: Option<String>,
158}
159
160#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
161pub struct CpuEvent {
162    pub usage_as_percentage: f32,
163    pub core_count: u32,
164}
165
166#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
167pub struct MemoryEvent {
168    pub memory_in_bytes: u64,
169    pub virtual_memory_in_bytes: u64,
170}
171
172#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
173pub struct ActionEvent {
174    pub source: String,
175    pub action: String,
176}
177
178#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
179pub struct EditEvent {
180    pub duration: i64,
181    pub environment: String,
182}
183
184#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
185pub struct SettingEvent {
186    pub setting: String,
187    pub value: String,
188}
189
190#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
191pub struct ExtensionEvent {
192    pub extension_id: Arc<str>,
193    pub version: Arc<str>,
194}
195
196#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
197pub struct AppEvent {
198    pub operation: String,
199}
200
201#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
202pub struct ReplEvent {
203    pub kernel_language: String,
204    pub kernel_status: String,
205    pub repl_session_id: String,
206}
207
208#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
209pub struct BacktraceFrame {
210    pub ip: usize,
211    pub symbol_addr: usize,
212    pub base: Option<usize>,
213    pub symbols: Vec<String>,
214}
215
216#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
217pub struct HangReport {
218    pub backtrace: Vec<BacktraceFrame>,
219    pub app_version: Option<SemanticVersion>,
220    pub os_name: String,
221    pub os_version: Option<String>,
222    pub architecture: String,
223    /// Identifier unique to each Zed installation (differs for stable, preview, dev)
224    pub installation_id: Option<String>,
225}
226
227#[derive(Serialize, Deserialize)]
228pub struct LocationData {
229    pub file: String,
230    pub line: u32,
231}
232
233#[derive(Serialize, Deserialize)]
234pub struct Panic {
235    /// The name of the thread that panicked
236    pub thread: String,
237    /// The panic message
238    pub payload: String,
239    /// The location of the panic (file, line number)
240    #[serde(skip_serializing_if = "Option::is_none")]
241    pub location_data: Option<LocationData>,
242    pub backtrace: Vec<String>,
243    /// Zed version number
244    pub app_version: String,
245    /// Zed release channel (stable, preview, dev)
246    pub release_channel: String,
247    pub os_name: String,
248    pub os_version: Option<String>,
249    pub architecture: String,
250    /// The time the panic occurred (UNIX millisecond timestamp)
251    pub panicked_on: i64,
252    /// Identifier unique to each system Zed is installed on
253    #[serde(skip_serializing_if = "Option::is_none")]
254    pub system_id: Option<String>,
255    /// Identifier unique to each Zed installation (differs for stable, preview, dev)
256    #[serde(skip_serializing_if = "Option::is_none")]
257    pub installation_id: Option<String>,
258    /// Identifier unique to each Zed session (differs for each time you open Zed)
259    pub session_id: String,
260}
261
262#[derive(Serialize, Deserialize)]
263pub struct PanicRequest {
264    pub panic: Panic,
265}