/* * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * Nuxeo - initial API and implementation * * $Id$ */ package org.nuxeo.ecm.core.management.events; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.nuxeo.ecm.core.event.impl.EventListenerDescriptor; /** * Helper class to store statistics about listeners calls. * * @author Thierry Delprat */ public class EventStatsHolder { protected static boolean collectAsyncHandlersExecTime = false; protected static boolean collectSyncHandlersExecTime = false; protected static Map<String, CallStat> syncStats = new HashMap<String, CallStat>(); protected static Map<String, CallStat> aSyncStats = new HashMap<String, CallStat>(); private EventStatsHolder() { } public static boolean isCollectAsyncHandlersExecTime() { return collectAsyncHandlersExecTime; } public static void setCollectAsyncHandlersExecTime(boolean collectAsyncHandlersExecTime) { EventStatsHolder.collectAsyncHandlersExecTime = collectAsyncHandlersExecTime; } public static boolean isCollectSyncHandlersExecTime() { return collectSyncHandlersExecTime; } public static void setCollectSyncHandlersExecTime(boolean collectSyncHandlersExecTime) { EventStatsHolder.collectSyncHandlersExecTime = collectSyncHandlersExecTime; } /** * @since 5.6 */ public static void clearStats() { synchronized (aSyncStats) { EventStatsHolder.aSyncStats.clear(); } } public static void logAsyncExec(EventListenerDescriptor desc, long delta) { if (!collectAsyncHandlersExecTime) { return; } String name = desc.getName(); synchronized (aSyncStats) { CallStat stat = aSyncStats.get(name); if (stat == null) { String label = desc.asPostCommitListener().getClass().getSimpleName(); if (desc.getIsAsync()) { label += "(async)"; } else { label += "(sync)"; } stat = new CallStat(label); aSyncStats.put(name, stat); } stat.update(delta); } } public static void logSyncExec(EventListenerDescriptor desc, long delta) { if (!collectSyncHandlersExecTime) { return; } String name = desc.getName(); synchronized (syncStats) { CallStat stat = syncStats.get(name); if (stat == null) { String label = desc.asEventListener().getClass().getSimpleName(); stat = new CallStat(label); syncStats.put(name, stat); } stat.update(delta); } } public static String getAsyncHandlersExecTime() { return getStringSummary(aSyncStats); } /** * @since 5.6 */ public static Map<String, CallStat> getAsyncHandlersCallStats() { return Collections.unmodifiableMap(aSyncStats); } public static String getSyncHandlersExecTime() { return getStringSummary(syncStats); } /** * @since 5.6 */ public static Map<String, CallStat> getSyncHandlersCallStats() { return Collections.unmodifiableMap(syncStats); } protected static String getStringSummary(Map<String, CallStat> stats) { StringBuffer sb = new StringBuffer(); synchronized (stats) { long totalTime = 0; for (String name : stats.keySet()) { totalTime += stats.get(name).getAccumulatedTime(); } for (String name : stats.keySet()) { CallStat stat = stats.get(name); sb.append(name); sb.append(" - "); sb.append(stat.getLabel()); sb.append(" - "); sb.append(stat.getCallCount()); sb.append(" calls - "); sb.append(stat.getAccumulatedTime()); sb.append("ms - "); String pcent = String.format("%.2f", 100.0 * stat.getAccumulatedTime() / totalTime); sb.append(pcent); sb.append("%\n"); } } return sb.toString(); } public static void resetHandlersExecTime() { synchronized (syncStats) { syncStats = new HashMap<String, CallStat>(); } synchronized (aSyncStats) { aSyncStats = new HashMap<String, CallStat>(); } } }