telemetry: Reduce the amount of telemetry events fired (#36060)
1. Extension loaded events are now condensed into a single event with a Vec of (extension_id, extension_version) called id_and_versions. 2. Editor Saved & AutoSaved are merged into a singular event with a type field that is either "manual" or "autosave”. 3. Editor Edited event will only fire once every 10 minutes now. 4. Editor Closed event is fired when an editor item (tab) is removed from a pane cc: @katie-z-geer Release Notes: - N/A --------- Co-authored-by: Marshall Bowers <git@maxdeviant.com>
This commit is contained in:
parent
628b1058be
commit
255bb0a3f8
6 changed files with 110 additions and 43 deletions
|
@ -340,22 +340,35 @@ impl Telemetry {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn log_edit_event(self: &Arc<Self>, environment: &'static str, is_via_ssh: bool) {
|
pub fn log_edit_event(self: &Arc<Self>, environment: &'static str, is_via_ssh: bool) {
|
||||||
|
static LAST_EVENT_TIME: Mutex<Option<Instant>> = Mutex::new(None);
|
||||||
|
|
||||||
let mut state = self.state.lock();
|
let mut state = self.state.lock();
|
||||||
let period_data = state.event_coalescer.log_event(environment);
|
let period_data = state.event_coalescer.log_event(environment);
|
||||||
drop(state);
|
drop(state);
|
||||||
|
|
||||||
if let Some((start, end, environment)) = period_data {
|
if let Some(mut last_event) = LAST_EVENT_TIME.try_lock() {
|
||||||
let duration = end
|
let current_time = std::time::Instant::now();
|
||||||
.saturating_duration_since(start)
|
let last_time = last_event.get_or_insert(current_time);
|
||||||
.min(Duration::from_secs(60 * 60 * 24))
|
|
||||||
.as_millis() as i64;
|
|
||||||
|
|
||||||
telemetry::event!(
|
if current_time.duration_since(*last_time) > Duration::from_secs(60 * 10) {
|
||||||
"Editor Edited",
|
*last_time = current_time;
|
||||||
duration = duration,
|
} else {
|
||||||
environment = environment,
|
return;
|
||||||
is_via_ssh = is_via_ssh
|
}
|
||||||
);
|
|
||||||
|
if let Some((start, end, environment)) = period_data {
|
||||||
|
let duration = end
|
||||||
|
.saturating_duration_since(start)
|
||||||
|
.min(Duration::from_secs(60 * 60 * 24))
|
||||||
|
.as_millis() as i64;
|
||||||
|
|
||||||
|
telemetry::event!(
|
||||||
|
"Editor Edited",
|
||||||
|
duration = duration,
|
||||||
|
environment = environment,
|
||||||
|
is_via_ssh = is_via_ssh
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,6 +250,24 @@ pub type RenderDiffHunkControlsFn = Arc<
|
||||||
) -> AnyElement,
|
) -> AnyElement,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
enum ReportEditorEvent {
|
||||||
|
Saved { auto_saved: bool },
|
||||||
|
EditorOpened,
|
||||||
|
ZetaTosClicked,
|
||||||
|
Closed,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ReportEditorEvent {
|
||||||
|
pub fn event_type(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Saved { .. } => "Editor Saved",
|
||||||
|
Self::EditorOpened => "Editor Opened",
|
||||||
|
Self::ZetaTosClicked => "Edit Prediction Provider ToS Clicked",
|
||||||
|
Self::Closed => "Editor Closed",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct InlineValueCache {
|
struct InlineValueCache {
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
inlays: Vec<InlayId>,
|
inlays: Vec<InlayId>,
|
||||||
|
@ -2325,7 +2343,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
if editor.mode.is_full() {
|
if editor.mode.is_full() {
|
||||||
editor.report_editor_event("Editor Opened", None, cx);
|
editor.report_editor_event(ReportEditorEvent::EditorOpened, None, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
editor
|
editor
|
||||||
|
@ -9124,7 +9142,7 @@ impl Editor {
|
||||||
.on_mouse_down(MouseButton::Left, |_, window, _| window.prevent_default())
|
.on_mouse_down(MouseButton::Left, |_, window, _| window.prevent_default())
|
||||||
.on_click(cx.listener(|this, _event, window, cx| {
|
.on_click(cx.listener(|this, _event, window, cx| {
|
||||||
cx.stop_propagation();
|
cx.stop_propagation();
|
||||||
this.report_editor_event("Edit Prediction Provider ToS Clicked", None, cx);
|
this.report_editor_event(ReportEditorEvent::ZetaTosClicked, None, cx);
|
||||||
window.dispatch_action(
|
window.dispatch_action(
|
||||||
zed_actions::OpenZedPredictOnboarding.boxed_clone(),
|
zed_actions::OpenZedPredictOnboarding.boxed_clone(),
|
||||||
cx,
|
cx,
|
||||||
|
@ -20547,7 +20565,7 @@ impl Editor {
|
||||||
|
|
||||||
fn report_editor_event(
|
fn report_editor_event(
|
||||||
&self,
|
&self,
|
||||||
event_type: &'static str,
|
reported_event: ReportEditorEvent,
|
||||||
file_extension: Option<String>,
|
file_extension: Option<String>,
|
||||||
cx: &App,
|
cx: &App,
|
||||||
) {
|
) {
|
||||||
|
@ -20581,15 +20599,30 @@ impl Editor {
|
||||||
.show_edit_predictions;
|
.show_edit_predictions;
|
||||||
|
|
||||||
let project = project.read(cx);
|
let project = project.read(cx);
|
||||||
telemetry::event!(
|
let event_type = reported_event.event_type();
|
||||||
event_type,
|
|
||||||
file_extension,
|
if let ReportEditorEvent::Saved { auto_saved } = reported_event {
|
||||||
vim_mode,
|
telemetry::event!(
|
||||||
copilot_enabled,
|
event_type,
|
||||||
copilot_enabled_for_language,
|
type = if auto_saved {"autosave"} else {"manual"},
|
||||||
edit_predictions_provider,
|
file_extension,
|
||||||
is_via_ssh = project.is_via_ssh(),
|
vim_mode,
|
||||||
);
|
copilot_enabled,
|
||||||
|
copilot_enabled_for_language,
|
||||||
|
edit_predictions_provider,
|
||||||
|
is_via_ssh = project.is_via_ssh(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
telemetry::event!(
|
||||||
|
event_type,
|
||||||
|
file_extension,
|
||||||
|
vim_mode,
|
||||||
|
copilot_enabled,
|
||||||
|
copilot_enabled_for_language,
|
||||||
|
edit_predictions_provider,
|
||||||
|
is_via_ssh = project.is_via_ssh(),
|
||||||
|
);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Copy the highlighted chunks to the clipboard as JSON. The format is an array of lines,
|
/// Copy the highlighted chunks to the clipboard as JSON. The format is an array of lines,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
Anchor, Autoscroll, Editor, EditorEvent, EditorSettings, ExcerptId, ExcerptRange, FormatTarget,
|
Anchor, Autoscroll, Editor, EditorEvent, EditorSettings, ExcerptId, ExcerptRange, FormatTarget,
|
||||||
MultiBuffer, MultiBufferSnapshot, NavigationData, SearchWithinRange, SelectionEffects,
|
MultiBuffer, MultiBufferSnapshot, NavigationData, ReportEditorEvent, SearchWithinRange,
|
||||||
ToPoint as _,
|
SelectionEffects, ToPoint as _,
|
||||||
display_map::HighlightKey,
|
display_map::HighlightKey,
|
||||||
editor_settings::SeedQuerySetting,
|
editor_settings::SeedQuerySetting,
|
||||||
persistence::{DB, SerializedEditor},
|
persistence::{DB, SerializedEditor},
|
||||||
|
@ -776,6 +776,10 @@ impl Item for Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_removed(&self, cx: &App) {
|
||||||
|
self.report_editor_event(ReportEditorEvent::Closed, None, cx);
|
||||||
|
}
|
||||||
|
|
||||||
fn deactivated(&mut self, _: &mut Window, cx: &mut Context<Self>) {
|
fn deactivated(&mut self, _: &mut Window, cx: &mut Context<Self>) {
|
||||||
let selection = self.selections.newest_anchor();
|
let selection = self.selections.newest_anchor();
|
||||||
self.push_to_nav_history(selection.head(), None, true, false, cx);
|
self.push_to_nav_history(selection.head(), None, true, false, cx);
|
||||||
|
@ -815,9 +819,9 @@ impl Item for Editor {
|
||||||
) -> Task<Result<()>> {
|
) -> Task<Result<()>> {
|
||||||
// Add meta data tracking # of auto saves
|
// Add meta data tracking # of auto saves
|
||||||
if options.autosave {
|
if options.autosave {
|
||||||
self.report_editor_event("Editor Autosaved", None, cx);
|
self.report_editor_event(ReportEditorEvent::Saved { auto_saved: true }, None, cx);
|
||||||
} else {
|
} else {
|
||||||
self.report_editor_event("Editor Saved", None, cx);
|
self.report_editor_event(ReportEditorEvent::Saved { auto_saved: false }, None, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
let buffers = self.buffer().clone().read(cx).all_buffers();
|
let buffers = self.buffer().clone().read(cx).all_buffers();
|
||||||
|
@ -896,7 +900,11 @@ impl Item for Editor {
|
||||||
.path
|
.path
|
||||||
.extension()
|
.extension()
|
||||||
.map(|a| a.to_string_lossy().to_string());
|
.map(|a| a.to_string_lossy().to_string());
|
||||||
self.report_editor_event("Editor Saved", file_extension, cx);
|
self.report_editor_event(
|
||||||
|
ReportEditorEvent::Saved { auto_saved: false },
|
||||||
|
file_extension,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
|
||||||
project.update(cx, |project, cx| project.save_buffer_as(buffer, path, cx))
|
project.update(cx, |project, cx| project.save_buffer_as(buffer, path, cx))
|
||||||
}
|
}
|
||||||
|
@ -997,12 +1005,16 @@ impl Item for Editor {
|
||||||
) {
|
) {
|
||||||
self.workspace = Some((workspace.weak_handle(), workspace.database_id()));
|
self.workspace = Some((workspace.weak_handle(), workspace.database_id()));
|
||||||
if let Some(workspace) = &workspace.weak_handle().upgrade() {
|
if let Some(workspace) = &workspace.weak_handle().upgrade() {
|
||||||
cx.subscribe(&workspace, |editor, _, event: &workspace::Event, _cx| {
|
cx.subscribe(
|
||||||
if matches!(event, workspace::Event::ModalOpened) {
|
&workspace,
|
||||||
editor.mouse_context_menu.take();
|
|editor, _, event: &workspace::Event, _cx| match event {
|
||||||
editor.inline_blame_popover.take();
|
workspace::Event::ModalOpened => {
|
||||||
}
|
editor.mouse_context_menu.take();
|
||||||
})
|
editor.inline_blame_popover.take();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
)
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1118,15 +1118,17 @@ impl ExtensionStore {
|
||||||
extensions_to_unload.len() - reload_count
|
extensions_to_unload.len() - reload_count
|
||||||
);
|
);
|
||||||
|
|
||||||
for extension_id in &extensions_to_load {
|
let extension_ids = extensions_to_load
|
||||||
if let Some(extension) = new_index.extensions.get(extension_id) {
|
.iter()
|
||||||
telemetry::event!(
|
.filter_map(|id| {
|
||||||
"Extension Loaded",
|
Some((
|
||||||
extension_id,
|
id.clone(),
|
||||||
version = extension.manifest.version
|
new_index.extensions.get(id)?.manifest.version.clone(),
|
||||||
);
|
))
|
||||||
}
|
})
|
||||||
}
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
telemetry::event!("Extensions Loaded", id_and_versions = extension_ids);
|
||||||
|
|
||||||
let themes_to_remove = old_index
|
let themes_to_remove = old_index
|
||||||
.themes
|
.themes
|
||||||
|
|
|
@ -293,6 +293,7 @@ pub trait Item: Focusable + EventEmitter<Self::Event> + Render + Sized {
|
||||||
|
|
||||||
fn deactivated(&mut self, _window: &mut Window, _: &mut Context<Self>) {}
|
fn deactivated(&mut self, _window: &mut Window, _: &mut Context<Self>) {}
|
||||||
fn discarded(&self, _project: Entity<Project>, _window: &mut Window, _cx: &mut Context<Self>) {}
|
fn discarded(&self, _project: Entity<Project>, _window: &mut Window, _cx: &mut Context<Self>) {}
|
||||||
|
fn on_removed(&self, _cx: &App) {}
|
||||||
fn workspace_deactivated(&mut self, _window: &mut Window, _: &mut Context<Self>) {}
|
fn workspace_deactivated(&mut self, _window: &mut Window, _: &mut Context<Self>) {}
|
||||||
fn navigate(&mut self, _: Box<dyn Any>, _window: &mut Window, _: &mut Context<Self>) -> bool {
|
fn navigate(&mut self, _: Box<dyn Any>, _window: &mut Window, _: &mut Context<Self>) -> bool {
|
||||||
false
|
false
|
||||||
|
@ -532,6 +533,7 @@ pub trait ItemHandle: 'static + Send {
|
||||||
);
|
);
|
||||||
fn deactivated(&self, window: &mut Window, cx: &mut App);
|
fn deactivated(&self, window: &mut Window, cx: &mut App);
|
||||||
fn discarded(&self, project: Entity<Project>, window: &mut Window, cx: &mut App);
|
fn discarded(&self, project: Entity<Project>, window: &mut Window, cx: &mut App);
|
||||||
|
fn on_removed(&self, cx: &App);
|
||||||
fn workspace_deactivated(&self, window: &mut Window, cx: &mut App);
|
fn workspace_deactivated(&self, window: &mut Window, cx: &mut App);
|
||||||
fn navigate(&self, data: Box<dyn Any>, window: &mut Window, cx: &mut App) -> bool;
|
fn navigate(&self, data: Box<dyn Any>, window: &mut Window, cx: &mut App) -> bool;
|
||||||
fn item_id(&self) -> EntityId;
|
fn item_id(&self) -> EntityId;
|
||||||
|
@ -968,6 +970,10 @@ impl<T: Item> ItemHandle for Entity<T> {
|
||||||
self.update(cx, |this, cx| this.deactivated(window, cx));
|
self.update(cx, |this, cx| this.deactivated(window, cx));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_removed(&self, cx: &App) {
|
||||||
|
self.read(cx).on_removed(cx);
|
||||||
|
}
|
||||||
|
|
||||||
fn workspace_deactivated(&self, window: &mut Window, cx: &mut App) {
|
fn workspace_deactivated(&self, window: &mut Window, cx: &mut App) {
|
||||||
self.update(cx, |this, cx| this.workspace_deactivated(window, cx));
|
self.update(cx, |this, cx| this.workspace_deactivated(window, cx));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1829,6 +1829,7 @@ impl Pane {
|
||||||
let mode = self.nav_history.mode();
|
let mode = self.nav_history.mode();
|
||||||
self.nav_history.set_mode(NavigationMode::ClosingItem);
|
self.nav_history.set_mode(NavigationMode::ClosingItem);
|
||||||
item.deactivated(window, cx);
|
item.deactivated(window, cx);
|
||||||
|
item.on_removed(cx);
|
||||||
self.nav_history.set_mode(mode);
|
self.nav_history.set_mode(mode);
|
||||||
|
|
||||||
if self.is_active_preview_item(item.item_id()) {
|
if self.is_active_preview_item(item.item_id()) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue