Skip to content

Commit 856d963

Browse files
JosephTLyonsrgbkrk
andauthored
Add repl events (#15259)
Release Notes: - N/A --------- Co-authored-by: Kyle Kelley <rgbkrk@gmail.com>
1 parent 745d2e4 commit 856d963

File tree

11 files changed

+188
-35
lines changed

11 files changed

+188
-35
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/client/src/telemetry.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use sysinfo::{CpuRefreshKind, Pid, ProcessRefreshKind, RefreshKind, System};
1818
use telemetry_events::{
1919
ActionEvent, AppEvent, AssistantEvent, AssistantKind, CallEvent, CpuEvent, EditEvent,
2020
EditorEvent, Event, EventRequestBody, EventWrapper, ExtensionEvent, InlineCompletionEvent,
21-
MemoryEvent, SettingEvent,
21+
MemoryEvent, ReplEvent, SettingEvent,
2222
};
2323
use tempfile::NamedTempFile;
2424
#[cfg(not(debug_assertions))]
@@ -531,6 +531,21 @@ impl Telemetry {
531531
}
532532
}
533533

534+
pub fn report_repl_event(
535+
self: &Arc<Self>,
536+
kernel_language: String,
537+
kernel_status: String,
538+
repl_session_id: String,
539+
) {
540+
let event = Event::Repl(ReplEvent {
541+
kernel_language,
542+
kernel_status,
543+
repl_session_id,
544+
});
545+
546+
self.report_event(event)
547+
}
548+
534549
fn report_event(self: &Arc<Self>, event: Event) {
535550
let mut state = self.state.lock();
536551

crates/collab/src/api/events.rs

Lines changed: 84 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use sha2::{Digest, Sha256};
1616
use std::sync::{Arc, OnceLock};
1717
use telemetry_events::{
1818
ActionEvent, AppEvent, AssistantEvent, CallEvent, CpuEvent, EditEvent, EditorEvent, Event,
19-
EventRequestBody, EventWrapper, ExtensionEvent, InlineCompletionEvent, MemoryEvent,
19+
EventRequestBody, EventWrapper, ExtensionEvent, InlineCompletionEvent, MemoryEvent, ReplEvent,
2020
SettingEvent,
2121
};
2222
use uuid::Uuid;
@@ -518,6 +518,13 @@ pub async fn post_events(
518518
checksum_matched,
519519
))
520520
}
521+
Event::Repl(event) => to_upload.repl_events.push(ReplEventRow::from_event(
522+
event.clone(),
523+
&wrapper,
524+
&request_body,
525+
first_event_at,
526+
checksum_matched,
527+
)),
521528
}
522529
}
523530

@@ -542,6 +549,7 @@ struct ToUpload {
542549
extension_events: Vec<ExtensionEventRow>,
543550
edit_events: Vec<EditEventRow>,
544551
action_events: Vec<ActionEventRow>,
552+
repl_events: Vec<ReplEventRow>,
545553
}
546554

547555
impl ToUpload {
@@ -617,6 +625,11 @@ impl ToUpload {
617625
.await
618626
.with_context(|| format!("failed to upload to table '{ACTION_EVENTS_TABLE}'"))?;
619627

628+
const REPL_EVENTS_TABLE: &str = "repl_events";
629+
Self::upload_to_table(REPL_EVENTS_TABLE, &self.repl_events, clickhouse_client)
630+
.await
631+
.with_context(|| format!("failed to upload to table '{REPL_EVENTS_TABLE}'"))?;
632+
620633
Ok(())
621634
}
622635

@@ -625,22 +638,24 @@ impl ToUpload {
625638
rows: &[T],
626639
clickhouse_client: &clickhouse::Client,
627640
) -> anyhow::Result<()> {
628-
if !rows.is_empty() {
629-
let mut insert = clickhouse_client.insert(table)?;
630-
631-
for event in rows {
632-
insert.write(event).await?;
633-
}
641+
if rows.is_empty() {
642+
return Ok(());
643+
}
634644

635-
insert.end().await?;
645+
let mut insert = clickhouse_client.insert(table)?;
636646

637-
let event_count = rows.len();
638-
log::info!(
639-
"wrote {event_count} {event_specifier} to '{table}'",
640-
event_specifier = if event_count == 1 { "event" } else { "events" }
641-
);
647+
for event in rows {
648+
insert.write(event).await?;
642649
}
643650

651+
insert.end().await?;
652+
653+
let event_count = rows.len();
654+
log::info!(
655+
"wrote {event_count} {event_specifier} to '{table}'",
656+
event_specifier = if event_count == 1 { "event" } else { "events" }
657+
);
658+
644659
Ok(())
645660
}
646661
}
@@ -1189,6 +1204,62 @@ impl ExtensionEventRow {
11891204
}
11901205
}
11911206

