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.Map;
025import java.util.Map.Entry;
026import java.util.concurrent.ConcurrentHashMap;
027
028import org.nuxeo.ecm.core.event.impl.EventListenerDescriptor;
029
030/**
031 * Helper class to store statistics about listeners calls.
032 *
033 * @author Thierry Delprat
034 * @deprecated since 11.4: superseded by dropwizard metrics
035 */
036@Deprecated(since = "11.4")
037public class EventStatsHolder {
038
039    protected static boolean collectAsyncHandlersExecTime = false;
040
041    protected static boolean collectSyncHandlersExecTime = false;
042
043    protected static Map<String, CallStat> syncStats = new ConcurrentHashMap<>();
044
045    protected static Map<String, CallStat> aSyncStats = new ConcurrentHashMap<>();
046
047    private EventStatsHolder() {
048    }
049
050    public static boolean isCollectAsyncHandlersExecTime() {
051        return collectAsyncHandlersExecTime;
052    }
053
054    public static void setCollectAsyncHandlersExecTime(boolean collectAsyncHandlersExecTime) {
055        EventStatsHolder.collectAsyncHandlersExecTime = collectAsyncHandlersExecTime;
056    }
057
058    public static boolean isCollectSyncHandlersExecTime() {
059        return collectSyncHandlersExecTime;
060    }
061
062    public static void setCollectSyncHandlersExecTime(boolean collectSyncHandlersExecTime) {
063        EventStatsHolder.collectSyncHandlersExecTime = collectSyncHandlersExecTime;
064    }
065
066    /**
067     * @since 5.6
068     */
069    public static void clearStats() {
070        syncStats.clear();
071        aSyncStats.clear();
072    }
073
074    public static void logAsyncExec(EventListenerDescriptor desc, long delta) {
075        if (!collectAsyncHandlersExecTime) {
076            return;
077        }
078        String name = desc.getName();
079        synchronized (aSyncStats) {
080            CallStat stat = aSyncStats.get(name);
081            if (stat == null) {
082                String label = desc.asPostCommitListener().getClass().getSimpleName();
083                if (desc.getIsAsync()) {
084                    label += "(async)";
085                } else {
086                    label += "(sync)";
087                }
088                stat = new CallStat(label);
089                aSyncStats.put(name, stat);
090            }
091            stat.update(delta);
092        }
093    }
094
095    public static void logSyncExec(EventListenerDescriptor desc, long delta) {
096        if (!collectSyncHandlersExecTime) {
097            return;
098        }
099        String name = desc.getName();
100        syncStats.computeIfAbsent(name, k -> new CallStat(desc.asEventListener().getClass().getSimpleName()))
101                 .update(delta);
102    }
103
104    public static String getAsyncHandlersExecTime() {
105        return getStringSummary(aSyncStats);
106    }
107
108    /**
109     * @since 5.6
110     */
111    public static Map<String, CallStat> getAsyncHandlersCallStats() {
112        return Collections.unmodifiableMap(aSyncStats);
113    }
114
115    public static String getSyncHandlersExecTime() {
116        return getStringSummary(syncStats);
117    }
118
119    /**
120     * @since 5.6
121     */
122    public static Map<String, CallStat> getSyncHandlersCallStats() {
123        return Collections.unmodifiableMap(syncStats);
124    }
125
126    protected static String getStringSummary(Map<String, CallStat> stats) {
127        long totalTime = 0;
128        for (CallStat stat : stats.values()) {
129            totalTime += stat.getAccumulatedTime();
130        }
131        if (totalTime == 0) {
132            totalTime = 1;
133        }
134        StringBuilder sb = new StringBuilder();
135        for (Entry<String, CallStat> en : stats.entrySet()) {
136            String name = en.getKey();
137            CallStat stat = en.getValue();
138            sb.append(name);
139            sb.append(" - ");
140            sb.append(stat.getLabel());
141            sb.append(" - ");
142            sb.append(stat.getCallCount());
143            sb.append(" calls - ");
144            sb.append(stat.getAccumulatedTime());
145            sb.append("ms - ");
146            String pcent = String.format("%.2f", 100.0 * stat.getAccumulatedTime() / totalTime);
147            sb.append(pcent);
148            sb.append("%\n");
149        }
150        return sb.toString();
151    }
152
153    public static void resetHandlersExecTime() {
154        clearStats();
155    }
156
157}