Remove code sending zed events to mixpanel

This commit is contained in:
Joseph Lyons 2023-06-05 15:33:17 -04:00
parent 2190a27dff
commit 311074e397
8 changed files with 4 additions and 272 deletions

View file

@ -93,7 +93,6 @@ jobs:
MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }} APPLE_NOTARIZATION_USERNAME: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }} APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
ZED_MIXPANEL_TOKEN: ${{ secrets.ZED_MIXPANEL_TOKEN }}
steps: steps:
- name: Install Rust - name: Install Rust
run: | run: |

View file

@ -21,19 +21,3 @@ jobs:
${{ github.event.release.body }} ${{ github.event.release.body }}
``` ```
mixpanel_release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: "3.10.5"
architecture: "x64"
cache: "pip"
- run: pip install -r script/mixpanel_release/requirements.txt
- run: >
python script/mixpanel_release/main.py
${{ github.event.release.tag_name }}
${{ secrets.MIXPANEL_PROJECT_ID }}
${{ secrets.MIXPANEL_SERVICE_ACCOUNT_USERNAME }}
${{ secrets.MIXPANEL_SERVICE_ACCOUNT_SECRET }}

View file

@ -776,15 +776,6 @@ impl Client {
if credentials.is_none() && try_keychain { if credentials.is_none() && try_keychain {
credentials = read_credentials_from_keychain(cx); credentials = read_credentials_from_keychain(cx);
read_from_keychain = credentials.is_some(); read_from_keychain = credentials.is_some();
if read_from_keychain {
cx.read(|cx| {
self.telemetry().report_mixpanel_event(
"read credentials from keychain",
Default::default(),
*settings::get::<TelemetrySettings>(cx),
);
});
}
} }
if credentials.is_none() { if credentials.is_none() {
let mut status_rx = self.status(); let mut status_rx = self.status();
@ -1072,11 +1063,8 @@ impl Client {
) -> Task<Result<Credentials>> { ) -> Task<Result<Credentials>> {
let platform = cx.platform(); let platform = cx.platform();
let executor = cx.background(); let executor = cx.background();
let telemetry = self.telemetry.clone();
let http = self.http.clone(); let http = self.http.clone();
let telemetry_settings = cx.read(|cx| *settings::get::<TelemetrySettings>(cx));
executor.clone().spawn(async move { executor.clone().spawn(async move {
// Generate a pair of asymmetric encryption keys. The public key will be used by the // Generate a pair of asymmetric encryption keys. The public key will be used by the
// zed server to encrypt the user's access token, so that it can'be intercepted by // zed server to encrypt the user's access token, so that it can'be intercepted by
@ -1159,12 +1147,6 @@ impl Client {
.context("failed to decrypt access token")?; .context("failed to decrypt access token")?;
platform.activate(true); platform.activate(true);
telemetry.report_mixpanel_event(
"authenticate with browser",
Default::default(),
telemetry_settings,
);
Ok(Credentials { Ok(Credentials {
user_id: user_id.parse()?, user_id: user_id.parse()?,
access_token, access_token,

View file

@ -1,14 +1,9 @@
use crate::{TelemetrySettings, ZED_SECRET_CLIENT_TOKEN, ZED_SERVER_URL}; use crate::{TelemetrySettings, ZED_SECRET_CLIENT_TOKEN, ZED_SERVER_URL};
use db::kvp::KEY_VALUE_STORE; use db::kvp::KEY_VALUE_STORE;
use gpui::{ use gpui::{executor::Background, serde_json, AppContext, Task};
executor::Background,
serde_json::{self, value::Map, Value},
AppContext, Task,
};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use parking_lot::Mutex; use parking_lot::Mutex;
use serde::Serialize; use serde::Serialize;
use serde_json::json;
use std::{ use std::{
env, env,
io::Write, io::Write,
@ -19,7 +14,7 @@ use std::{
}; };
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
use util::http::HttpClient; use util::http::HttpClient;
use util::{channel::ReleaseChannel, post_inc, ResultExt, TryFutureExt}; use util::{channel::ReleaseChannel, TryFutureExt};
use uuid::Uuid; use uuid::Uuid;
pub struct Telemetry { pub struct Telemetry {
@ -37,23 +32,15 @@ struct TelemetryState {
os_name: &'static str, os_name: &'static str,
os_version: Option<Arc<str>>, os_version: Option<Arc<str>>,
architecture: &'static str, architecture: &'static str,
mixpanel_events_queue: Vec<MixpanelEvent>,
clickhouse_events_queue: Vec<ClickhouseEventWrapper>, clickhouse_events_queue: Vec<ClickhouseEventWrapper>,
next_mixpanel_event_id: usize,
flush_mixpanel_events_task: Option<Task<()>>,
flush_clickhouse_events_task: Option<Task<()>>, flush_clickhouse_events_task: Option<Task<()>>,
log_file: Option<NamedTempFile>, log_file: Option<NamedTempFile>,
is_staff: Option<bool>, is_staff: Option<bool>,
} }
const MIXPANEL_EVENTS_URL: &'static str = "https://api.mixpanel.com/track";
const MIXPANEL_ENGAGE_URL: &'static str = "https://api.mixpanel.com/engage#profile-set";
const CLICKHOUSE_EVENTS_URL_PATH: &'static str = "/api/events"; const CLICKHOUSE_EVENTS_URL_PATH: &'static str = "/api/events";
lazy_static! { lazy_static! {
static ref MIXPANEL_TOKEN: Option<String> = std::env::var("ZED_MIXPANEL_TOKEN")
.ok()
.or_else(|| option_env!("ZED_MIXPANEL_TOKEN").map(|key| key.to_string()));
static ref CLICKHOUSE_EVENTS_URL: String = static ref CLICKHOUSE_EVENTS_URL: String =
format!("{}{}", *ZED_SERVER_URL, CLICKHOUSE_EVENTS_URL_PATH); format!("{}{}", *ZED_SERVER_URL, CLICKHOUSE_EVENTS_URL_PATH);
} }
@ -95,47 +82,6 @@ pub enum ClickhouseEvent {
}, },
} }
#[derive(Serialize, Debug)]
struct MixpanelEvent {
event: String,
properties: MixpanelEventProperties,
}
#[derive(Serialize, Debug)]
struct MixpanelEventProperties {
// Mixpanel required fields
#[serde(skip_serializing_if = "str::is_empty")]
token: &'static str,
time: u128,
#[serde(rename = "distinct_id")]
installation_id: Option<Arc<str>>,
#[serde(rename = "$insert_id")]
insert_id: usize,
// 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,
}
#[derive(Serialize)]
struct MixpanelEngageRequest {
#[serde(rename = "$token")]
token: &'static str,
#[serde(rename = "$distinct_id")]
installation_id: Arc<str>,
#[serde(rename = "$set")]
set: Value,
}
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
const MAX_QUEUE_LEN: usize = 1; const MAX_QUEUE_LEN: usize = 1;
@ -168,29 +114,13 @@ impl Telemetry {
release_channel, release_channel,
installation_id: None, installation_id: None,
metrics_id: None, metrics_id: None,
mixpanel_events_queue: Default::default(),
clickhouse_events_queue: Default::default(), clickhouse_events_queue: Default::default(),
flush_mixpanel_events_task: Default::default(),
flush_clickhouse_events_task: Default::default(), flush_clickhouse_events_task: Default::default(),
next_mixpanel_event_id: 0,
log_file: None, log_file: None,
is_staff: None, is_staff: None,
}), }),
}); });
if MIXPANEL_TOKEN.is_some() {
this.executor
.spawn({
let this = this.clone();
async move {
if let Some(tempfile) = NamedTempFile::new().log_err() {
this.state.lock().log_file = Some(tempfile);
}
}
})
.detach();
}
this this
} }
@ -218,20 +148,9 @@ impl Telemetry {
let mut state = this.state.lock(); let mut state = this.state.lock();
state.installation_id = Some(installation_id.clone()); state.installation_id = Some(installation_id.clone());
for event in &mut state.mixpanel_events_queue {
event
.properties
.installation_id
.get_or_insert_with(|| installation_id.clone());
}
let has_mixpanel_events = !state.mixpanel_events_queue.is_empty();
let has_clickhouse_events = !state.clickhouse_events_queue.is_empty(); let has_clickhouse_events = !state.clickhouse_events_queue.is_empty();
drop(state);
if has_mixpanel_events { drop(state);
this.flush_mixpanel_events();
}
if has_clickhouse_events { if has_clickhouse_events {
this.flush_clickhouse_events(); this.flush_clickhouse_events();
@ -256,37 +175,11 @@ impl Telemetry {
return; return;
} }
let this = self.clone();
let mut state = self.state.lock(); let mut state = self.state.lock();
let installation_id = state.installation_id.clone();
let metrics_id: Option<Arc<str>> = metrics_id.map(|id| id.into()); let metrics_id: Option<Arc<str>> = metrics_id.map(|id| id.into());
state.metrics_id = metrics_id.clone(); state.metrics_id = metrics_id.clone();
state.is_staff = Some(is_staff); state.is_staff = Some(is_staff);
drop(state); drop(state);
if let Some((token, installation_id)) = MIXPANEL_TOKEN.as_ref().zip(installation_id) {
self.executor
.spawn(
async move {
let json_bytes = serde_json::to_vec(&[MixpanelEngageRequest {
token,
installation_id,
set: json!({
"Staff": is_staff,
"ID": metrics_id,
"App": true
}),
}])?;
this.http_client
.post_json(MIXPANEL_ENGAGE_URL, json_bytes.into())
.await?;
anyhow::Ok(())
}
.log_err(),
)
.detach();
}
} }
pub fn report_clickhouse_event( pub fn report_clickhouse_event(
@ -310,7 +203,7 @@ impl Telemetry {
}); });
if state.installation_id.is_some() { if state.installation_id.is_some() {
if state.mixpanel_events_queue.len() >= MAX_QUEUE_LEN { if state.clickhouse_events_queue.len() >= MAX_QUEUE_LEN {
drop(state); drop(state);
self.flush_clickhouse_events(); self.flush_clickhouse_events();
} else { } else {
@ -324,55 +217,6 @@ impl Telemetry {
} }
} }
pub fn report_mixpanel_event(
self: &Arc<Self>,
kind: &str,
properties: Value,
telemetry_settings: TelemetrySettings,
) {
if !telemetry_settings.metrics {
return;
}
let mut state = self.state.lock();
let event = MixpanelEvent {
event: kind.into(),
properties: MixpanelEventProperties {
token: "",
time: SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis(),
installation_id: state.installation_id.clone(),
insert_id: post_inc(&mut state.next_mixpanel_event_id),
event_properties: if let Value::Object(properties) = properties {
Some(properties)
} else {
None
},
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(),
},
};
state.mixpanel_events_queue.push(event);
if state.installation_id.is_some() {
if state.mixpanel_events_queue.len() >= MAX_QUEUE_LEN {
drop(state);
self.flush_mixpanel_events();
} else {
let this = self.clone();
let executor = self.executor.clone();
state.flush_mixpanel_events_task = Some(self.executor.spawn(async move {
executor.timer(DEBOUNCE_INTERVAL).await;
this.flush_mixpanel_events();
}));
}
}
}
pub fn metrics_id(self: &Arc<Self>) -> Option<Arc<str>> { pub fn metrics_id(self: &Arc<Self>) -> Option<Arc<str>> {
self.state.lock().metrics_id.clone() self.state.lock().metrics_id.clone()
} }
@ -385,44 +229,6 @@ impl Telemetry {
self.state.lock().is_staff self.state.lock().is_staff
} }
fn flush_mixpanel_events(self: &Arc<Self>) {
let mut state = self.state.lock();
let mut events = mem::take(&mut state.mixpanel_events_queue);
state.flush_mixpanel_events_task.take();
drop(state);
if let Some(token) = MIXPANEL_TOKEN.as_ref() {
let this = self.clone();
self.executor
.spawn(
async move {
let mut json_bytes = Vec::new();
if let Some(file) = &mut this.state.lock().log_file {
let file = file.as_file_mut();
for event in &mut events {
json_bytes.clear();
serde_json::to_writer(&mut json_bytes, event)?;
file.write_all(&json_bytes)?;
file.write(b"\n")?;
event.properties.token = token;
}
}
json_bytes.clear();
serde_json::to_writer(&mut json_bytes, &events)?;
this.http_client
.post_json(MIXPANEL_EVENTS_URL, json_bytes.into())
.await?;
anyhow::Ok(())
}
.log_err(),
)
.detach();
}
}
fn flush_clickhouse_events(self: &Arc<Self>) { fn flush_clickhouse_events(self: &Arc<Self>) {
let mut state = self.state.lock(); let mut state = self.state.lock();
let mut events = mem::take(&mut state.clickhouse_events_queue); let mut events = mem::take(&mut state.clickhouse_events_queue);

View file

@ -1,9 +1,6 @@
fn main() { fn main() {
println!("cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET=10.15.7"); println!("cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET=10.15.7");
if let Ok(value) = std::env::var("ZED_MIXPANEL_TOKEN") {
println!("cargo:rustc-env=ZED_MIXPANEL_TOKEN={value}");
}
if let Ok(value) = std::env::var("ZED_PREVIEW_CHANNEL") { if let Ok(value) = std::env::var("ZED_PREVIEW_CHANNEL") {
println!("cargo:rustc-env=ZED_PREVIEW_CHANNEL={value}"); println!("cargo:rustc-env=ZED_PREVIEW_CHANNEL={value}");
} }

View file

@ -171,11 +171,6 @@ fn main() {
.detach(); .detach();
client.telemetry().start(); client.telemetry().start();
client.telemetry().report_mixpanel_event(
"start app",
Default::default(),
*settings::get::<TelemetrySettings>(cx),
);
let app_state = Arc::new(AppState { let app_state = Arc::new(AppState {
languages, languages,

View file

@ -1,30 +0,0 @@
import datetime
import sys
import requests
def main():
version = sys.argv[1]
version = version.removeprefix("v")
project_id = sys.argv[2]
account_username = sys.argv[3]
account_secret = sys.argv[4]
current_datetime = datetime.datetime.now(datetime.timezone.utc)
current_datetime = current_datetime.strftime("%Y-%m-%d %H:%M:%S")
url = f"https://mixpanel.com/api/app/projects/{project_id}/annotations"
payload = {
"date": current_datetime,
"description": version
}
response = requests.post(
url,
auth=(account_username, account_secret),
json=payload
)
if __name__ == "__main__":
main()

View file

@ -1 +0,0 @@
requests==2.28.1