001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.varia.stats;
023:
024: import org.jboss.ejb.plugins.cmp.jdbc2.schema.Cache;
025: import org.jboss.logging.Logger;
026: import org.jboss.system.ServiceMBeanSupport;
027:
028: import javax.management.ObjectName;
029:
030: /**
031: * @jmx:mbean extends="org.jboss.system.ServiceMBean"
032: *
033: * @author <a href="mailto:alex@jboss.org">Alexey Loubyansky</a>
034: * @version <tt>$Revision: 57210 $</tt>
035: */
036: public class CacheListener extends ServiceMBeanSupport implements
037: Cache.Listener, CacheListenerMBean {
038: private static final Logger log = Logger
039: .getLogger(CacheListener.class);
040:
041: private ObjectName statsCollector;
042: private ObjectName cacheName;
043: private String tableName;
044:
045: /**
046: * @jmx.managed-attribute
047: */
048: public ObjectName getStatsCollector() {
049: return statsCollector;
050: }
051:
052: /**
053: * @jmx.managed-attribute
054: */
055: public void setStatsCollector(ObjectName statsCollector) {
056: this .statsCollector = statsCollector;
057: }
058:
059: /**
060: * @jmx.managed-attribute
061: */
062: public ObjectName getCacheName() {
063: return cacheName;
064: }
065:
066: /**
067: * @jmx.managed-attribute
068: */
069: public void setCacheName(ObjectName cacheName) {
070: this .cacheName = cacheName;
071: }
072:
073: public void startService() throws Exception {
074: tableName = cacheName.getKeyProperty("table");
075: getServer().invoke(cacheName, "registerListener",
076: new Object[] { this },
077: new String[] { Cache.Listener.class.getName() });
078: }
079:
080: // Cache.Listener implementation
081:
082: public void contention(int partitionIndex, long time) {
083: try {
084: StatisticalItem item = new ContentionStats(tableName,
085: partitionIndex, time);
086: server.invoke(statsCollector, "addStatisticalItem",
087: new Object[] { item },
088: new String[] { StatisticalItem.class.getName() });
089: } catch (Exception e) {
090: log.error("Failed to add invocation.", e);
091: }
092: }
093:
094: public void eviction(int partitionIndex, Object pk, int size) {
095: try {
096: StatisticalItem item = new EvictionStats(tableName,
097: partitionIndex, pk);
098: server.invoke(statsCollector, "addStatisticalItem",
099: new Object[] { item },
100: new String[] { StatisticalItem.class.getName() });
101: } catch (Exception e) {
102: log.error("Failed to add invocation.", e);
103: }
104: }
105:
106: public void hit(int partitionIndex) {
107: try {
108: StatisticalItem item = new HitStats(tableName,
109: partitionIndex);
110: server.invoke(statsCollector, "addStatisticalItem",
111: new Object[] { item },
112: new String[] { StatisticalItem.class.getName() });
113: } catch (Exception e) {
114: log.error("Failed to add invocation.", e);
115: }
116: }
117:
118: public void miss(int partitionIndex) {
119: try {
120: StatisticalItem item = new MissStats(tableName,
121: partitionIndex);
122: server.invoke(statsCollector, "addStatisticalItem",
123: new Object[] { item },
124: new String[] { StatisticalItem.class.getName() });
125: } catch (Exception e) {
126: log.error("Failed to add invocation.", e);
127: }
128: }
129:
130: public static class HitStats extends AbstractStatisticalItem {
131: public static final String NAME = "Cache Hits Per Transaction";
132:
133: private final String tableName;
134: private final int partitionIndex;
135:
136: public HitStats(String name, int partitionIndex) {
137: super (NAME);
138: value = name + partitionIndex;
139: this .tableName = name;
140: this .partitionIndex = partitionIndex;
141: }
142:
143: public String getTableName() {
144: return tableName;
145: }
146:
147: public int getPartitionIndex() {
148: return partitionIndex;
149: }
150: }
151:
152: public static class MissStats extends AbstractStatisticalItem {
153: public static final String NAME = "Cache Misses Per Transaction";
154:
155: public MissStats(String name, int partitionIndex) {
156: super (NAME);
157: value = name;
158: }
159: }
160:
161: public static class ContentionStats extends AbstractStatisticalItem {
162: public static final String NAME = "Cache Contention Statistics Per Transaction";
163:
164: private long maxContentionTime;
165: private long contentionTimeTotal;
166:
167: public ContentionStats(String name, int partitionIndex, long ms) {
168: super (NAME);
169: value = name;
170: contentionTimeTotal = maxContentionTime = ms;
171: }
172:
173: public void merge(StatisticalItem item) {
174: super .merge(item);
175:
176: ContentionStats cs = (ContentionStats) item;
177: if (cs.maxContentionTime > maxContentionTime) {
178: maxContentionTime = cs.maxContentionTime;
179: }
180: contentionTimeTotal += cs.contentionTimeTotal;
181: }
182:
183: public long getContentionTimeTotal() {
184: return contentionTimeTotal;
185: }
186:
187: public long getMaxContentionTime() {
188: return maxContentionTime;
189: }
190: }
191:
192: public static class EvictionStats extends AbstractStatisticalItem {
193: public static final String NAME = "Cache Eviction Statistics Per Transaction";
194:
195: private final String tableName;
196: private final Object pk;
197:
198: public EvictionStats(String tableName, int partitionIndex,
199: Object pk) {
200: super (NAME);
201: value = tableName;
202:
203: this .tableName = tableName;
204: this .pk = pk;
205: }
206:
207: public String getTableName() {
208: return tableName;
209: }
210:
211: public Object getPk() {
212: return pk;
213: }
214: }
215: }
|