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 */ 021package com.unboundid.ldap.sdk; 022 023 024 025import java.io.Serializable; 026import java.util.concurrent.atomic.AtomicLong; 027 028import com.unboundid.util.Mutable; 029import com.unboundid.util.ThreadSafety; 030import 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) 072public 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}