modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/authentication/AuthenticateUserAction.java | 7 + modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/framework/FaceletRedirectionViewHandler.java | 21 +++- modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserTrackingFilter.java | 3 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/HibernatePerformanceMonitor.java | 48 +++++++++- modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/HibernateStatisticsStopWatch.java | 32 +++++- 5 files changed, 102 insertions(+), 9 deletions(-)
New commits: commit 002b86ac0fc42f69e390a5f51ea104a7afbd8369 Author: Joseph Marques joseph@redhat.com Date: Fri Mar 26 03:13:34 2010 -0400
improve logging to capture some simple rules and thresholds to indicate performance issues
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/framework/FaceletRedirectionViewHandler.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/framework/FaceletRedirectionViewHandler.java index 17247dc..22aaccb 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/framework/FaceletRedirectionViewHandler.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/common/framework/FaceletRedirectionViewHandler.java @@ -62,10 +62,27 @@ public class FaceletRedirectionViewHandler extends FaceletViewHandler { public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException { long monitorId = HibernatePerformanceMonitor.get().start(); super.renderView(context, viewToRender); - HibernatePerformanceMonitor.get().stop(monitorId, "URL " + viewToRender.getViewId()); + HibernatePerformanceMonitor.get().stop(monitorId, "URL " + getURL(viewToRender)); }
- protected void handleRnderException(FacesContext context, Exception ex) throws IOException, ELException, + private String getURL(UIViewRoot viewToRender) { + StringBuilder results = new StringBuilder(viewToRender.getViewId()); + + boolean first = true; + for (Map.Entry<String, Object> urlParam : viewToRender.getAttributes().entrySet()) { + if (first) { + results.append('?'); + } else { + results.append('&'); + } + results.append(urlParam.getKey() + "=" + urlParam.getValue()); + } + + return results.toString(); + } + + @Override + protected void handleRenderException(FacesContext context, Exception ex) throws IOException, ELException, FacesException { try { if (context.getViewRoot().getViewId().equals("/rhq/common/error.xhtml")) { diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserTrackingFilter.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserTrackingFilter.java index 8b6c03c..6299947 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserTrackingFilter.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/WebUserTrackingFilter.java @@ -13,6 +13,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
import org.rhq.enterprise.gui.legacy.util.SessionUtils; +import org.rhq.enterprise.server.util.HibernatePerformanceMonitor;
public class WebUserTrackingFilter extends BaseFilter {
@@ -23,6 +24,8 @@ public class WebUserTrackingFilter extends BaseFilter { ServletException { HttpServletRequest request = (HttpServletRequest) req;
+ HibernatePerformanceMonitor.get().zeroStats(); + // only record GET requests, resubmitting to POST pages is dangerous String method = request.getMethod(); if (method.equals("GET")) { diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/HibernatePerformanceMonitor.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/HibernatePerformanceMonitor.java index 1215cb0..848a067 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/HibernatePerformanceMonitor.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/HibernatePerformanceMonitor.java @@ -18,14 +18,20 @@ */ package org.rhq.enterprise.server.util;
+import java.lang.management.ManagementFactory; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong;
+import javax.management.MBeanServer; import javax.persistence.EntityManager;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.hibernate.stat.QueryStatistics; +import org.hibernate.stat.Statistics; + +import org.rhq.core.domain.util.PersistenceUtility;
/** * @author Joseph Marques @@ -45,6 +51,15 @@ public class HibernatePerformanceMonitor { return singleton; }
+ public void zeroStats() { + if (log.isDebugEnabled()) { + EntityManager entityManager = LookupUtil.getEntityManager(); + MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer(); + Statistics stats = PersistenceUtility.getStatisticsService(entityManager, platformMBeanServer); + stats.clear(); + } + } + public long start() { if (log.isDebugEnabled()) { EntityManager entityManager = LookupUtil.getEntityManager(); @@ -61,11 +76,38 @@ public class HibernatePerformanceMonitor { if (log.isDebugEnabled()) { HibernateStatisticsStopWatch watch = watches.remove(id); if (watch == null) { - // could happen if debugging was turned on and the start() call was already skipped - return; + return; // could happen if debugging was turned on and the start() call was already skipped } watch.stop(); - log.debug(watch.toString() + (logPrefix == null ? "(unknown)" : " for " + logPrefix + " ")); + + String cause = ""; + if (watch.getQueryExecutions() != 0) { + if ((watch.getConnects() / (double) (watch.getEntityLoads() + watch.getQueryExecutions())) >= 5.0) { + cause = "(N+1 issue?) ";// might indicate need for LEFT JOIN FETCHes + } + if ((watch.getTransations() / (double) watch.getQueryExecutions()) >= 5.0) { + cause = "(xaction nesting?) "; // might indicate excessive @REQUIRES_NEW + } else if (watch.getTransations() > 10) { + cause = "(too many xactions?"; + } + } + if (watch.getTime() > 3000) { + cause = "(slowness?) "; // might indicate inefficient query or table contention + } + + String callingContext = " for " + (logPrefix == null ? "(unknown)" : logPrefix); + log.debug(watch.toString() + cause + callingContext); + + if (logPrefix.contains("URL")) { + String[] queries = watch.getStats().getQueries(); + for (int i = 0; i < queries.length; i++) { + String query = queries[i]; + QueryStatistics queryStats = watch.getStats().getQueryStatistics(query); + log.debug("queryString[" + i + "]=" + queries[i]); + log.debug("queryStats[" + i + "=" + queryStats); + } + //watch.getStats().logSummary(); + } } }
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/HibernateStatisticsStopWatch.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/HibernateStatisticsStopWatch.java index 5ca8470..7eb62da 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/HibernateStatisticsStopWatch.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/HibernateStatisticsStopWatch.java @@ -34,10 +34,10 @@ public class HibernateStatisticsStopWatch {
private Statistics stats;
- long queryExecutions; - long transations; - long entityLoads; - long connects; + long queryExecutions; // Get global number of executed queries + long transations; // The number of transactions we know to have completed + long entityLoads; // Get global number of entity loads + long connects; // Get the global number of connections asked by the sessions long time;
public HibernateStatisticsStopWatch(EntityManager entityManager) { @@ -61,6 +61,30 @@ public class HibernateStatisticsStopWatch { time += System.currentTimeMillis(); }
+ public Statistics getStats() { + return stats; + } + + public long getQueryExecutions() { + return queryExecutions; + } + + public long getTransations() { + return transations; + } + + public long getEntityLoads() { + return entityLoads; + } + + public long getConnects() { + return connects; + } + + public long getTime() { + return time; + } + public String toString() { return "HibernateStats" // + "[ queries=" + queryExecutions //
commit d0d27d83e1e961d591b674e7c4a80e6adf2981e8 Author: Joseph Marques joseph@redhat.com Date: Fri Mar 26 03:11:37 2010 -0400
BZ 577109 - fix for partial-page requests not properly recovering from view exceptions
during the authentication action, test whether we've "bookmarked" an ajax request; if so, redirect to the URLs in the web user preferences stored by WebUserTrackingFilter;
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/authentication/AuthenticateUserAction.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/authentication/AuthenticateUserAction.java index 62e9518..c314189 100644 --- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/authentication/AuthenticateUserAction.java +++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/authentication/AuthenticateUserAction.java @@ -145,6 +145,13 @@ public class AuthenticateUserAction extends TilesAction { if ((url == null) || url.equals("/Logout.do")) { url = URL_DASHBOARD; } + if (url.toLowerCase().indexOf("ajax") != -1) { + // we can't return to a URL that was a partial page request + // because the view no longer exists, and will blow up. + // instead, redirect back to the last saved URL + url = webUser.getWebPreferences().getLastVisitedURL(2); + System.out.println("Bypassing partial-page with " + url); + }
af = new ActionForward(url); }
rhq-commits@lists.fedorahosted.org