001: /**
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */package com.tc.util;
004:
005: import com.tc.logging.LogLevel;
006: import com.tc.logging.TCLogger;
007: import com.tc.logging.TCLogging;
008:
009: import java.lang.ref.SoftReference;
010: import java.util.Collections;
011: import java.util.Date;
012: import java.util.HashMap;
013: import java.util.Iterator;
014: import java.util.LinkedList;
015: import java.util.List;
016: import java.util.Map;
017:
018: /**
019: * This class can be used while debugging to record some activity based on a key and later can be used to inpect the
020: * activity when something goes wrong. Do note that this class can bloat up the memory and take up a lot of resources.
021: * SoftREferences are used to avoid "OutOfMemory" Errors.
022: */
023: public class ActivityMonitor {
024:
025: private static final TCLogger logger = TCLogging
026: .getLogger(ActivityMonitor.class);
027: private static Map activyMonitors = new HashMap();
028:
029: private final String name;
030: private final Map activityMap = Collections
031: .synchronizedMap(new HashMap());
032: private final boolean softref;
033:
034: static {
035: // Since this is only used when debugging...
036: logger.setLevel(LogLevel.DEBUG);
037: }
038:
039: public ActivityMonitor() {
040: this ("Activity Monitor");
041: }
042:
043: public ActivityMonitor(String name) {
044: this (name, true);
045: }
046:
047: public ActivityMonitor(String name, boolean softref) {
048: this .name = name;
049: this .softref = softref;
050: }
051:
052: public void addActivity(Object id, String what) {
053: if (softref) {
054: addActivitySoftRef(id, what);
055: } else {
056: addActivityNormal(id, what);
057: }
058: }
059:
060: private void addActivitySoftRef(Object id, String what) {
061: synchronized (activityMap) {
062: SoftReference ref = (SoftReference) activityMap.get(id);
063: if (ref == null) {
064: ref = new SoftReference(new LinkedList());
065: activityMap.put(id, ref);
066: }
067: List list = (List) ref.get();
068: if (list == null) {
069: logger.debug(name + " :: GC cleared activity for " + id
070: + "!");
071: list = new LinkedList();
072: list
073: .add("GC cleared activity ! - (" + new Date()
074: + ")");
075: ref = new SoftReference(list);
076: activityMap.put(id, ref);
077: }
078: addActivityList(list, what);
079: }
080: }
081:
082: private void addActivityList(List list, String what) {
083: synchronized (list) {
084: list.add(what + " - " + Thread.currentThread().getName()
085: + " @ " + new Date());
086: try {
087: throw new Exception(" happened at -");
088: } catch (Exception ex) {
089: list.add(ex.getStackTrace());
090: }
091: }
092: }
093:
094: private void addActivityNormal(Object id, String what) {
095: synchronized (activityMap) {
096: List list = (List) activityMap.get(id);
097: if (list == null) {
098: list = new LinkedList();
099: activityMap.put(id, list);
100: }
101: addActivityList(list, what);
102: }
103: }
104:
105: public void printActivityFor(Object id) {
106: if (softref) {
107: printActivityForSoftRef(id);
108: } else {
109: printActivityForNormal(id);
110: }
111: }
112:
113: private void printActivityForSoftRef(Object id) {
114: SoftReference ref = (SoftReference) activityMap.get(id);
115: if (ref == null) {
116: logger.debug(name + " :: No Activity for " + id);
117: return;
118: }
119: List list = (List) ref.get();
120: if (list == null) {
121: logger.debug(name + " :: GC cleared Activity for " + id
122: + " !!!");
123: return;
124:
125: }
126: printActivityForList(list, id);
127: }
128:
129: private void printActivityForNormal(Object id) {
130: List list = (List) activityMap.get(id);
131: if (list == null) {
132: logger.debug(name + " :: No Activity for " + id);
133: return;
134: }
135: printActivityForList(list, id);
136: }
137:
138: private void printActivityForList(List list, Object id) {
139: logger.debug(name + " :: Activity for " + id
140: + " ---- START ----");
141: synchronized (list) {
142: for (Iterator iter = list.iterator(); iter.hasNext();) {
143: Object element = iter.next();
144: if (element instanceof StackTraceElement[]) {
145: StackTraceElement ste[] = (StackTraceElement[]) element;
146: for (int i = 0; i < ste.length; i++) {
147: final String steStr = ste[i].toString();
148: if (steStr.indexOf(this .getClass().getName()) == -1) {
149: logger.debug("\tat " + steStr);
150: }
151: }
152: } else {
153: logger.debug(element + " happened at ");
154: }
155: }
156: logger.debug(name + " :: Activity for " + id
157: + " ---- END ----");
158: }
159: }
160:
161: public void clear() {
162: activityMap.clear();
163: }
164:
165: public static ActivityMonitor getActivityMonitor(String name) {
166: return getActivityMonitor(name, true);
167: }
168:
169: public static ActivityMonitor getActivityMonitor(String name,
170: boolean softref) {
171: synchronized (activyMonitors) {
172: ActivityMonitor monitor = (ActivityMonitor) activyMonitors
173: .get(name);
174: if (monitor == null) {
175: monitor = new ActivityMonitor(name, softref);
176: activyMonitors.put(name, monitor);
177: }
178: return monitor;
179: }
180: }
181: }
|