Time from the very start till popup disposal for IJPL-55674 Performance metrics: Search Everywhere opening

GitOrigin-RevId: b1aa6bdbc21c8979b2e126438aa5b0525f3476bd
This commit is contained in:
Elena Shaverdova
2024-07-31 16:07:35 +02:00
committed by intellij-monorepo-bot
parent 7d941d5ef5
commit 3a2a6caf80
12 changed files with 107 additions and 16 deletions

View File

@@ -13,6 +13,7 @@ import com.intellij.ide.actions.searcheverywhere.*
import com.intellij.ide.actions.searcheverywhere.SETabSwitcherListener.Companion.SE_TAB_TOPIC
import com.intellij.ide.actions.searcheverywhere.SETabSwitcherListener.SETabSwitchedEvent
import com.intellij.ide.actions.searcheverywhere.footer.createTextExtendedInfo
import com.intellij.ide.actions.searcheverywhere.statistics.SearchFieldStatisticsCollector.wrapEventWithActionStartData
import com.intellij.ide.util.scopeChooser.ScopeDescriptor
import com.intellij.ide.util.scopeChooser.ScopeOption
import com.intellij.ide.util.scopeChooser.ScopeService
@@ -287,7 +288,7 @@ class TextSearchContributor(val event: AnActionEvent) : WeightedSearchEverywhere
}
override fun actionPerformed(e: AnActionEvent) {
showInSearchEverywherePopup(ID, e, true, true)
showInSearchEverywherePopup(ID, wrapEventWithActionStartData(e), true, true)
}
}
}

View File

@@ -3,6 +3,7 @@ package com.intellij.ide.actions;
import com.intellij.ide.DataManager;
import com.intellij.ide.actions.searcheverywhere.ActionSearchEverywhereContributor;
import com.intellij.ide.actions.searcheverywhere.statistics.SearchFieldStatisticsCollector;
import com.intellij.ide.lightEdit.LightEditCompatible;
import com.intellij.ide.ui.search.OptionDescription;
import com.intellij.ide.util.gotoByName.GotoActionModel;
@@ -23,6 +24,7 @@ import java.awt.event.InputEvent;
public class GotoActionAction extends SearchEverywhereBaseAction implements DumbAware, LightEditCompatible {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
e = SearchFieldStatisticsCollector.wrapEventWithActionStartData(e);
String tabID = ActionSearchEverywhereContributor.class.getSimpleName();
showInSearchEverywherePopup(tabID, e, false, true);
}

View File

@@ -3,6 +3,7 @@ package com.intellij.ide.actions;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.actions.searcheverywhere.ClassSearchEverywhereContributor;
import com.intellij.ide.actions.searcheverywhere.statistics.SearchFieldStatisticsCollector;
import com.intellij.ide.util.gotoByName.GotoClassModel2;
import com.intellij.navigation.ChooseByNameRegistry;
import com.intellij.openapi.actionSystem.*;
@@ -29,6 +30,7 @@ public final class GotoClassAction extends SearchEverywhereBaseAction implements
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
e = SearchFieldStatisticsCollector.wrapEventWithActionStartData(e);
Project project = e.getProject();
if (project == null) return;

View File

@@ -2,6 +2,7 @@
package com.intellij.ide.actions;
import com.intellij.ide.actions.searcheverywhere.FileSearchEverywhereContributor;
import com.intellij.ide.actions.searcheverywhere.statistics.SearchFieldStatisticsCollector;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.DumbAware;
import org.jetbrains.annotations.NotNull;
@@ -17,6 +18,7 @@ public class GotoFileAction extends SearchEverywhereBaseAction implements DumbAw
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
e = SearchFieldStatisticsCollector.wrapEventWithActionStartData(e);
String tabID = FileSearchEverywhereContributor.class.getSimpleName();
showInSearchEverywherePopup(tabID, e, true, true);
}

View File

@@ -2,6 +2,7 @@
package com.intellij.ide.actions;
import com.intellij.ide.actions.searcheverywhere.SymbolSearchEverywhereContributor;
import com.intellij.ide.actions.searcheverywhere.statistics.SearchFieldStatisticsCollector;
import com.intellij.navigation.ChooseByNameRegistry;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
@@ -14,6 +15,7 @@ public final class GotoSymbolAction extends SearchEverywhereBaseAction implement
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
e = SearchFieldStatisticsCollector.wrapEventWithActionStartData(e);
Project project = e.getProject();
if (project == null) return;

View File

