001 /*
002 * Copyright 2009-2014 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2009-2014 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021 package com.unboundid.ldap.sdk;
022
023
024
025 import java.io.Serializable;
026 import java.util.concurrent.atomic.AtomicLong;
027
028 import com.unboundid.util.Mutable;
029 import com.unboundid.util.ThreadSafety;
030 import com.unboundid.util.ThreadSafetyLevel;
031
032
033
034 /**
035 * This class provides a data structure with information about usage of an LDAP
036 * connection pool. Calls to update statistics maintained by this class are
037 * threadsafe, but attempts to access different statistics may not be consistent
038 * if operations may be in progress in the connection pool.
039 * <BR><BR>
040 * The set of statistics maintained for connection pools include:
041 * <UL>
042 * <LI>The current number of connections that are available within the
043 * pool.</LI>
044 * <LI>The maximum number of connections that may be available within the
045 * pool.</LI>
046 * <LI>The total number of connections that have been successfully checked out
047 * of the pool.</LI>
048 * <LI>The number of connections that have been successfully checked out of
049 * of the pool without needing to wait for a connection to become
050 * available.
051 * <LI>The number of connections that have been successfully checked out of
052 * the pool after waiting for a connection to become available.</LI>
053 * <LI>The number of connections that have been successfully checked out of
054 * the pool after creating a new connection to service the request.</LI>
055 * <LI>The number of failed attempts to check a connection out of the
056 * pool.</LI>
057 * <LI>The number of connections that have been released back to the pool as
058 * valid.</LI>
059 * <LI>The number of connections that have been closed as defunct.</LI>
060 * <LI>The number of connections that have been closed as expired (i.e., that
061 * had been established for the maximum connection age).</LI>
062 * <LI>The number of connections that have been closed as unneeded (because
063 * the pool already had the maximum number of available connections).</LI>
064 * <LI>The number of successful attempts to create a new connection for use in
065 * the pool.</LI>
066 * <LI>The number of failed attempts to create a new connection for use in the
067 * pool.</LI>
068 * </UL>
069 */
070 @Mutable()
071 @ThreadSafety(level=ThreadSafetyLevel.MOSTLY_THREADSAFE)
072 public final class LDAPConnectionPoolStatistics
073 implements Serializable
074 {
075 /**
076 * The serial version UID for this serializable class.
077 */
078 private static final long serialVersionUID = 1493039391352814874L;
079
080
081
082 // The number of connections that have been closed as defunct.
083 private final AtomicLong numConnectionsClosedDefunct;
084
085 // The number of connections that have been closed because they were expired.
086 private final AtomicLong numConnectionsClosedExpired;
087
088 // The number of connections that have been closed because they were no longer
089 // needed.
090 private final AtomicLong numConnectionsClosedUnneeded;
091
092 // The number of failed attempts to check out a connection from the pool.
093 private final AtomicLong numFailedCheckouts;
094
095 // The number of failed attempts to create a connection for use in the pool.
096 private final AtomicLong numFailedConnectionAttempts;
097
098 // The number of valid connections released back to the pool.
099 private final AtomicLong numReleasedValid;
100
101 // The number of successful attempts to check out a connection from the pool.
102 private final AtomicLong numSuccessfulCheckouts;
103
104 // The number of successful checkout attempts that retrieved a connection from
105 // the pool after waiting for it to become available.
106 private final AtomicLong numSuccessfulCheckoutsAfterWait;
107
108 // The number of successful checkout attempts that had to create a new
109 // connection because none were available.
110 private final AtomicLong numSuccessfulCheckoutsNewConnection;
111
112 // The number of successful checkout attempts that were able to take an
113 // existing connection without waiting.
114 private final AtomicLong numSuccessfulCheckoutsWithoutWait;
115
116 // The number successful attempts to create a connection for use in the pool.
117 private final AtomicLong numSuccessfulConnectionAttempts;
118
119 // The connection pool with which these statistics are associated.
120 private final AbstractConnectionPool pool;
121
122
123
124 /**
125 * Creates a new instance of this LDAP connection pool statistics object. All
126 * of the counts will be initialized to zero.
127 *
128 * @param pool The connection pool with which these statistics are
129 * associated.
130 */
131 public LDAPConnectionPoolStatistics(final AbstractConnectionPool pool)
132 {
133 this.pool = pool;
134
135 numSuccessfulConnectionAttempts = new AtomicLong(0L);
136 numFailedConnectionAttempts = new AtomicLong(0L);
137 numConnectionsClosedDefunct = new AtomicLong(0L);
138 numConnectionsClosedExpired = new AtomicLong(0L);
139 numConnectionsClosedUnneeded = new AtomicLong(0L);
140 numSuccessfulCheckouts = new AtomicLong(0L);
141 numSuccessfulCheckoutsAfterWait = new AtomicLong(0L);
142 numSuccessfulCheckoutsNewConnection = new AtomicLong(0L);
143 numSuccessfulCheckoutsWithoutWait = new AtomicLong(0L);
144 numFailedCheckouts = new AtomicLong(0L);
145 numReleasedValid = new AtomicLong(0L);
146 }
147
148
149
150 /**
151 * Resets all counters back to zero.
152 */
153 public void reset()
154 {
155 numSuccessfulConnectionAttempts.set(0L);
156 numFailedConnectionAttempts.set(0L);
157 numConnectionsClosedDefunct.set(0L);
158 numConnectionsClosedExpired.set(0L);
159 numConnectionsClosedUnneeded.set(0L);
160 numSuccessfulCheckouts.set(0L);
161 numSuccessfulCheckoutsAfterWait.set(0L);
162 numSuccessfulCheckoutsNewConnection.set(0L);
163 numSuccessfulCheckoutsWithoutWait.set(0L);
164 numFailedCheckouts.set(0L);
165 numReleasedValid.set(0L);
166 }
167
168
169
170 /**
171 * Retrieves the number of connections that have been successfully created for
172 * use in conjunction with the connection pool.
173 *
174 * @return The number of connections that have been created for use in
175 * conjunction with the connection pool.
176 */
177 public long getNumSuccessfulConnectionAttempts()
178 {
179 return numSuccessfulConnectionAttempts.get();
180 }
181
182
183
184 /**
185 * Increments the number of connections that have been successfully created
186 * for use in conjunction with the connection pool.
187 */
188 void incrementNumSuccessfulConnectionAttempts()
189 {
190 numSuccessfulConnectionAttempts.incrementAndGet();
191 }
192
193
194
195 /**
196 * Retrieves the number of failed attempts to create a connection for use in
197 * the connection pool.
198 *
199 * @return The number of failed attempts to create a connection for use in
200 * the connection pool.
201 */
202 public long getNumFailedConnectionAttempts()
203 {
204 return numFailedConnectionAttempts.get();
205 }
206
207
208
209 /**
210 * Increments the number of failed attempts to create a connection for use in
211 * the connection pool.
212 */
213 void incrementNumFailedConnectionAttempts()
214 {
215 numFailedConnectionAttempts.incrementAndGet();
216 }
217
218
219
220 /**
221 * Retrieves the number of connections that have been closed as defunct (i.e.,
222 * they are no longer believed to be valid).
223 *
224 * @return The number of connections that have been closed as defunct.
225 */
226 public long getNumConnectionsClosedDefunct()
227 {
228 return numConnectionsClosedDefunct.get();
229 }
230
231
232
233 /**
234 * Increments the number of connections that have been closed as defunct.
235 */
236 void incrementNumConnectionsClosedDefunct()
237 {
238 numConnectionsClosedDefunct.incrementAndGet();
239 }
240
241
242
243 /**
244 * Retrieves the number of connections that have been closed as expired (i.e.,
245 * they have been established for longer than the maximum connection age for
246 * the pool).
247 *
248 * @return The number of connections that have been closed as expired.
249 */
250 public long getNumConnectionsClosedExpired()
251 {
252 return numConnectionsClosedExpired.get();
253 }
254
255
256
257 /**
258 * Increments the number of connections that have been closed as expired.
259 */
260 void incrementNumConnectionsClosedExpired()
261 {
262 numConnectionsClosedExpired.incrementAndGet();
263 }
264
265
266
267 /**
268 * Retrieves the number of connections that have been closed as unneeded
269 * (i.e., they were created in response to heavy load but are no longer needed
270 * to meet the current load, or they were closed when the pool was closed).
271 *
272 * @return The number of connections that have been closed as unneeded.
273 */
274 public long getNumConnectionsClosedUnneeded()
275 {
276 return numConnectionsClosedUnneeded.get();
277 }
278
279
280
281 /**
282 * Increments the number of connections that have been closed as unneeded.
283 */
284 void incrementNumConnectionsClosedUnneeded()
285 {
286 numConnectionsClosedUnneeded.incrementAndGet();
287 }
288
289
290
291 /**
292 * Retrieves the number of successful attempts to check out a connection from
293 * the pool (including connections checked out for internal use by operations
294 * processed as part of the pool).
295 *
296 * @return The number of successful attempts to check out a connection from
297 * the pool.
298 */
299 public long getNumSuccessfulCheckouts()
300 {
301 return numSuccessfulCheckouts.get();
302 }
303
304
305
306 /**
307 * Retrieves the number of successful attempts to check out a connection from
308 * the pool that were able to obtain an existing connection without waiting.
309 *
310 * @return The number of successful attempts to check out a connection from
311 * the pool that were able to obtain an existing connection without
312 * waiting.
313 */
314 public long getNumSuccessfulCheckoutsWithoutWaiting()
315 {
316 return numSuccessfulCheckoutsWithoutWait.get();
317 }
318
319
320
321 /**
322 * Retrieves the number of successful attempts to check out a connection from
323 * the pool that had to wait for a connection to become available.
324 *
325 * @return The number of successful attempts to check out a connection from
326 * the pool that had to wait for a connection to become available.
327 */
328 public long getNumSuccessfulCheckoutsAfterWaiting()
329 {
330 return numSuccessfulCheckoutsAfterWait.get();
331 }
332
333
334
335 /**
336 * Retrieves the number of successful attempts to check out a connection from
337 * the pool that had to create a new connection because no existing
338 * connections were available.
339 *
340 * @return The number of successful attempts to check out a connection from
341 * the pool that had to create a new connection because no existing
342 * connections were available.
343 */
344 public long getNumSuccessfulCheckoutsNewConnection()
345 {
346 return numSuccessfulCheckoutsNewConnection.get();
347 }
348
349
350
351 /**
352 * Increments the number of successful attempts to check out a connection from
353 * the pool without waiting.
354 */
355 void incrementNumSuccessfulCheckoutsWithoutWaiting()
356 {
357 numSuccessfulCheckouts.incrementAndGet();
358 numSuccessfulCheckoutsWithoutWait.incrementAndGet();
359 }
360
361
362
363 /**
364 * Increments the number of successful attempts to check out a connection from
365 * the pool after waiting.
366 */
367 void incrementNumSuccessfulCheckoutsAfterWaiting()
368 {
369 numSuccessfulCheckouts.incrementAndGet();
370 numSuccessfulCheckoutsAfterWait.incrementAndGet();
371 }
372
373
374
375 /**
376 * Increments the number of successful attempts to check out a connection from
377 * the pool after creating a new connection.
378 */
379 void incrementNumSuccessfulCheckoutsNewConnection()
380 {
381 numSuccessfulCheckouts.incrementAndGet();
382 numSuccessfulCheckoutsNewConnection.incrementAndGet();
383 }
384
385
386
387 /**
388 * Retrieves the number of failed attempts to check out a connection from
389 * the pool (including connections checked out for internal use by operations
390 * processed as part of the pool).
391 *
392 * @return The number of failed attempts to check out a connection from
393 * the pool.
394 */
395 public long getNumFailedCheckouts()
396 {
397 return numFailedCheckouts.get();
398 }
399
400
401
402 /**
403 * Increments the number of failed attempts to check out a connection from
404 * the pool.
405 */
406 void incrementNumFailedCheckouts()
407 {
408 numFailedCheckouts.incrementAndGet();
409 }
410
411
412
413 /**
414 * Retrieves the number of times a valid, usable connection has been released
415 * back to the pool after being checked out (including connections checked out
416 * for internal use by operations processed within the pool).
417 *
418 * @return The number of times a valid connection has been released back to
419 * the pool.
420 */
421 public long getNumReleasedValid()
422 {
423 return numReleasedValid.get();
424 }
425
426
427
428 /**
429 * Increments the number of times a valid, usable connection has been released
430 * back to the pool.
431 */
432 void incrementNumReleasedValid()
433 {
434 numReleasedValid.incrementAndGet();
435 }
436
437
438
439 /**
440 * Retrieves the number of connections currently available for use in the
441 * pool, if that information is available.
442 *
443 * @return The number of connections currently available for use in the pool,
444 * or -1 if that is not applicable for the associated connection pool
445 * implementation.
446 */
447 public int getNumAvailableConnections()
448 {
449 return pool.getCurrentAvailableConnections();
450 }
451
452
453
454 /**
455 * Retrieves the maximum number of connections that may be available in the
456 * pool at any time, if that information is available.
457 *
458 * @return The maximum number of connections that may be available in the
459 * pool at any time, or -1 if that is not applicable for the
460 * associated connection pool implementation.
461 */
462 public int getMaximumAvailableConnections()
463 {
464 return pool.getMaximumAvailableConnections();
465 }
466
467
468
469 /**
470 * Retrieves a string representation of this LDAP connection pool statistics
471 * object.
472 *
473 * @return A string representation of this LDAP connection pool statistics
474 * object.
475 */
476 @Override()
477 public String toString()
478 {
479 final StringBuilder buffer = new StringBuilder();
480 toString(buffer);
481 return buffer.toString();
482 }
483
484
485
486 /**
487 * Appends a string representation of this LDAP connection pool statistics
488 * object to the provided buffer.
489 *
490 * @param buffer The buffer to which the string representation should be
491 * appended.
492 */
493 public void toString(final StringBuilder buffer)
494 {
495 final long availableConns = pool.getCurrentAvailableConnections();
496 final long maxConns = pool.getMaximumAvailableConnections();
497 final long successfulConns = numSuccessfulConnectionAttempts.get();
498 final long failedConns = numFailedConnectionAttempts.get();
499 final long connsClosedDefunct = numConnectionsClosedDefunct.get();
500 final long connsClosedExpired = numConnectionsClosedExpired.get();
501 final long connsClosedUnneeded = numConnectionsClosedUnneeded.get();
502 final long successfulCheckouts = numSuccessfulCheckouts.get();
503 final long failedCheckouts = numFailedCheckouts.get();
504 final long releasedValid = numReleasedValid.get();
505
506 buffer.append("LDAPConnectionPoolStatistics(numAvailableConnections=");
507 buffer.append(availableConns);
508 buffer.append(", maxAvailableConnections=");
509 buffer.append(maxConns);
510 buffer.append(", numSuccessfulConnectionAttempts=");
511 buffer.append(successfulConns);
512 buffer.append(", numFailedConnectionAttempts=");
513 buffer.append(failedConns);
514 buffer.append(", numConnectionsClosedDefunct=");
515 buffer.append(connsClosedDefunct);
516 buffer.append(", numConnectionsClosedExpired=");
517 buffer.append(connsClosedExpired);
518 buffer.append(", numConnectionsClosedUnneeded=");
519 buffer.append(connsClosedUnneeded);
520 buffer.append(", numSuccessfulCheckouts=");
521 buffer.append(successfulCheckouts);
522 buffer.append(", numFailedCheckouts=");
523 buffer.append(failedCheckouts);
524 buffer.append(", numReleasedValid=");
525 buffer.append(releasedValid);
526 buffer.append(')');
527 }
528 }