mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
IJPL-164498 Provide the ability to see thread dump from "plugin might be slowing down" notification
(cherry picked from commit 221a494ba04c3bc696efdf39d7962e3d23eb88fb) IJ-CR-146685 GitOrigin-RevId: 913f93c2c4381878807efd2b05cb800882aef97a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
9dbc6953c2
commit
2fa39514f1
@@ -39,5 +39,6 @@
|
||||
<orderEntry type="library" name="kotlinx-serialization-json" level="project" />
|
||||
<orderEntry type="library" name="kotlinx-serialization-core" level="project" />
|
||||
<orderEntry type="module" module-name="intellij.platform.statistics" />
|
||||
<orderEntry type="module" module-name="intellij.platform.core.ui" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -4,7 +4,9 @@
|
||||
</dependencies>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<editorNotificationProvider implementation="com.intellij.platform.diagnostic.plugin.freeze.PluginFreezeNotifier"/>
|
||||
<diagnostic.freezeNotifier implementation="com.intellij.platform.diagnostic.plugin.freeze.PluginFreezeNotifier"/>
|
||||
<editorNotificationProvider implementation="com.intellij.platform.diagnostic.plugin.freeze.PluginFreezeNotificationPanel"/>
|
||||
|
||||
<registryKey key="ide.diagnostics.notification.freezes.in.plugins"
|
||||
defaultValue="true"
|
||||
description="Show notification about freezes in plugins"/>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
action.disable.plugin.text=Disable plugin
|
||||
action.close.panel.text=Dismiss
|
||||
action.ignore.plugin.text=Ignore freezes in plugin
|
||||
notification.content.plugin.caused.freeze.detected=Plugin ''{0}'' might be slowing things down
|
||||
action.open.issue.tracker.text=Open issue tracker
|
||||
progress.title.opening.issue.tracker=Opening plugin issue tracker
|
||||
action.ignore.plugin.text=Ignore
|
||||
notification.content.freeze.detected={0} has encountered a slowdown
|
||||
notification.content.plugin.caused.freeze=Plugin ''{0}'' might be slowing things down
|
||||
action.report.text=Report problem
|
||||
action.ignore.plugin.tooltip=Ignore such performance issues in the future
|
||||
action.dismiss.tooltip=Dismiss the notification
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
// 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.platform.diagnostic.plugin.freeze
|
||||
|
||||
import com.intellij.diagnostic.FreezeNotifier
|
||||
import com.intellij.diagnostic.IdeErrorsDialog
|
||||
import com.intellij.diagnostic.MessagePool
|
||||
import com.intellij.diagnostic.ThreadDump
|
||||
import com.intellij.featureStatistics.fusCollectors.LifecycleUsageTriggerCollector
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.ide.plugins.PluginManagerCore.isVendorJetBrains
|
||||
import com.intellij.openapi.application.impl.ApplicationInfoImpl
|
||||
import com.intellij.openapi.diagnostic.IdeaLoggingEvent
|
||||
import com.intellij.openapi.extensions.PluginDescriptor
|
||||
import com.intellij.openapi.fileEditor.FileEditor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.ui.EditorNotificationPanel
|
||||
import com.intellij.ui.EditorNotificationProvider
|
||||
import com.intellij.ui.EditorNotifications
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
import java.util.function.Function
|
||||
import javax.swing.JComponent
|
||||
|
||||
internal class PluginFreezeNotifier: FreezeNotifier {
|
||||
override fun notifyFreeze(event: IdeaLoggingEvent, currentDumps: Collection<ThreadDump>, reportDir: Path, durationMs: Long) {
|
||||
val freezeWatcher = PluginFreezeWatcher.getInstance()
|
||||
|
||||
val freezeReason = freezeWatcher.getFreezeReason()
|
||||
if (freezeReason != null) return // still have previous reason shown to user
|
||||
|
||||
for (dump in currentDumps) {
|
||||
val reason = freezeWatcher.dumpedThreads(event, dump, durationMs)
|
||||
if (reason != null) {
|
||||
LifecycleUsageTriggerCollector.pluginFreezeDetected(reason.pluginId, durationMs)
|
||||
|
||||
reportFreeze()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun reportFreeze() {
|
||||
for (project in ProjectManager.getInstance().openProjects) {
|
||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class PluginFreezeNotificationPanel : EditorNotificationProvider {
|
||||
private val reported: MutableSet<FreezeReason> = Collections.synchronizedSet(HashSet())
|
||||
|
||||
override fun collectNotificationData(project: Project, file: VirtualFile): Function<in FileEditor, out JComponent?>? {
|
||||
if (!Registry.get("ide.diagnostics.notification.freezes.in.plugins").asBoolean()) return null
|
||||
|
||||
val freezeReason = PluginFreezeWatcher.getInstance().getFreezeReason() ?: return null
|
||||
val frozenPlugin = freezeReason.pluginId
|
||||
val pluginDescriptor = PluginManagerCore.getPlugin(frozenPlugin) ?: return null
|
||||
|
||||
return Function {
|
||||
EditorNotificationPanel(EditorNotificationPanel.Status.Warning).apply {
|
||||
text = if (isVendorJetBrains(pluginDescriptor.vendor ?: "")) {
|
||||
PluginFreezeBundle.message("notification.content.freeze.detected", ApplicationInfoImpl.getShadowInstance().versionName)
|
||||
}
|
||||
else {
|
||||
PluginFreezeBundle.message("notification.content.plugin.caused.freeze", pluginDescriptor.name)
|
||||
}
|
||||
|
||||
createActionLabel(PluginFreezeBundle.message("action.report.text")) {
|
||||
reportFreeze(project, pluginDescriptor, freezeReason)
|
||||
}
|
||||
createActionLabel(PluginFreezeBundle.message("action.ignore.plugin.text")) {
|
||||
PluginsFreezesService.getInstance().mutePlugin(frozenPlugin)
|
||||
|
||||
LifecycleUsageTriggerCollector.pluginFreezeIgnored(frozenPlugin)
|
||||
|
||||
closePanel(project)
|
||||
}.apply {
|
||||
toolTipText = PluginFreezeBundle.message("action.ignore.plugin.tooltip")
|
||||
}
|
||||
|
||||
createActionLabel(PluginFreezeBundle.message("action.close.panel.text")) {
|
||||
closePanel(project)
|
||||
}.apply {
|
||||
toolTipText = PluginFreezeBundle.message("action.dismiss.tooltip")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun reportFreeze(project: Project, pluginDescriptor: PluginDescriptor, freezeReason: FreezeReason) {
|
||||
if (reported.add(freezeReason)) {
|
||||
// must be added only once
|
||||
MessagePool.getInstance().addIdeFatalMessage(freezeReason.event)
|
||||
}
|
||||
|
||||
val dialog = object : IdeErrorsDialog(MessagePool.getInstance(), project, null) {
|
||||
override fun updateOnSubmit() {
|
||||
super.updateOnSubmit()
|
||||
|
||||
LifecycleUsageTriggerCollector.pluginFreezeReported(pluginDescriptor.pluginId)
|
||||
closePanel(project)
|
||||
}
|
||||
}
|
||||
|
||||
dialog.show()
|
||||
}
|
||||
|
||||
private fun closePanel(project: Project) {
|
||||
PluginFreezeWatcher.getInstance().reset()
|
||||
reported.clear()
|
||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
// 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.platform.diagnostic.plugin.freeze
|
||||
|
||||
import com.intellij.featureStatistics.fusCollectors.LifecycleUsageTriggerCollector
|
||||
import com.intellij.ide.BrowserUtil
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.impl.ApplicationInfoImpl
|
||||
import com.intellij.openapi.extensions.PluginId
|
||||
import com.intellij.openapi.fileEditor.FileEditor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
|
||||
import com.intellij.ui.EditorNotificationPanel
|
||||
import com.intellij.ui.EditorNotificationProvider
|
||||
import com.intellij.ui.EditorNotifications
|
||||
import com.intellij.util.ui.RestartDialogImpl
|
||||
import java.util.function.Function
|
||||
import javax.swing.JComponent
|
||||
|
||||
internal class PluginFreezeNotifier : EditorNotificationProvider {
|
||||
private val freezeWatcher = PluginFreezeWatcher.getInstance()
|
||||
private val freezeStorageService = PluginsFreezesService.getInstance()
|
||||
|
||||
override fun collectNotificationData(project: Project, file: VirtualFile): Function<in FileEditor, out JComponent?>? {
|
||||
if (!Registry.get("ide.diagnostics.notification.freezes.in.plugins").asBoolean()) return null
|
||||
|
||||
val frozenPlugin = freezeWatcher.getFreezeReason() ?: return null
|
||||
val pluginDescriptor = PluginManagerCore.getPlugin(frozenPlugin) ?: return null
|
||||
val application = ApplicationManager.getApplication()
|
||||
if (pluginDescriptor.isImplementationDetail || ApplicationInfoImpl.getShadowInstance().isEssentialPlugin(frozenPlugin)) return null
|
||||
if (pluginDescriptor.isBundled && !application.isInternal) return null
|
||||
|
||||
return Function {
|
||||
EditorNotificationPanel(EditorNotificationPanel.Status.Warning).apply {
|
||||
text = PluginFreezeBundle.message("notification.content.plugin.caused.freeze.detected", pluginDescriptor.name)
|
||||
createActionLabel(PluginFreezeBundle.message("action.disable.plugin.text")) {
|
||||
disablePlugin(frozenPlugin)
|
||||
|
||||
LifecycleUsageTriggerCollector.pluginDisabledOnFreeze(frozenPlugin)
|
||||
}
|
||||
createActionLabel(PluginFreezeBundle.message("action.ignore.plugin.text")) {
|
||||
freezeStorageService.mutePlugin(frozenPlugin)
|
||||
|
||||
LifecycleUsageTriggerCollector.pluginFreezeIgnored(frozenPlugin)
|
||||
|
||||
closePanel(project)
|
||||
}
|
||||
createActionLabel(PluginFreezeBundle.message("action.open.issue.tracker.text")) {
|
||||
openIssueTracker(project, pluginDescriptor)
|
||||
|
||||
LifecycleUsageTriggerCollector.pluginIssueTrackerOpened()
|
||||
}
|
||||
createActionLabel(PluginFreezeBundle.message("action.close.panel.text")) {
|
||||
closePanel(project)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO support dynamic plugins
|
||||
private fun disablePlugin(frozenPlugin: PluginId) {
|
||||
val pluginDisabled = PluginManagerCore.disablePlugin(frozenPlugin)
|
||||
if (pluginDisabled) {
|
||||
RestartDialogImpl.showRestartRequired()
|
||||
}
|
||||
}
|
||||
|
||||
private fun openIssueTracker(project: Project, pluginDescriptor: IdeaPluginDescriptor) {
|
||||
runWithModalProgressBlocking(project, PluginFreezeBundle.message("progress.title.opening.issue.tracker")) {
|
||||
PluginIssueTrackerResolver.getMarketplaceBugTrackerUrl(pluginDescriptor)?.let {
|
||||
BrowserUtil.open(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun closePanel(project: Project) {
|
||||
freezeWatcher.reset()
|
||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,21 @@
|
||||
package com.intellij.platform.diagnostic.plugin.freeze
|
||||
|
||||
import com.intellij.diagnostic.IdePerformanceListener
|
||||
import com.intellij.diagnostic.ThreadDump
|
||||
import com.intellij.featureStatistics.fusCollectors.LifecycleUsageTriggerCollector
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.ide.plugins.PluginUtilImpl
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.ReadAction
|
||||
import com.intellij.openapi.application.impl.ApplicationInfoImpl
|
||||
import com.intellij.openapi.components.Service
|
||||
import com.intellij.openapi.components.service
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.diagnostic.IdeaLoggingEvent
|
||||
import com.intellij.openapi.extensions.PluginId
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
import com.intellij.platform.diagnostic.freezeAnalyzer.FreezeAnalyzer
|
||||
import com.intellij.threadDumpParser.ThreadState
|
||||
import com.intellij.ui.EditorNotifications
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.absolutePathString
|
||||
|
||||
@Service(Service.Level.APP)
|
||||
internal class PluginFreezeWatcher : IdePerformanceListener, Disposable {
|
||||
internal class PluginFreezeWatcher {
|
||||
@Volatile
|
||||
private var latestFrozenPlugin: PluginId? = null
|
||||
@Volatile
|
||||
private var lastFreezeDuration: Long = -1
|
||||
private var reason: FreezeReason? = null
|
||||
|
||||
private val stackTracePattern: Regex = """at (\S+)\.(\S+)\(([^:]+):(\d+)\)""".toRegex()
|
||||
|
||||
@@ -32,66 +24,29 @@ internal class PluginFreezeWatcher : IdePerformanceListener, Disposable {
|
||||
fun getInstance(): PluginFreezeWatcher = service()
|
||||
}
|
||||
|
||||
init {
|
||||
ApplicationManager.getApplication().messageBus.connect(this)
|
||||
.subscribe(IdePerformanceListener.TOPIC, this)
|
||||
}
|
||||
|
||||
fun getFreezeReason(): PluginId? = latestFrozenPlugin
|
||||
fun getFreezeReason(): FreezeReason? = reason
|
||||
|
||||
fun reset() {
|
||||
latestFrozenPlugin = null
|
||||
lastFreezeDuration = -1
|
||||
reason = null
|
||||
}
|
||||
|
||||
override fun dispose() {}
|
||||
|
||||
override fun uiFreezeStarted(reportDir: Path) {
|
||||
if (latestFrozenPlugin != null) return
|
||||
|
||||
lastFreezeDuration = -1
|
||||
}
|
||||
|
||||
override fun uiFreezeFinished(durationMs: Long, reportDir: Path?) {
|
||||
if (lastFreezeDuration < 0) {
|
||||
lastFreezeDuration = durationMs
|
||||
|
||||
reportCounters()
|
||||
}
|
||||
}
|
||||
|
||||
override fun dumpedThreads(toFile: Path, dump: ThreadDump) {
|
||||
if (latestFrozenPlugin != null) return // user have not yet handled previous failure
|
||||
|
||||
fun dumpedThreads(event: IdeaLoggingEvent, dump: ThreadDump, durationMs: Long) : FreezeReason? {
|
||||
val freezeCausingThreads = FreezeAnalyzer.analyzeFreeze(dump.rawDump, null)?.threads.orEmpty()
|
||||
val pluginIds = freezeCausingThreads.mapNotNull { analyzeFreezeCausingPlugin(it) }
|
||||
val frozenPlugin = pluginIds.groupingBy { it }.eachCount().maxByOrNull { it.value }?.key ?: return
|
||||
val frozenPlugin = pluginIds.groupingBy { it }.eachCount().maxByOrNull { it.value }?.key ?: return null
|
||||
|
||||
val pluginDescriptor = PluginManagerCore.getPlugin(frozenPlugin) ?: return null
|
||||
|
||||
if (pluginDescriptor.isImplementationDetail || ApplicationInfoImpl.getShadowInstance().isEssentialPlugin(frozenPlugin)) return null
|
||||
if (pluginDescriptor.isBundled && !ApplicationManager.getApplication().isInternal) return null
|
||||
|
||||
val freezeStorageService = PluginsFreezesService.getInstance()
|
||||
if (freezeStorageService.shouldBeIgnored(frozenPlugin)) return
|
||||
if (freezeStorageService.shouldBeIgnored(frozenPlugin)) return null
|
||||
freezeStorageService.setLatestFreezeDate(frozenPlugin)
|
||||
|
||||
latestFrozenPlugin = frozenPlugin
|
||||
reason = FreezeReason(frozenPlugin, event, durationMs)
|
||||
|
||||
Logger.getInstance(PluginFreezeWatcher::class.java)
|
||||
.warn("Plugin '$frozenPlugin' caused IDE freeze." +
|
||||
"Find thread dumps at ${toFile.absolutePathString()}")
|
||||
|
||||
reportCounters()
|
||||
|
||||
ReadAction.compute<Unit, Throwable> {
|
||||
for (project in ProjectManager.getInstance().openProjects) {
|
||||
EditorNotifications.getInstance(project).updateAllNotifications()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun reportCounters() {
|
||||
latestFrozenPlugin?.let {
|
||||
if (lastFreezeDuration > 0) {
|
||||
LifecycleUsageTriggerCollector.pluginFreezeReported(it, lastFreezeDuration)
|
||||
}
|
||||
}
|
||||
return reason
|
||||
}
|
||||
|
||||
private fun analyzeFreezeCausingPlugin(threadInfo: ThreadState): PluginId? {
|
||||
@@ -109,4 +64,10 @@ internal class PluginFreezeWatcher : IdePerformanceListener, Disposable {
|
||||
StackTraceElement(className, methodName, fileName, lineNumber.toInt())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal data class FreezeReason(
|
||||
val pluginId: PluginId,
|
||||
val event: IdeaLoggingEvent,
|
||||
val durationMs: Long
|
||||
)
|
||||
@@ -0,0 +1,11 @@
|
||||
// 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.diagnostic
|
||||
|
||||
import com.intellij.openapi.diagnostic.IdeaLoggingEvent
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.nio.file.Path
|
||||
|
||||
@ApiStatus.Internal
|
||||
interface FreezeNotifier {
|
||||
fun notifyFreeze(event: IdeaLoggingEvent, currentDumps: Collection<ThreadDump>, reportDir: Path, durationMs: Long)
|
||||
}
|
||||
@@ -68,7 +68,7 @@ import javax.swing.event.DocumentEvent
|
||||
import javax.swing.event.HyperlinkEvent
|
||||
import javax.swing.text.JTextComponent
|
||||
|
||||
open class IdeErrorsDialog internal constructor(
|
||||
open class IdeErrorsDialog @ApiStatus.Internal constructor(
|
||||
private val myMessagePool: MessagePool,
|
||||
private val myProject: Project?,
|
||||
defaultMessage: LogMessage?
|
||||
|
||||
@@ -34,9 +34,11 @@ import kotlin.coroutines.coroutineContext
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
private val FREEZE_NOTIFIER_EP: ExtensionPointName<FreezeNotifier> = ExtensionPointName("com.intellij.diagnostic.freezeNotifier")
|
||||
|
||||
internal class IdeaFreezeReporter : PerformanceListener {
|
||||
private var dumpTask: SamplingTask? = null
|
||||
private val currentDumps = ArrayList<ThreadDump>()
|
||||
private val currentDumps = Collections.synchronizedList(ArrayList<ThreadDump>())
|
||||
private var stacktraceCommonPart: List<StackTraceElement>? = null
|
||||
|
||||
@Volatile
|
||||
@@ -165,19 +167,30 @@ internal class IdeaFreezeReporter : PerformanceListener {
|
||||
return
|
||||
}
|
||||
|
||||
val dumps = ArrayList(currentDumps) // defensive copy
|
||||
|
||||
if (Registry.`is`("freeze.reporter.enabled", false)) {
|
||||
val performanceWatcher = PerformanceWatcher.getInstance()
|
||||
// check that we have at least half of the dumps required
|
||||
if ((durationMs / 1000).toInt() > FREEZE_THRESHOLD && !stacktraceCommonPart.isNullOrEmpty()) {
|
||||
val dumpingDurationMs = durationMs - performanceWatcher.unresponsiveInterval
|
||||
val dumpsCount = min(performanceWatcher.maxDumpDuration.toLong(), dumpingDurationMs / 2) / performanceWatcher.dumpInterval
|
||||
if (dumpTask.isValid(dumpingDurationMs) || currentDumps.size >= max(3, dumpsCount)) {
|
||||
if (dumpTask.isValid(dumpingDurationMs) || dumps.size >= max(3, dumpsCount)) {
|
||||
val attachments = ArrayList<Attachment>()
|
||||
addDumpsAttachments(from = currentDumps, textMapper = { it.rawDump }, container = attachments)
|
||||
addDumpsAttachments(from = dumps, textMapper = { it.rawDump }, container = attachments)
|
||||
if (reportDir != null) {
|
||||
EP_NAME.forEachExtensionSafe { attachments.addAll(it.getAttachments(reportDir)) }
|
||||
}
|
||||
report(createEvent(dumpTask, durationMs, attachments, reportDir, performanceWatcher, finished = true))
|
||||
|
||||
val loggingEvent = createEvent(dumpTask, durationMs, attachments, reportDir, performanceWatcher, finished = true)
|
||||
|
||||
report(loggingEvent)
|
||||
|
||||
if (reportDir != null && loggingEvent != null && dumps.isNotEmpty()) {
|
||||
for (notifier in FREEZE_NOTIFIER_EP.extensionList) {
|
||||
notifier.notifyFreeze(loggingEvent, dumps, reportDir, durationMs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import static com.intellij.internal.statistic.utils.PluginInfoDetectorKt.getPlug
|
||||
public final class LifecycleUsageTriggerCollector extends CounterUsagesCollector {
|
||||
private static final Logger LOG = Logger.getInstance(LifecycleUsageTriggerCollector.class);
|
||||
|
||||
private static final EventLogGroup LIFECYCLE = new EventLogGroup("lifecycle", 72);
|
||||
private static final EventLogGroup LIFECYCLE = new EventLogGroup("lifecycle", 73);
|
||||
|
||||
private static final EventField<Boolean> eapField = EventFields.Boolean("eap");
|
||||
private static final EventField<Boolean> testField = EventFields.Boolean("test");
|
||||
@@ -66,14 +66,12 @@ public final class LifecycleUsageTriggerCollector extends CounterUsagesCollector
|
||||
|
||||
private static final EventId1<Long> IDE_FREEZE = LIFECYCLE.registerEvent("ide.freeze", EventFields.DurationMs);
|
||||
|
||||
private static final EventId2<PluginInfo, Long> IDE_FREEZE_REPORTED_PLUGIN =
|
||||
LIFECYCLE.registerEvent("ide.freeze.plugin", EventFields.PluginInfo, EventFields.DurationMs);
|
||||
private static final EventId1<PluginInfo> IDE_FREEZE_PLUGIN_DISABLED =
|
||||
LIFECYCLE.registerEvent("ide.freeze.disabled.plugin", EventFields.PluginInfo);
|
||||
private static final EventId2<PluginInfo, Long> IDE_FREEZE_DETECTED_PLUGIN =
|
||||
LIFECYCLE.registerEvent("ide.freeze.detected.plugin", EventFields.PluginInfo, EventFields.DurationMs);
|
||||
private static final EventId1<PluginInfo> IDE_FREEZE_PLUGIN_ISSUE_REPORTED =
|
||||
LIFECYCLE.registerEvent("ide.freeze.reported.plugin", EventFields.PluginInfo);
|
||||
private static final EventId1<PluginInfo> IDE_FREEZE_PLUGIN_IGNORED =
|
||||
LIFECYCLE.registerEvent("ide.freeze.ignored.plugin", EventFields.PluginInfo);
|
||||
private static final EventId IDE_FREEZE_PLUGIN_ISSUE_TRACKER_OPENED =
|
||||
LIFECYCLE.registerEvent("ide.freeze.issue.tracker.opened");
|
||||
|
||||
private static final ClassEventField errorField = EventFields.Class("error");
|
||||
private static final EventField<VMOptions.MemoryKind> memoryErrorKindField =
|
||||
@@ -231,19 +229,15 @@ public final class LifecycleUsageTriggerCollector extends CounterUsagesCollector
|
||||
EARLY_ERRORS.log(numErrors);
|
||||
}
|
||||
|
||||
public static void pluginFreezeReported(@NotNull PluginId pluginId, long durationMs) {
|
||||
IDE_FREEZE_REPORTED_PLUGIN.log(getPluginInfoById(pluginId), durationMs);
|
||||
public static void pluginFreezeDetected(@NotNull PluginId pluginId, long durationMs) {
|
||||
IDE_FREEZE_DETECTED_PLUGIN.log(getPluginInfoById(pluginId), durationMs);
|
||||
}
|
||||
|
||||
public static void pluginDisabledOnFreeze(@NotNull PluginId id) {
|
||||
IDE_FREEZE_PLUGIN_DISABLED.log(getPluginInfoById(id));
|
||||
public static void pluginFreezeReported(@NotNull PluginId pluginId) {
|
||||
IDE_FREEZE_PLUGIN_ISSUE_REPORTED.log(getPluginInfoById(pluginId));
|
||||
}
|
||||
|
||||
public static void pluginFreezeIgnored(@NotNull PluginId id) {
|
||||
IDE_FREEZE_PLUGIN_IGNORED.log(getPluginInfoById(id));
|
||||
}
|
||||
|
||||
public static void pluginIssueTrackerOpened() {
|
||||
IDE_FREEZE_PLUGIN_ISSUE_TRACKER_OPENED.log();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<!-- only bundled plugin can define extension -->
|
||||
<!--suppress PluginXmlDynamicPlugin -->
|
||||
<extensionPoint name="registerToolWindowTaskProvider" interface="com.intellij.toolWindow.RegisterToolWindowTaskProvider"/>
|
||||
<extensionPoint qualifiedName="com.intellij.diagnostic.freezeNotifier" interface="com.intellij.diagnostic.FreezeNotifier"/>
|
||||
</extensionPoints>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
|
||||
Reference in New Issue
Block a user