@@ -5,6 +5,7 @@ import com.intellij.codeWithMe.ClientId;
import com.intellij.ide.HelpTooltip;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.actions.searcheverywhere.SearchEverywhereManagerImpl;
import com.intellij.ide.actions.searcheverywhere.statistics.SearchFieldStatisticsCollector;
import com.intellij.ide.lightEdit.LightEdit;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.actionSystem.*;
@@ -105,15 +106,16 @@ public class SearchEverywhereAction extends SearchEverywhereBaseAction
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
if (LightEdit.owns(e.getProject())) return;
AnActionEvent newEvent = SearchFieldStatisticsCollector.wrapEventWithActionStartData(e);
if (LightEdit.owns(newEvent.getProject())) return;
if (AdvancedSettings.getBoolean("ide.suppress.double.click.handler") && e.getInputEvent() instanceof KeyEvent) {
if (((KeyEvent)e.getInputEvent()).getKeyCode() == KeyEvent.VK_SHIFT) {
if (AdvancedSettings.getBoolean("ide.suppress.double.click.handler") && newEvent.getInputEvent() instanceof KeyEvent) {
if (((KeyEvent)newEvent.getInputEvent()).getKeyCode() == KeyEvent.VK_SHIFT) {
return;
}
}
ReadAction.run(() -> showInSearchEverywherePopup(SearchEverywhereManagerImpl.ALL_CONTRIBUTORS_GROUP_ID, e, true, true));
ReadAction.run(() -> showInSearchEverywherePopup(SearchEverywhereManagerImpl.ALL_CONTRIBUTORS_GROUP_ID, newEvent, true, true));
}
}

View File

