From 437da281d5388f7aeb17650149cfcf0d5d0cbb71 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Sun, 11 Apr 2010 22:25:40 +0400 Subject: [PATCH] some logging... --- .../progress/impl/ProgressManagerImpl.java | 54 +++++++++++++++++-- .../wm/impl/status/InfoAndProgressPanel.java | 46 ++++++++++++++-- 2 files changed, 90 insertions(+), 10 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java index 943961afb290..33d5ef39b222 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/impl/ProgressManagerImpl.java @@ -20,6 +20,7 @@ import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ex.ApplicationEx; +import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.progress.*; @@ -28,15 +29,18 @@ import com.intellij.openapi.progress.util.SmoothProgressAdapter; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.wm.WindowManager; import com.intellij.openapi.wm.ex.ProgressIndicatorEx; import com.intellij.psi.PsiLock; import com.intellij.ui.SystemNotifications; +import com.intellij.util.containers.SortedList; +import gnu.trove.THashMap; import org.jetbrains.annotations.*; import javax.swing.*; import java.awt.*; -import java.util.ArrayList; +import java.util.*; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @@ -53,6 +57,8 @@ public class ProgressManagerImpl extends ProgressManager { @NonNls private static final String NAME = "Progress Cancel Checker"; private static final boolean DISABLED = Comparing.equal(System.getProperty(PROCESS_CANCELED_EXCEPTION), "disabled"); + private static final Map myWastedTime = new THashMap(); + public ProgressManagerImpl(Application application) { if (!application.isUnitTestMode() && !DISABLED) { final Thread thread = new Thread(NAME) { @@ -250,6 +256,7 @@ public class ProgressManagerImpl extends ProgressManager { private static boolean runProcessWithProgressSynchronously(final Task task, final JComponent parentComponent) { final long start = System.currentTimeMillis(); + long time = 0; final boolean result = ((ApplicationEx)ApplicationManager.getApplication()) .runProcessWithProgressSynchronously(new TaskContainer(task) { public void run() { @@ -259,18 +266,19 @@ public class ProgressManagerImpl extends ProgressManager { if (result) { final long end = System.currentTimeMillis(); final Task.NotificationInfo notificationInfo = task.getNotificationInfo(); - if (notificationInfo != null && end - start > 5000) { // show notification only if process took more than 5 secs + time = end - start; + if (notificationInfo != null && time > 5000) { // show notification only if process took more than 5 secs final JFrame frame = WindowManager.getInstance().getFrame(task.getProject()); if (!frame.hasFocus()) { systemNotify(notificationInfo); } } - task.onSuccess(); } else { task.onCancel(); } + moreTimeWasted(time, task); return result; } @@ -344,26 +352,28 @@ public class ProgressManagerImpl extends ProgressManager { canceled = true; } final long end = System.currentTimeMillis(); + final long time = end - start; if (canceled || progressIndicator.isCanceled()) { ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { task.onCancel(); + moreTimeWasted(time, task); } }, ModalityState.NON_MODAL); } else if (!canceled) { final Task.NotificationInfo notificationInfo = task.getNotificationInfo(); - if (notificationInfo != null && end - start > 5000) { // snow notification if process took more than 5 secs + if (notificationInfo != null && time > 5000) { // snow notification if process took more than 5 secs final Component window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow(); if (window == null || notificationInfo.isShowWhenFocused()) { systemNotify(notificationInfo); } } - ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { task.onSuccess(); + moreTimeWasted(time, task); } }, ModalityState.NON_MODAL); } @@ -381,6 +391,40 @@ public class ProgressManagerImpl extends ProgressManager { } } + private static void moreTimeWasted(long time, Task timeEater) { + if (!ApplicationManagerEx.getApplicationEx().isInternal()) return; + + synchronized (myWastedTime) { + String title = timeEater.getTitle(); + Long total = myWastedTime.get(title); + myWastedTime.put(title, total == null ? time : total + time); + } + } + + public static long getWastedTime() { + synchronized (myWastedTime) { + long result = 0; + for (Map.Entry each : myWastedTime.entrySet()) { + result += each.getValue(); + } + return result; + } + } + + public static List> getTimeWasters() { + synchronized (myWastedTime) { + SortedList> result = new SortedList>(new Comparator>() { + public int compare(Pair o1, Pair o2) { + return o2.second.compareTo(o1.second); + } + }); + for (Map.Entry each : myWastedTime.entrySet()) { + result.add(Pair.create(each.getKey(), each.getValue())); + } + return result; + } + } + public void run(@NotNull final Task task) { if (task.isHeadless()) { new TaskRunnable(task, new EmptyProgressIndicator()).run(); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java index 188f00b54b80..41671bc698f5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java @@ -17,13 +17,17 @@ package com.intellij.openapi.wm.impl.status; import com.intellij.idea.ActionsBundle; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.TaskInfo; +import com.intellij.openapi.progress.impl.ProgressManagerImpl; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.BalloonHandler; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.MultiValuesMap; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.ToolWindowAnchor; import com.intellij.openapi.wm.ex.ProgressIndicatorEx; @@ -47,10 +51,9 @@ import javax.swing.event.HyperlinkListener; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.List; public class InfoAndProgressPanel extends JPanel implements StatusBarPatch { private final ProcessPopup myPopup; @@ -378,13 +381,46 @@ public class InfoAndProgressPanel extends JPanel implements StatusBarPatch { removeAll(); setLayout(new BorderLayout()); add(myInfoPanel, BorderLayout.CENTER); + myProgressIcon.setBorder(myCompoundBorder); - add(myProgressIcon, BorderLayout.EAST); + + long wastedTime = ProgressManagerImpl.getWastedTime(); + if (ApplicationManagerEx.getApplicationEx().isInternal() && wastedTime > 10 * 1000) { + JPanel wrapper = new JPanel(new BorderLayout()); + wrapper.add(new JLabel(" Your wasted time: " + formatTime(wastedTime) + " "), BorderLayout.CENTER); + wrapper.add(myProgressIcon, BorderLayout.EAST); + + long time = System.currentTimeMillis() - ApplicationManagerEx.getApplicationEx().getStartTime(); + long percentage = wastedTime * 100 / time; + String period = new SimpleDateFormat("mm 'min' HH 'hours'").format(new Date(2000, 0, 1, 0, 0, 0).getTime() + time); + + List> list = ProgressManagerImpl.getTimeWasters(); + StringBuilder s = new StringBuilder("Successfully wasted " + percentage +"% of your time in " + period + ":
"); + for (Pair each : list) { + s.append(""); + s.append(each.first); + s.append(":"); + s.append(formatTime(each.second)); + s.append(""); + } + s.append(""); + wrapper.setToolTipText(s.toString()); + add(wrapper, BorderLayout.EAST); + } else { + add(myProgressIcon, BorderLayout.EAST); + } + myProgressIcon.suspend(); myInfoPanel.revalidate(); myInfoPanel.repaint(); } + private String formatTime(long t) { + if (t < 1000) return "< 1 sec"; + if (t < 60 * 1000) return (t / 1000) + " sec"; + return "~" + (int)Math.ceil(t / (60 * 1000f)) + " min"; + } + public boolean isProcessWindowOpen() { return myPopup.isShowing(); }