001/* 002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 * 009 * Contributors: 010 * Nuxeo - initial API and implementation 011 * 012 * $Id$ 013 */ 014package org.nuxeo.ecm.core.management.events; 015 016import java.util.Collections; 017import java.util.HashMap; 018import java.util.Map; 019 020import org.nuxeo.ecm.core.event.impl.EventListenerDescriptor; 021 022/** 023 * Helper class to store statistics about listeners calls. 024 * 025 * @author Thierry Delprat 026 */ 027public class EventStatsHolder { 028 029 protected static boolean collectAsyncHandlersExecTime = false; 030 031 protected static boolean collectSyncHandlersExecTime = false; 032 033 protected static Map<String, CallStat> syncStats = new HashMap<String, CallStat>(); 034 035 protected static Map<String, CallStat> aSyncStats = new HashMap<String, CallStat>(); 036 037 private EventStatsHolder() { 038 } 039 040 public static boolean isCollectAsyncHandlersExecTime() { 041 return collectAsyncHandlersExecTime; 042 } 043 044 public static void setCollectAsyncHandlersExecTime(boolean collectAsyncHandlersExecTime) { 045 EventStatsHolder.collectAsyncHandlersExecTime = collectAsyncHandlersExecTime; 046 } 047 048 public static boolean isCollectSyncHandlersExecTime() { 049 return collectSyncHandlersExecTime; 050 } 051 052 public static void setCollectSyncHandlersExecTime(boolean collectSyncHandlersExecTime) { 053 EventStatsHolder.collectSyncHandlersExecTime = collectSyncHandlersExecTime; 054 } 055 056 /** 057 * @since 5.6 058 */ 059 public static void clearStats() { 060 synchronized (aSyncStats) { 061 EventStatsHolder.aSyncStats.clear(); 062 } 063 } 064 065 public static void logAsyncExec(EventListenerDescriptor desc, long delta) { 066 if (!collectAsyncHandlersExecTime) { 067 return; 068 } 069 String name = desc.getName(); 070 synchronized (aSyncStats) { 071 CallStat stat = aSyncStats.get(name); 072 if (stat == null) { 073 String label = desc.asPostCommitListener().getClass().getSimpleName(); 074 if (desc.getIsAsync()) { 075 label += "(async)"; 076 } else { 077 label += "(sync)"; 078 } 079 stat = new CallStat(label); 080 aSyncStats.put(name, stat); 081 } 082 stat.update(delta); 083 } 084 } 085 086 public static void logSyncExec(EventListenerDescriptor desc, long delta) { 087 if (!collectSyncHandlersExecTime) { 088 return; 089 } 090 String name = desc.getName(); 091 synchronized (syncStats) { 092 CallStat stat = syncStats.get(name); 093 if (stat == null) { 094 String label = desc.asEventListener().getClass().getSimpleName(); 095 stat = new CallStat(label); 096 syncStats.put(name, stat); 097 } 098 stat.update(delta); 099 } 100 } 101 102 public static String getAsyncHandlersExecTime() { 103 return getStringSummary(aSyncStats); 104 } 105 106 /** 107 * @since 5.6 108 */ 109 public static Map<String, CallStat> getAsyncHandlersCallStats() { 110 return Collections.unmodifiableMap(aSyncStats); 111 } 112 113 public static String getSyncHandlersExecTime() { 114 return getStringSummary(syncStats); 115 } 116 117 /** 118 * @since 5.6 119 */ 120 public static Map<String, CallStat> getSyncHandlersCallStats() { 121 return Collections.unmodifiableMap(syncStats); 122 } 123 124 protected static String getStringSummary(Map<String, CallStat> stats) { 125 StringBuffer sb = new StringBuffer(); 126 synchronized (stats) { 127 128 long totalTime = 0; 129 for (String name : stats.keySet()) { 130 totalTime += stats.get(name).getAccumulatedTime(); 131 } 132 133 for (String name : stats.keySet()) { 134 CallStat stat = stats.get(name); 135 sb.append(name); 136 sb.append(" - "); 137 sb.append(stat.getLabel()); 138 sb.append(" - "); 139 sb.append(stat.getCallCount()); 140 sb.append(" calls - "); 141 sb.append(stat.getAccumulatedTime()); 142 sb.append("ms - "); 143 String pcent = String.format("%.2f", 100.0 * stat.getAccumulatedTime() / totalTime); 144 sb.append(pcent); 145 sb.append("%\n"); 146 } 147 } 148 return sb.toString(); 149 } 150 151 public static void resetHandlersExecTime() { 152 synchronized (syncStats) { 153 syncStats = new HashMap<String, CallStat>(); 154 } 155 synchronized (aSyncStats) { 156 aSyncStats = new HashMap<String, CallStat>(); 157 } 158 } 159 160}