@@ -4,8 +4,10 @@ package com.intellij.ide.actions.searcheverywhere;
import com.intellij.codeWithMe.ClientId;
import com.intellij.ide.actions.BigPopupUI;
import com.intellij.ide.actions.OpenInRightSplitAction;
import com.intellij.ide.actions.searcheverywhere.statistics.SearchFieldStatisticsCollector;
import com.intellij.ide.lightEdit.LightEdit;
import com.intellij.ide.lightEdit.LightEditCompatible;
import com.intellij.internal.statistic.utils.StartMoment;
import com.intellij.lang.LangBundle;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
@@ -41,7 +43,7 @@ import java.util.function.Predicate;
import java.util.stream.Collector;
import static com.intellij.ide.actions.SearchEverywhereAction.SEARCH_EVERYWHERE_POPUP;
import static com.intellij.ide.actions.searcheverywhere.statistics.SearchEverywhereUsageTriggerCollector.DIALOG_CLOSED;
import static com.intellij.ide.actions.searcheverywhere.statistics.SearchEverywhereUsageTriggerCollector.*;
public final class SearchEverywhereManagerImpl implements SearchEverywhereManager {
public static final String ALL_CONTRIBUTORS_GROUP_ID = "SearchEverywhereContributor.All";
@@ -83,7 +85,7 @@ public final class SearchEverywhereManagerImpl implements SearchEverywhereManage
List<SearchEverywhereContributor<?>> contributors = createContributors(initEvent, project);
SearchEverywhereContributorValidationRule.updateContributorsMap(contributors);
SearchEverywhereSpellingCorrector spellingCorrector = SearchEverywhereSpellingCorrector.getInstance(project);
mySearchEverywhereUI = createView(myProject, contributors, spellingCorrector);
mySearchEverywhereUI = createView(myProject, contributors, spellingCorrector, SearchFieldStatisticsCollector.getStartMoment(initEvent));
contributors.forEach(c -> Disposer.register(mySearchEverywhereUI, c));
mySearchEverywhereUI.switchToTab(tabID);
@@ -269,11 +271,12 @@ public final class SearchEverywhereManagerImpl implements SearchEverywhereManage
}
private SearchEverywhereUI createView(Project project, List<SearchEverywhereContributor<?>> contributors,
@Nullable SearchEverywhereSpellingCorrector spellingCorrector) {
@Nullable SearchEverywhereSpellingCorrector spellingCorrector,
@Nullable StartMoment startMoment) {
if (LightEdit.owns(project)) {
contributors = ContainerUtil.filter(contributors, (contributor) -> contributor instanceof LightEditCompatible);
}
SearchEverywhereUI view = new SearchEverywhereUI(project, contributors, myTabsShortcutsMap::get, spellingCorrector);
SearchEverywhereUI view = new SearchEverywhereUI(project, contributors, myTabsShortcutsMap::get, spellingCorrector, startMoment);
view.setSearchFinishedHandler(() -> {
if (isShown()) {

View File

@@ -30,6 +30,7 @@ import com.intellij.ide.util.treeView.smartTree.TreeElement;
import com.intellij.internal.statistic.eventLog.events.EventFields;
import com.intellij.internal.statistic.eventLog.events.EventPair;
import com.intellij.internal.statistic.local.ContributorsLocalSummary;
import com.intellij.internal.statistic.utils.StartMoment;
import com.intellij.lang.LanguageStructureViewBuilder;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
@@ -178,6 +179,14 @@ public final class SearchEverywhereUI extends BigPopupUI implements UiDataProvid
public SearchEverywhereUI(@Nullable Project project, List<SearchEverywhereContributor<?>> contributors,
@NotNull Function<? super String, String> shortcutSupplier,
@Nullable SearchEverywhereSpellingCorrector spellingCorrector) {
this(project, contributors, shortcutSupplier, spellingCorrector, null);
}
@ApiStatus.Internal
public SearchEverywhereUI(@Nullable Project project, List<SearchEverywhereContributor<?>> contributors,
@NotNull Function<? super String, String> shortcutSupplier,
@Nullable SearchEverywhereSpellingCorrector spellingCorrector,
@Nullable StartMoment startMoment) {
super(project);
mySpellingCorrector = spellingCorrector;
@@ -257,7 +266,8 @@ public final class SearchEverywhereUI extends BigPopupUI implements UiDataProvid
SearchPerformanceTracker performanceTracker = new SearchPerformanceTracker(() -> myHeader.getSelectedTab().getID());
addSearchListener(performanceTracker);
Disposer.register(this, SearchFieldStatisticsCollector.createAndStart(mySearchField, performanceTracker, myMlService, myProject));
Disposer.register(this, SearchFieldStatisticsCollector.createAndStart(mySearchField, performanceTracker, myMlService, myProject,
startMoment));
}
public void addSearchListener(SearchListener listener) {

View File

@@ -17,7 +17,7 @@ import java.util.List;
@ApiStatus.Internal
public final class SearchEverywhereUsageTriggerCollector extends CounterUsagesCollector {
private static final EventLogGroup GROUP = new EventLogGroup("searchEverywhere", 17);
private static final EventLogGroup GROUP = new EventLogGroup("searchEverywhere", 18);
// this string will be used as ID for contributors from private
// plugins that mustn't be sent in statistics
@@ -89,11 +89,12 @@ public final class SearchEverywhereUsageTriggerCollector extends CounterUsagesCo
public static final LongEventField TIME_TO_FIRST_RESULT_LAST_QUERY = EventFields.Long("timeToFirstResultLastQuery");
public static final StringEventField LAST_TAB_ID = EventFields.String("lastTabId", ourTabs);
public static final LongEventField DURATION_MS = EventFields.Long("durationMs");
public static final LongEventField DURATION_FROM_ACTION_START_MS = EventFields.Long("durationFromActionStartMs");
public static final IntEventField ML_EXPERIMENT_VERSION = EventFields.Int("mlExperimentVersion");
public static final IntEventField ML_EXPERIMENT_GROUP = EventFields.Int("mlExperimentGroup");
public static final VarargEventId SESSION_FINISHED = GROUP.registerVarargEvent(
"sessionFinished", TYPED_NAVIGATION_KEYS, TYPED_SYMBOL_KEYS,
TIME_TO_FIRST_RESULT, FIRST_TAB_ID, TIME_TO_FIRST_RESULT_LAST_QUERY, LAST_TAB_ID, DURATION_MS,
TIME_TO_FIRST_RESULT, FIRST_TAB_ID, TIME_TO_FIRST_RESULT_LAST_QUERY, LAST_TAB_ID, DURATION_MS, DURATION_FROM_ACTION_START_MS,
ML_EXPERIMENT_GROUP, ML_EXPERIMENT_VERSION
);
@@ -106,6 +107,7 @@ public final class SearchEverywhereUsageTriggerCollector extends CounterUsagesCo
}
public static @NotNull String getReportableContributorID(@NotNull SearchEverywhereContributor<?> contributor) {
//noinspection rawtypes
Class<? extends SearchEverywhereContributor> clazz = contributor.getClass();
PluginInfo pluginInfo = PluginInfoDetectorKt.getPluginInfo(clazz);
return pluginInfo.isDevelopedByJetBrains() ? contributor.getSearchProviderId() : NOT_REPORTABLE_CONTRIBUTOR_ID;

View File

@@ -2,9 +2,13 @@
package com.intellij.ide.actions.searcheverywhere.statistics;
import com.intellij.ide.actions.searcheverywhere.SearchEverywhereMlService;
import com.intellij.internal.statistic.utils.StartMoment;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.KeyAdapter;
@@ -17,6 +21,7 @@ public final class SearchFieldStatisticsCollector implements Disposable {
private final Project myProject;
private final JTextField myTextField;
private final StartMoment myStartMoment;
private final SearchEverywhereMlService myMlService;
private final SearchPerformanceTracker myPerformanceTracker;
@@ -24,18 +29,20 @@ public final class SearchFieldStatisticsCollector implements Disposable {
private int myNavKeysTyped;
private SearchFieldStatisticsCollector(JTextField field, SearchPerformanceTracker performanceTracker,
SearchEverywhereMlService mlService, Project project) {
SearchEverywhereMlService mlService, Project project, @Nullable StartMoment startMoment) {
myProject = project;
myPerformanceTracker = performanceTracker;
myMlService = mlService;
myTextField = field;
myStartMoment = startMoment;
}
public static SearchFieldStatisticsCollector createAndStart(JTextField field,
SearchPerformanceTracker performanceTracker,
SearchEverywhereMlService mlService,
Project project) {
SearchFieldStatisticsCollector res = new SearchFieldStatisticsCollector(field, performanceTracker, mlService, project);
Project project,
@Nullable StartMoment startMoment) {
SearchFieldStatisticsCollector res = new SearchFieldStatisticsCollector(field, performanceTracker, mlService, project, startMoment);
res.initListeners();
return res;
}
@@ -59,6 +66,9 @@ public final class SearchFieldStatisticsCollector implements Disposable {
pairs.add(TYPED_NAVIGATION_KEYS.with(myNavKeysTyped));
pairs.add(TYPED_SYMBOL_KEYS.with(mySymbolKeysTyped));
pairs.add(DURATION_MS.with(info.getDuration()));
if (myStartMoment != null) {
pairs.add(DURATION_FROM_ACTION_START_MS.with(myStartMoment.getCurrentDuration().toMillis()));
}
if (myMlService != null) {
pairs.add(ML_EXPERIMENT_VERSION.with(myMlService.getExperimentVersion()));
@@ -84,4 +94,30 @@ public final class SearchFieldStatisticsCollector implements Disposable {
}
});
}
private static final DataKey<StartMoment> START_MOMENT_KEY = DataKey.create("start_moment_of_search_everywhere");
public static StartMoment getStartMoment(AnActionEvent event) {
return event.getData(START_MOMENT_KEY);
}
@NotNull
public static AnActionEvent wrapEventWithActionStartData(@NotNull AnActionEvent event) {
StartMoment startMoment = StartMoment.Companion.now();
DataContext initialDataContext = event.getDataContext();
DataContext wrappedDataContext = wrapDataContextWithActionStartData(initialDataContext, startMoment);
if (wrappedDataContext == initialDataContext) return event;
return event.withDataContext(wrappedDataContext);
}
@NotNull
private static DataContext wrapDataContextWithActionStartData(@NotNull DataContext dataContext, @NotNull StartMoment startMoment) {
if (dataContext.getData(START_MOMENT_KEY) != null) return dataContext;
return CustomizedDataContext.withSnapshot(dataContext, sink -> sink.set(START_MOMENT_KEY, startMoment));
}
@NotNull
public static DataContext wrapDataContextWithActionStartData(@NotNull DataContext dataContext) {
return wrapDataContextWithActionStartData(dataContext, StartMoment.Companion.now());
}
}

View File

@@ -0,0 +1,27 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.internal.statistic.utils
import org.jetbrains.annotations.ApiStatus
/**
* Is used to track durations for reporting to FUS
*/
@ApiStatus.Internal
@ApiStatus.Experimental
interface StartMoment {
companion object {
fun now(): StartMoment {
return InstantStartMoment()
}
private class InstantStartMoment(private val now: Long = System.nanoTime()) : StartMoment {
override fun getCurrentDuration(): java.time.Duration {
return java.time.Duration.ofNanos(System.nanoTime() - now)
}
}
}
fun getCurrentDuration(): java.time.Duration
}

View File

@@ -40,6 +40,7 @@ import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadPoolExecutor;
import static com.intellij.openapi.ui.playback.commands.ActionCommand.getInputEvent;
import static com.intellij.ide.actions.searcheverywhere.statistics.SearchFieldStatisticsCollector.wrapDataContextWithActionStartData;
import static com.intellij.openapi.ui.playback.commands.AlphaNumericTypeCommand.findTarget;
/**
@@ -103,11 +104,12 @@ public class SearchEverywhereCommand extends AbstractCommand {
DataContext dataContext = CustomizedDataContext.withSnapshot(
DataManager.getInstance().getDataContext(component),
sink -> sink.set(CommonDataKeys.PROJECT, context.getProject()));
DataContext wrappedDataContext = wrapDataContextWithActionStartData(dataContext);
IdeEventQueue.getInstance().getPopupManager().closeAllPopups(false);
TraceKt.use(PerformanceTestSpan.getTracer(warmup).spanBuilder("searchEverywhere_dialog_shown"), dialogSpan -> {
var manager = SearchEverywhereManager.getInstance(project);
AnActionEvent event = AnActionEvent.createEvent(
dataContext, null, ActionPlaces.EDITOR_POPUP, ActionUiKind.POPUP, null);
wrappedDataContext, null, ActionPlaces.EDITOR_POPUP, ActionUiKind.POPUP, null);
manager.show(tabId.get(), "", event);
attachSearchListeners(manager.getCurrentlyShownUI());
return null;