Merge pull request #1829 from zed-industries/add-release-channel-information-to-telemetry-events

Joseph T. Lyons created

Add release channel information to telemetry events

Change summary

crates/auto_update/src/update_notification.rs |  6 +-----
crates/client/src/amplitude_telemetry.rs      | 10 ++++++++++
crates/client/src/telemetry.rs                | 17 ++++++++++++++++-
crates/editor/src/editor.rs                   |  2 +-
crates/settings/src/settings.rs               | 10 ++++++++++
crates/zed/src/main.rs                        |  6 +++---
crates/zed/src/zed.rs                         |  6 +-----
7 files changed, 42 insertions(+), 15 deletions(-)

Detailed changes

crates/auto_update/src/update_notification.rs 🔗

@@ -29,11 +29,7 @@ impl View for UpdateNotification {
         let theme = cx.global::<Settings>().theme.clone();
         let theme = &theme.update_notification;
 
-        let app_name = match *cx.global::<ReleaseChannel>() {
-            ReleaseChannel::Dev => "Zed Dev",
-            ReleaseChannel::Preview => "Zed Preview",
-            ReleaseChannel::Stable => "Zed",
-        };
+        let app_name = cx.global::<ReleaseChannel>().name();
 
         MouseEventHandler::<ViewReleaseNotes>::new(0, cx, |state, cx| {
             Flex::column()

crates/client/src/amplitude_telemetry.rs 🔗

@@ -10,6 +10,7 @@ use lazy_static::lazy_static;
 use parking_lot::Mutex;
 use serde::Serialize;
 use serde_json::json;
+use settings::ReleaseChannel;
 use std::{
     io::Write,
     mem,
@@ -33,6 +34,7 @@ struct AmplitudeTelemetryState {
     metrics_id: Option<Arc<str>>,
     device_id: Option<Arc<str>>,
     app_version: Option<Arc<str>>,
+    release_channel: Option<&'static str>,
     os_version: Option<Arc<str>>,
     os_name: &'static str,
     queue: Vec<AmplitudeEvent>,
@@ -70,6 +72,7 @@ struct AmplitudeEvent {
     app_version: Option<Arc<str>>,
     #[serde(rename = "App")]
     app: &'static str,
+    release_channel: Option<&'static str>,
     event_id: usize,
     session_id: u128,
     time: u128,
@@ -90,6 +93,11 @@ const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(30);
 impl AmplitudeTelemetry {
     pub fn new(client: Arc<dyn HttpClient>, cx: &AppContext) -> Arc<Self> {
         let platform = cx.platform();
+        let release_channel = if cx.has_global::<ReleaseChannel>() {
+            Some(cx.global::<ReleaseChannel>().name())
+        } else {
+            None
+        };
         let this = Arc::new(Self {
             http_client: client,
             executor: cx.background().clone(),
@@ -101,6 +109,7 @@ impl AmplitudeTelemetry {
                 os_version: platform.os_version().ok().map(|v| v.to_string().into()),
                 os_name: platform.os_name().into(),
                 app_version: platform.app_version().ok().map(|v| v.to_string().into()),
+                release_channel,
                 device_id: None,
                 queue: Default::default(),
                 flush_task: Default::default(),
@@ -215,6 +224,7 @@ impl AmplitudeTelemetry {
             app: "Zed",
             os_version: state.os_version.clone(),
             app_version: state.app_version.clone(),
+            release_channel: state.release_channel,
             event_id: post_inc(&mut state.next_event_id),
         };
         state.queue.push(event);

crates/client/src/telemetry.rs 🔗

@@ -10,6 +10,7 @@ use lazy_static::lazy_static;
 use parking_lot::Mutex;
 use serde::Serialize;
 use serde_json::json;
+use settings::ReleaseChannel;
 use std::{
     io::Write,
     mem,
@@ -32,6 +33,7 @@ struct TelemetryState {
     metrics_id: Option<Arc<str>>,
     device_id: Option<Arc<str>>,
     app_version: Option<Arc<str>>,
+    release_channel: Option<&'static str>,
     os_version: Option<Arc<str>>,
     os_name: &'static str,
     queue: Vec<MixpanelEvent>,
@@ -67,9 +69,15 @@ struct MixpanelEventProperties {
     // Custom fields
     #[serde(skip_serializing_if = "Option::is_none", flatten)]
     event_properties: Option<Map<String, Value>>,
+    #[serde(rename = "OS Name")]
     os_name: &'static str,
+    #[serde(rename = "OS Version")]
     os_version: Option<Arc<str>>,
+    #[serde(rename = "Release Channel")]
+    release_channel: Option<&'static str>,
+    #[serde(rename = "App Version")]
     app_version: Option<Arc<str>>,
+    #[serde(rename = "Signed In")]
     signed_in: bool,
     #[serde(rename = "App")]
     app: &'static str,
@@ -100,6 +108,11 @@ const DEBOUNCE_INTERVAL: Duration = Duration::from_secs(30);
 impl Telemetry {
     pub fn new(client: Arc<dyn HttpClient>, cx: &AppContext) -> Arc<Self> {
         let platform = cx.platform();
+        let release_channel = if cx.has_global::<ReleaseChannel>() {
+            Some(cx.global::<ReleaseChannel>().name())
+        } else {
+            None
+        };
         let this = Arc::new(Self {
             http_client: client,
             executor: cx.background().clone(),
@@ -107,6 +120,7 @@ impl Telemetry {
                 os_version: platform.os_version().ok().map(|v| v.to_string().into()),
                 os_name: platform.os_name().into(),
                 app_version: platform.app_version().ok().map(|v| v.to_string().into()),
+                release_channel,
                 device_id: None,
                 metrics_id: None,
                 queue: Default::default(),
@@ -189,7 +203,7 @@ impl Telemetry {
                         let json_bytes = serde_json::to_vec(&[MixpanelEngageRequest {
                             token,
                             distinct_id: device_id,
-                            set: json!({ "staff": is_staff, "id": metrics_id }),
+                            set: json!({ "Staff": is_staff, "ID": metrics_id }),
                         }])?;
                         let request = Request::post(MIXPANEL_ENGAGE_URL)
                             .header("Content-Type", "application/json")
@@ -222,6 +236,7 @@ impl Telemetry {
                 },
                 os_name: state.os_name,
                 os_version: state.os_version.clone(),
+                release_channel: state.release_channel,
                 app_version: state.app_version.clone(),
                 signed_in: state.metrics_id.is_some(),
                 app: "Zed",

crates/editor/src/editor.rs 🔗

@@ -6470,7 +6470,7 @@ impl Editor {
             project.read(cx).client().report_event(
                 name,
                 json!({
-                    "file_extension": file
+                    "File Extension": file
                         .path()
                         .extension()
                         .and_then(|e| e.to_str())

crates/settings/src/settings.rs 🔗

@@ -62,6 +62,16 @@ pub enum ReleaseChannel {
     Stable,
 }
 
+impl ReleaseChannel {
+    pub fn name(&self) -> &'static str {
+        match self {
+            ReleaseChannel::Dev => "Zed Dev",
+            ReleaseChannel::Preview => "Zed Preview",
+            ReleaseChannel::Stable => "Zed",
+        }
+    }
+}
+
 impl FeatureFlags {
     pub fn keymap_files(&self) -> Vec<&'static str> {
         vec![]

crates/zed/src/main.rs 🔗

@@ -90,6 +90,9 @@ fn main() {
     });
 
     app.run(move |cx| {
+        cx.set_global(*RELEASE_CHANNEL);
+        cx.set_global(HomeDir(zed::paths::HOME.to_path_buf()));
+
         let client = client::Client::new(http.clone(), cx);
         let mut languages = LanguageRegistry::new(login_shell_env_loaded);
         languages.set_language_server_download_dir(zed::paths::LANGUAGES_DIR.clone());
@@ -101,9 +104,6 @@ fn main() {
 
         let (settings_file_content, keymap_file) = cx.background().block(config_files).unwrap();
 
-        cx.set_global(*RELEASE_CHANNEL);
-        cx.set_global(HomeDir(zed::paths::HOME.to_path_buf()));
-
         //Setup settings global before binding actions
         cx.set_global(SettingsFile::new(
             &*zed::paths::SETTINGS,

crates/zed/src/zed.rs 🔗

@@ -389,11 +389,7 @@ fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) {
 }
 
 fn about(_: &mut Workspace, _: &About, cx: &mut gpui::ViewContext<Workspace>) {
-    let app_name = match *cx.global::<ReleaseChannel>() {
-        ReleaseChannel::Dev => "Zed Dev",
-        ReleaseChannel::Preview => "Zed Preview",
-        ReleaseChannel::Stable => "Zed",
-    };
+    let app_name = cx.global::<ReleaseChannel>().name();
     let version = env!("CARGO_PKG_VERSION");
     cx.prompt(
         gpui::PromptLevel::Info,