telemetry_events.rs

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