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: */
004: package com.tc.management.beans.tx;
005:
006: import java.util.HashMap;
007: import java.util.Iterator;
008: import java.util.Map;
009:
010: import javax.management.NotCompliantMBeanException;
011: import javax.management.openmbean.CompositeData;
012: import javax.management.openmbean.OpenDataException;
013: import javax.management.openmbean.TabularData;
014:
015: import com.tc.management.AbstractTerracottaMBean;
016: import com.tc.management.opentypes.adapters.ClassCreationCount;
017: import com.tc.management.stats.AggregateInteger;
018:
019: public final class ClientTxMonitor extends AbstractTerracottaMBean
020: implements ClientTxMonitorMBean {
021:
022: final AggregateInteger readTransactions;
023: final AggregateInteger writeTransactions;
024: final AggregateInteger writesPerTransaction;
025: final AggregateInteger modifiedObjectsPerTransaction;
026: final AggregateInteger newObjectsPerTransaction;
027:
028: final AggregateInteger notifiesPerTransaction;
029: final AggregateInteger writesPerObject;
030: final Map objectCreationCountByClass;
031:
032: public ClientTxMonitor() throws NotCompliantMBeanException {
033: super (ClientTxMonitorMBean.class, false);
034: readTransactions = new AggregateInteger(
035: "Client transactions (read)", 100);
036: writeTransactions = new AggregateInteger(
037: "Client transactions (write)", 100);
038: writesPerTransaction = new AggregateInteger(
039: "Writes per transaction (includes Object.notify() calls)",
040: 100);
041: modifiedObjectsPerTransaction = new AggregateInteger(
042: "Objects modified per transaction", 100);
043: newObjectsPerTransaction = new AggregateInteger(
044: "New objects created per transaction", 100);
045: notifiesPerTransaction = new AggregateInteger(
046: "Object.notify() invocations per transaction");
047: writesPerObject = new AggregateInteger(
048: "Modifications per object");
049: objectCreationCountByClass = new HashMap();
050: }
051:
052: public int getReadTransactionCount() {
053: return readTransactions.getN();
054: }
055:
056: public int getReadTransactionRatePerSecond() {
057: return readTransactions.getSampleRate(1000);
058: }
059:
060: public int getWriteTransactionCount() {
061: return writeTransactions.getN();
062: }
063:
064: public int getWriteTransactionRatePerSecond() {
065: return writeTransactions.getSampleRate(1000);
066: }
067:
068: public int getMinWritesPerWriteTransaction() {
069: return writesPerTransaction.getMinimum();
070: }
071:
072: public int getMaxWritesPerWriteTransaction() {
073: return writesPerTransaction.getMaximum();
074: }
075:
076: public int getMaxModifiedObjectsPerTransaction() {
077: return modifiedObjectsPerTransaction.getMaximum();
078: }
079:
080: public int getAvgModifiedObjectsPerTransaction() {
081: return (int) modifiedObjectsPerTransaction.getAverage();
082: }
083:
084: public int getObjectModificationRatePerSecond() {
085: return modifiedObjectsPerTransaction.getSampleRate(1000);
086: }
087:
088: public int getMaxNewObjectsPerTransaction() {
089: return newObjectsPerTransaction.getMaximum();
090: }
091:
092: public int getAvgNewObjectsPerTransaction() {
093: return (int) newObjectsPerTransaction.getAverage();
094: }
095:
096: public int getObjectCreationRatePerSecond() {
097: return newObjectsPerTransaction.getSampleRate(1000);
098: }
099:
100: public int getMaxNotificationsPerTransaction() {
101: return notifiesPerTransaction.getMaximum();
102: }
103:
104: public int getAvgNotificationsPerTransaction() {
105: return (int) notifiesPerTransaction.getAverage();
106: }
107:
108: public int getMaxWritesPerObject() {
109: return writesPerObject.getMaximum();
110: }
111:
112: public int getAvgWritesPerObject() {
113: return (int) writesPerObject.getAverage();
114: }
115:
116: public TabularData getObjectCreationCountByClass()
117: throws OpenDataException {
118: TabularData tabularData = ClassCreationCount
119: .newTabularDataInstance();
120: CompositeData compositeData;
121:
122: synchronized (objectCreationCountByClass) {
123: for (Iterator iter = objectCreationCountByClass.keySet()
124: .iterator(); iter.hasNext();) {
125: Class classNameItemValue = (Class) iter.next();
126: AggregateInteger objectCreationCountItemValue = (AggregateInteger) objectCreationCountByClass
127: .get(classNameItemValue);
128: compositeData = new ClassCreationCount(
129: classNameItemValue.getName(), new Integer(
130: objectCreationCountItemValue.getSum()))
131: .toCompositeData();
132: tabularData.put(compositeData);
133: }
134: }
135: return tabularData;
136: }
137:
138: public synchronized void reset() {
139: readTransactions.reset();
140: writeTransactions.reset();
141: writesPerTransaction.reset();
142: modifiedObjectsPerTransaction.reset();
143: newObjectsPerTransaction.reset();
144: notifiesPerTransaction.reset();
145: writesPerObject.reset();
146: synchronized (objectCreationCountByClass) {
147: objectCreationCountByClass.clear();
148: }
149: }
150:
151: public synchronized void committedReadTransaction() {
152: if (isEnabled())
153: readTransactions.addSample(1);
154: }
155:
156: public synchronized void committedWriteTransaction(
157: final int notifyCount, final int modifiedObjectCount,
158: final int[] writeCountPerObject,
159: final Map newObjectCountByClass) {
160: if (isEnabled()) {
161: writeTransactions.addSample(1);
162: modifiedObjectsPerTransaction
163: .addSample(modifiedObjectCount);
164: notifiesPerTransaction.addSample(notifyCount);
165: int totalWriteCount = 0;
166: for (int i = 0; i < writeCountPerObject.length; i++) {
167: totalWriteCount += writeCountPerObject[i];
168: writesPerObject.addSample(writeCountPerObject[i]);
169: }
170: writesPerTransaction.addSample(totalWriteCount
171: + notifyCount);
172: if (newObjectCountByClass != null
173: && !newObjectCountByClass.isEmpty()) {
174: int totalNewObjectCount = 0;
175: for (Iterator iter = newObjectCountByClass.keySet()
176: .iterator(); iter.hasNext();) {
177: final Class createdObjectClass = (Class) iter
178: .next();
179: final Integer classCreationCount = (Integer) newObjectCountByClass
180: .get(createdObjectClass);
181: synchronized (objectCreationCountByClass) {
182: AggregateInteger instanceCounter = (AggregateInteger) objectCreationCountByClass
183: .get(createdObjectClass);
184: if (instanceCounter == null) {
185: instanceCounter = new AggregateInteger(
186: "Object creation count for class["
187: + createdObjectClass
188: .getName() + "]");
189: objectCreationCountByClass
190: .put(createdObjectClass,
191: instanceCounter);
192: }
193: instanceCounter.addSample(classCreationCount
194: .intValue());
195: totalNewObjectCount += classCreationCount
196: .intValue();
197: }
198: }
199: newObjectsPerTransaction.addSample(totalNewObjectCount);
200: } else {
201: newObjectsPerTransaction.addSample(0);
202: }
203: }
204: }
205: }
|