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