001: /*
002: * This software is released under a licence similar to the Apache Software Licence.
003: * See org.logicalcobwebs.proxool.package.html for details.
004: * The latest version is available at http://proxool.sourceforge.net
005: */
006: package org.logicalcobwebs.proxool.admin;
007:
008: import org.apache.commons.logging.Log;
009: import org.apache.commons.logging.LogFactory;
010: import org.logicalcobwebs.proxool.ConnectionPoolDefinitionIF;
011: import org.logicalcobwebs.proxool.ConnectionPoolStatisticsIF;
012: import org.logicalcobwebs.proxool.ProxoolException;
013:
014: import java.util.Collection;
015: import java.util.Date;
016: import java.util.HashMap;
017: import java.util.Iterator;
018: import java.util.List;
019: import java.util.Map;
020: import java.util.StringTokenizer;
021: import java.util.Vector;
022:
023: /**
024: * Provides statistics about the performance of a pool.
025: *
026: * @version $Revision: 1.9 $, $Date: 2006/01/18 14:39:57 $
027: * @author bill
028: * @author $Author: billhorsman $ (current maintainer)
029: * @since Proxool 0.7
030: */
031: public class Admin {
032:
033: private static final Log LOG = LogFactory.getLog(Admin.class);
034:
035: private Log log;
036:
037: private Map statsRollers = new HashMap();
038:
039: private CompositeStatisticsListener compositeStatisticsListener = new CompositeStatisticsListener();
040:
041: /**
042: * @param definition gives access to pool definition
043: * @param definition see {@link org.logicalcobwebs.proxool.ConnectionPoolDefinitionIF#getStatistics definition}
044: */
045: public Admin(ConnectionPoolDefinitionIF definition)
046: throws ProxoolException {
047: log = LogFactory.getLog("org.logicalcobwebs.proxool.stats."
048: + definition.getAlias());
049:
050: StringTokenizer st = new StringTokenizer(definition
051: .getStatistics(), ",");
052: while (st.hasMoreTokens()) {
053: String token = st.nextToken();
054: statsRollers.put(token, new StatsRoller(definition
055: .getAlias(), compositeStatisticsListener, token));
056: }
057:
058: if (definition.getStatisticsLogLevel() != null) {
059: compositeStatisticsListener
060: .addListener(new StatisticsLogger(log, definition
061: .getStatisticsLogLevel()));
062: }
063:
064: }
065:
066: public void addStatisticsListener(
067: StatisticsListenerIF statisticsListener) {
068: this .compositeStatisticsListener
069: .addListener(statisticsListener);
070: }
071:
072: /**
073: * Call this every time an active connection is returned to the pool
074: * @param activeTime how long the connection was active
075: */
076: public void connectionReturned(long activeTime) {
077: try {
078: Iterator i = statsRollers.values().iterator();
079: while (i.hasNext()) {
080: StatsRoller statsRoller = (StatsRoller) i.next();
081: statsRoller.connectionReturned(activeTime);
082: }
083: } catch (Throwable e) {
084: LOG.error(
085: "Stats connectionReturned call failed. Ignoring.",
086: e);
087: }
088: }
089:
090: /**
091: * Call this every time a connection is refused
092: */
093: public void connectionRefused() {
094: try {
095: Iterator i = statsRollers.values().iterator();
096: while (i.hasNext()) {
097: StatsRoller statsRoller = (StatsRoller) i.next();
098: statsRoller.connectionRefused();
099: }
100: } catch (Exception e) {
101: LOG.error("Stats connectionRefused call failed. Ignoring.",
102: e);
103: }
104: }
105:
106: /**
107: * Returns the most recent sample that has completed its period
108: * @return sample (or null if no statistics are complete yet)
109: */
110: public StatisticsIF getStatistics(String token) {
111: try {
112: return ((StatsRoller) statsRollers.get(token))
113: .getCompleteStatistics();
114: } catch (NullPointerException e) {
115: return null;
116: }
117: }
118:
119: /**
120: * Cancels the timer that outputs the stats
121: */
122: public void cancelAll() {
123: Iterator i = statsRollers.values().iterator();
124: while (i.hasNext()) {
125: StatsRoller statsRoller = (StatsRoller) i.next();
126: statsRoller.cancel();
127: }
128: }
129:
130: public StatisticsIF[] getStatistics() {
131: List statistics = new Vector();
132: Iterator i = statsRollers.values().iterator();
133: while (i.hasNext()) {
134: StatsRoller statsRoller = (StatsRoller) i.next();
135: StatisticsIF s = statsRoller.getCompleteStatistics();
136: if (s != null) {
137: statistics.add(s);
138: }
139: }
140: return (StatisticsIF[]) statistics
141: .toArray(new StatisticsIF[statistics.size()]);
142: }
143:
144: /**
145: * Get a new snapshot
146: * @param cps used to help populate the snapshot
147: * @param cpd used to help populate the snapshot
148: * @return snapshot
149: */
150: public static SnapshotIF getSnapshot(
151: ConnectionPoolStatisticsIF cps,
152: ConnectionPoolDefinitionIF cpd, Collection connectionInfos) {
153: Snapshot s = new Snapshot(new Date());
154:
155: s.setDateStarted(cps.getDateStarted());
156: s.setActiveConnectionCount(cps.getActiveConnectionCount());
157: s
158: .setAvailableConnectionCount(cps
159: .getAvailableConnectionCount());
160: s.setOfflineConnectionCount(cps.getOfflineConnectionCount());
161: s.setMaximumConnectionCount(cpd.getMaximumConnectionCount());
162: s.setServedCount(cps.getConnectionsServedCount());
163: s.setRefusedCount(cps.getConnectionsRefusedCount());
164: s.setConnectionInfos(connectionInfos);
165: s.setConnectionCount(cps.getConnectionCount());
166:
167: /*
168: if (s.getActiveConnectionCount() != getCount(s.getConnectionInfos(), ConnectionInfoIF.STATUS_ACTIVE)) {
169: LOG.error("activeCount disparity: " + s.getActiveConnectionCount() + " != " + getCount(s.getConnectionInfos(), ConnectionInfoIF.STATUS_ACTIVE));
170: }
171: if (s.getAvailableConnectionCount() != getCount(s.getConnectionInfos(), ConnectionInfoIF.STATUS_AVAILABLE)) {
172: LOG.error("activeCount disparity: " + s.getAvailableConnectionCount() + " != " + getCount(s.getConnectionInfos(), ConnectionInfoIF.STATUS_AVAILABLE));
173: }
174: if (s.getOfflineConnectionCount() != getCount(s.getConnectionInfos(), ConnectionInfoIF.STATUS_OFFLINE)) {
175: LOG.error("offlineCount disparity: " + s.getOfflineConnectionCount() + " != " + getCount(s.getConnectionInfos(), ConnectionInfoIF.STATUS_OFFLINE));
176: }
177: */
178:
179: return s;
180: }
181:
182: }
183:
184: /*
185: Revision history:
186: $Log: Admin.java,v $
187: Revision 1.9 2006/01/18 14:39:57 billhorsman
188: Unbundled Jakarta's Commons Logging.
189:
190: Revision 1.8 2005/10/02 12:32:01 billhorsman
191: Make connectionCount available to statistics
192:
193: Revision 1.7 2003/10/27 20:26:19 billhorsman
194: connectionReturned() and connectionRefused() calls will now log any errors and continue rather than
195: possibly throwing RuntimeExceptions back to the caller. In principle, stats should not cause problems
196: to the core code. (No evidence of this happening - but it's more robust now.)
197:
198: Revision 1.6 2003/08/30 14:54:04 billhorsman
199: Checkstyle
200:
201: Revision 1.5 2003/03/11 14:51:55 billhorsman
202: more concurrency fixes relating to snapshots
203:
204: Revision 1.4 2003/03/10 23:43:14 billhorsman
205: reapplied checkstyle that i'd inadvertently let
206: IntelliJ change...
207:
208: Revision 1.3 2003/03/10 15:26:50 billhorsman
209: refactoringn of concurrency stuff (and some import
210: optimisation)
211:
212: Revision 1.2 2003/03/03 11:11:58 billhorsman
213: fixed licence
214:
215: Revision 1.1 2003/02/19 23:36:51 billhorsman
216: renamed monitor package to admin
217:
218: Revision 1.8 2003/02/07 15:08:51 billhorsman
219: removed redundant accessor
220:
221: Revision 1.7 2003/02/07 14:16:45 billhorsman
222: support for StatisticsListenerIF
223:
224: Revision 1.6 2003/02/06 17:41:05 billhorsman
225: now uses imported logging
226:
227: Revision 1.5 2003/02/05 00:20:27 billhorsman
228: getSnapshot is now static (because it can be)
229:
230: Revision 1.4 2003/02/04 15:59:49 billhorsman
231: finalize now shuts down StatsRoller timer
232:
233: Revision 1.3 2003/01/31 16:53:21 billhorsman
234: checkstyle
235:
236: Revision 1.2 2003/01/31 16:38:51 billhorsman
237: doc (and removing public modifier for classes where possible)
238:
239: Revision 1.1 2003/01/31 11:35:57 billhorsman
240: improvements to servlet (including connection details)
241:
242: Revision 1.2 2003/01/31 00:28:57 billhorsman
243: now handles multiple statistics
244:
245: Revision 1.1 2003/01/30 17:20:19 billhorsman
246: fixes, improvements and doc
247:
248: */
|