001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nuxeo - initial API and implementation 018 * 019 * $Id$ 020 */ 021package org.nuxeo.ecm.core.management.events; 022 023import java.util.Collections; 024import java.util.HashMap; 025import java.util.Map; 026 027import org.nuxeo.ecm.core.event.impl.EventListenerDescriptor; 028 029/** 030 * Helper class to store statistics about listeners calls. 031 * 032 * @author Thierry Delprat 033 */ 034public class EventStatsHolder { 035 036 protected static boolean collectAsyncHandlersExecTime = false; 037 038 protected static boolean collectSyncHandlersExecTime = false; 039 040 protected static Map<String, CallStat> syncStats = new HashMap<String, CallStat>(); 041 042 protected static Map<String, CallStat> aSyncStats = new HashMap<String, CallStat>(); 043 044 private EventStatsHolder() { 045 } 046 047 public static boolean isCollectAsyncHandlersExecTime() { 048 return collectAsyncHandlersExecTime; 049 } 050 051 public static void setCollectAsyncHandlersExecTime(boolean collectAsyncHandlersExecTime) { 052 EventStatsHolder.collectAsyncHandlersExecTime = collectAsyncHandlersExecTime; 053 } 054 055 public static boolean isCollectSyncHandlersExecTime() { 056 return collectSyncHandlersExecTime; 057 } 058 059 public static void setCollectSyncHandlersExecTime(boolean collectSyncHandlersExecTime) { 060 EventStatsHolder.collectSyncHandlersExecTime = collectSyncHandlersExecTime; 061 } 062 063 /** 064 * @since 5.6 065 */ 066 public static void clearStats() { 067 synchronized (aSyncStats) { 068 EventStatsHolder.aSyncStats.clear(); 069 } 070 } 071 072 public static void logAsyncExec(EventListenerDescriptor desc, long delta) { 073 if (!collectAsyncHandlersExecTime) { 074 return; 075 } 076 String name = desc.getName(); 077 synchronized (aSyncStats) { 078 CallStat stat = aSyncStats.get(name); 079 if (stat == null) { 080 String label = desc.asPostCommitListener().getClass().getSimpleName(); 081 if (desc.getIsAsync()) { 082 label += "(async)"; 083 } else { 084 label += "(sync)"; 085 } 086 stat = new CallStat(label); 087 aSyncStats.put(name, stat); 088 } 089 stat.update(delta); 090 } 091 } 092 093 public static void logSyncExec(EventListenerDescriptor desc, long delta) { 094 if (!collectSyncHandlersExecTime) { 095 return; 096 } 097 String name = desc.getName(); 098 synchronized (syncStats) { 099 CallStat stat = syncStats.get(name); 100 if (stat == null) { 101 String label = desc.asEventListener().getClass().getSimpleName(); 102 stat = new CallStat(label); 103 syncStats.put(name, stat); 104 } 105 stat.update(delta); 106 } 107 } 108 109 public static String getAsyncHandlersExecTime() { 110 return getStringSummary(aSyncStats); 111 } 112 113 /** 114 * @since 5.6 115 */ 116 public static Map<String, CallStat> getAsyncHandlersCallStats() { 117 return Collections.unmodifiableMap(aSyncStats); 118 } 119 120 public static String getSyncHandlersExecTime() { 121 return getStringSummary(syncStats); 122 } 123 124 /** 125 * @since 5.6 126 */ 127 public static Map<String, CallStat> getSyncHandlersCallStats() { 128 return Collections.unmodifiableMap(syncStats); 129 } 130 131 protected static String getStringSummary(Map<String, CallStat> stats) { 132 StringBuffer sb = new StringBuffer(); 133 synchronized (stats) { 134 135 long totalTime = 0; 136 for (String name : stats.keySet()) { 137 totalTime += stats.get(name).getAccumulatedTime(); 138 } 139 140 for (String name : stats.keySet()) { 141 CallStat stat = stats.get(name); 142 sb.append(name); 143 sb.append(" - "); 144 sb.append(stat.getLabel()); 145 sb.append(" - "); 146 sb.append(stat.getCallCount()); 147 sb.append(" calls - "); 148 sb.append(stat.getAccumulatedTime()); 149 sb.append("ms - "); 150 String pcent = String.format("%.2f", 100.0 * stat.getAccumulatedTime() / totalTime); 151 sb.append(pcent); 152 sb.append("%\n"); 153 } 154 } 155 return sb.toString(); 156 } 157 158 public static void resetHandlersExecTime() { 159 synchronized (syncStats) { 160 syncStats = new HashMap<String, CallStat>(); 161 } 162 synchronized (aSyncStats) { 163 aSyncStats = new HashMap<String, CallStat>(); 164 } 165 } 166 167}