1207+
#[derive(Serialize, Debug, clickhouse::Row)]
1208+
pub struct ReplEventRow {
1209+
// AppInfoBase
1210+
app_version: String,
1211+
major: Option<i32>,
1212+
minor: Option<i32>,
1213+
patch: Option<i32>,
1214+
checksum_matched: bool,
1215+
release_channel: String,
1216+
os_name: String,
1217+
os_version: String,
1218+
1219+
// ClientEventBase
1220+
installation_id: Option<String>,
1221+
session_id: Option<String>,
1222+
is_staff: Option<bool>,
1223+
time: i64,
1224+
1225+
// ReplEventRow
1226+
kernel_language: String,
1227+
kernel_status: String,
1228+
repl_session_id: String,
1229+
}
1230+
1231+
impl ReplEventRow {
1232+
fn from_event(
1233+
event: ReplEvent,
1234+
wrapper: &EventWrapper,
1235+
body: &EventRequestBody,
1236+
first_event_at: chrono::DateTime<chrono::Utc>,
1237+
checksum_matched: bool,
1238+
) -> Self {
1239+
let semver = body.semver();
1240+
let time =
1241+
first_event_at + chrono::Duration::milliseconds(wrapper.milliseconds_since_first_event);
1242+
1243+
Self {
1244+
app_version: body.app_version.clone(),
1245+
major: semver.map(|v| v.major() as i32),
1246+
minor: semver.map(|v| v.minor() as i32),
1247+
patch: semver.map(|v| v.patch() as i32),
1248+
checksum_matched,
1249+
release_channel: body.release_channel.clone().unwrap_or_default(),
1250+
os_name: body.os_name.clone(),
1251+
os_version: body.os_version.clone().unwrap_or_default(),
1252+
installation_id: body.installation_id.clone(),
1253+
session_id: body.session_id.clone(),
1254+
is_staff: body.is_staff,
1255+
time: time.timestamp_millis(),
1256+
kernel_language: event.kernel_language,
1257+
kernel_status: event.kernel_status,
1258+
repl_session_id: event.repl_session_id,
1259+
}
1260+
}
1261+
}
1262+
11921263
#[derive(Serialize, Debug, clickhouse::Row)]
11931264
pub struct EditEventRow {
11941265
// AppInfoBase

crates/repl/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ alacritty_terminal.workspace = true
1717
anyhow.workspace = true
1818
async-dispatcher.workspace = true
1919
base64.workspace = true
20+
client.workspace = true
2021
collections.workspace = true
2122
command_palette_hooks.workspace = true
2223
editor.workspace = true

crates/repl/src/repl.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ pub use crate::repl_sessions_ui::{
2424
};
2525
use crate::repl_store::ReplStore;
2626
pub use crate::session::Session;
27+
use client::telemetry::Telemetry;
2728

28-
pub fn init(fs: Arc<dyn Fs>, cx: &mut AppContext) {
29+
pub fn init(fs: Arc<dyn Fs>, telemetry: Arc<Telemetry>, cx: &mut AppContext) {
2930
set_dispatcher(zed_dispatcher(cx));
3031
JupyterSettings::register(cx);
3132
::editor::init_settings(cx);
3233
repl_sessions_ui::init(cx);
33-
ReplStore::init(fs, cx);
34+
ReplStore::init(fs, telemetry, cx);
3435
}
3536

3637
fn zed_dispatcher(cx: &mut AppContext) -> impl Dispatcher {

crates/repl/src/repl_editor.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,15 @@ pub fn run(editor: WeakView<Editor>, cx: &mut WindowContext) -> Result<()> {
4242
})?;
4343

4444
let fs = store.read(cx).fs().clone();
45+
let telemetry = store.read(cx).telemetry().clone();
46+
4547
let session = if let Some(session) = store.read(cx).get_session(editor.entity_id()).cloned()
4648
{
4749
session
4850
} else {
4951
let weak_editor = editor.downgrade();
50-
let session = cx.new_view(|cx| Session::new(weak_editor, fs, kernel_specification, cx));
52+
let session = cx
53+
.new_view(|cx| Session::new(weak_editor, fs, telemetry, kernel_specification, cx));
5154

5255
editor.update(cx, |_editor, cx| {
5356
cx.notify();

crates/repl/src/repl_store.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::sync::Arc;
22

33
use anyhow::Result;
4+
use client::telemetry::Telemetry;
45
use collections::HashMap;
56
use command_palette_hooks::CommandPaletteFilter;
67
use gpui::{
@@ -22,14 +23,15 @@ pub struct ReplStore {
2223
enabled: bool,
2324
sessions: HashMap<EntityId, View<Session>>,
2425
kernel_specifications: Vec<KernelSpecification>,
26+
telemetry: Arc<Telemetry>,
2527
_subscriptions: Vec<Subscription>,
2628
}
2729

2830
impl ReplStore {
2931
const NAMESPACE: &'static str = "repl";
3032

31-
pub(crate) fn init(fs: Arc<dyn Fs>, cx: &mut AppContext) {
32-
let store = cx.new_model(move |cx| Self::new(fs, cx));
33+
pub(crate) fn init(fs: Arc<dyn Fs>, telemetry: Arc<Telemetry>, cx: &mut AppContext) {
34+
let store = cx.new_model(move |cx| Self::new(fs, telemetry, cx));
3335

3436
store
3537
.update(cx, |store, cx| store.refresh_kernelspecs(cx))
@@ -42,13 +44,14 @@ impl ReplStore {
4244
cx.global::<GlobalReplStore>().0.clone()
4345
}
4446

45-
pub fn new(fs: Arc<dyn Fs>, cx: &mut ModelContext<Self>) -> Self {
47+
pub fn new(fs: Arc<dyn Fs>, telemetry: Arc<Telemetry>, cx: &mut ModelContext<Self>) -> Self {
4648
let subscriptions = vec![cx.observe_global::<SettingsStore>(move |this, cx| {
4749
this.set_enabled(JupyterSettings::enabled(cx), cx);
4850
})];
4951

5052
let this = Self {
5153
fs,
54+
telemetry,
5255
enabled: JupyterSettings::enabled(cx),
5356
sessions: HashMap::default(),
5457
kernel_specifications: Vec::new(),
@@ -62,6 +65,10 @@ impl ReplStore {
6265
&self.fs
6366
}
6467

68+
pub fn telemetry(&self) -> &Arc<Telemetry> {
69+
&self.telemetry
70+
}
71+
6572
pub fn is_enabled(&self) -> bool {
6673
self.enabled
6774
}

0 commit comments

Comments
 (0)