All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.agroal.pool.DefaultMetricsRepository Maven / Gradle / Ivy

There is a newer version: 2.5
Show newest version
package io.agroal.pool;

import java.text.MessageFormat;
import java.time.Duration;
import java.util.Locale;
import java.util.concurrent.atomic.LongAccumulator;
import java.util.concurrent.atomic.LongAdder;

import static java.lang.System.nanoTime;
import static java.time.Duration.ZERO;
import static java.time.Duration.ofNanos;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

/**
 * @author Luis Barreiro
 */
public final class DefaultMetricsRepository implements MetricsRepository {

    private static final String FORMAT_1 = "Connections: {0} created | {1} invalid | {2} reap | {3} flush | {4} destroyed";
    private static final String FORMAT_2 = "Pool: {0} available | {1} active | {2} max | {3} acquired | {4} returned";
    private static final String FORMAT_3 = "Created duration: {0,number,000.000}ms average | {1}ms max | {2}ms total";
    private static final String FORMAT_4 = "Acquire duration: {0,number,000.000}ms average | {1}ms max | {2}ms total";
    private static final String FORMAT_5 = "Threads awaiting: {0}";

    private final Pool connectionPool;
    private final LongAdder creationCount = new LongAdder();
    private final LongAdder creationTotalTime = new LongAdder();
    private final LongAdder acquireCount = new LongAdder();
    private final LongAdder returnCount = new LongAdder();
    private final LongAdder acquireTotalTime = new LongAdder();
    private final LongAdder leakDetectionCount = new LongAdder();
    private final LongAdder invalidCount = new LongAdder();
    private final LongAdder flushCount = new LongAdder();
    private final LongAdder reapCount = new LongAdder();
    private final LongAdder destroyCount = new LongAdder();
    private final LongAccumulator maxCreatedDuration = new LongAccumulator( Long::max, 0 );
    private final LongAccumulator maxAcquireDuration = new LongAccumulator( Long::max, 0 );

    public DefaultMetricsRepository(Pool pool) {
        connectionPool = pool;
    }

    @Override
    public long beforeConnectionCreation() {
        return nanoTime();
    }

    @Override
    public void afterConnectionCreation(long timestamp) {
        long duration = nanoTime() - timestamp;
        creationCount.increment();
        creationTotalTime.add( duration );
        maxCreatedDuration.accumulate( duration );
    }

    @Override
    public long beforeConnectionAcquire() {
        return nanoTime();
    }

    @Override
    public void afterConnectionAcquire(long timestamp) {
        long duration = nanoTime() - timestamp;
        acquireCount.increment();
        acquireTotalTime.add( duration );
        maxAcquireDuration.accumulate( duration );
    }

    @Override
    public void afterConnectionReturn() {
        returnCount.increment();
    }

    @Override
    public void afterLeakDetection() {
        leakDetectionCount.increment();
    }

    @Override
    public void afterConnectionInvalid() {
        invalidCount.increment();
    }

    @Override
    public void afterConnectionFlush() {
        flushCount.increment();
    }

    @Override
    public void afterConnectionReap() {
        reapCount.increment();
    }

    @Override
    public void afterConnectionDestroy() {
        destroyCount.increment();
    }

    // --- //

    @Override
    public long creationCount() {
        return creationCount.longValue();
    }

    @Override
    public Duration creationTimeAverage() {
        if ( creationCount.longValue() == 0 ) {
            return ZERO;
        }
        return ofNanos( creationTotalTime.longValue() / creationCount.longValue() );
    }

    @Override
    public Duration creationTimeMax() {
        return ofNanos( maxCreatedDuration.get() );
    }

    @Override
    public Duration creationTimeTotal() {
        return ofNanos( creationTotalTime.longValue() );
    }

    @Override
    public long acquireCount() {
        return acquireCount.longValue();
    }

    @Override
    public long leakDetectionCount() {
        return leakDetectionCount.longValue();
    }

    @Override
    public long invalidCount() {
        return invalidCount.longValue();
    }

    @Override
    public long flushCount() {
        return flushCount.longValue();
    }

    @Override
    public long reapCount() {
        return reapCount.longValue();
    }

    @Override
    public long destroyCount() {
        return destroyCount.longValue();
    }

    @Override
    public long activeCount() {
        return connectionPool.activeCount();
    }

    @Override
    public long maxUsedCount() {
        return connectionPool.maxUsedCount();
    }

    @Override
    public long availableCount() {
        return connectionPool.availableCount();
    }

    @Override
    public Duration blockingTimeAverage() {
        if ( acquireCount.longValue() == 0 ) {
            return ZERO;
        }
        return ofNanos( acquireTotalTime.longValue() / acquireCount.longValue() );
    }

    @Override
    public Duration blockingTimeMax() {
        return ofNanos( maxAcquireDuration.get() );
    }

    @Override
    public Duration blockingTimeTotal() {
        return ofNanos( acquireTotalTime.longValue() );
    }

    @Override
    public long awaitingCount() {
        return connectionPool.awaitingCount();
    }

    // --- //

    @Override
    public void reset() {
        creationCount.reset();
        creationTotalTime.reset();
        acquireCount.reset();
        acquireTotalTime.reset();
        leakDetectionCount.reset();
        invalidCount.reset();

        maxCreatedDuration.reset();
        maxAcquireDuration.reset();
        connectionPool.resetMaxUsedCount();
    }

    // --- //

    @Override
    public String toString() {
        double avgCreationMs = (double) creationTimeAverage().toNanos() / MILLISECONDS.toNanos( 1 );
        double avgBlockingMs = (double) blockingTimeAverage().toNanos() / MILLISECONDS.toNanos( 1 );

        String nl = System.lineSeparator();

        StringBuffer buffer = new StringBuffer( 500 );
        buffer.append( nl ).append( "===" ).append( nl );
        new MessageFormat( FORMAT_1, Locale.ROOT ).format( new Object[]{creationCount, invalidCount, reapCount, flushCount, destroyCount}, buffer, null ).append( nl );
        new MessageFormat( FORMAT_2, Locale.ROOT ).format( new Object[]{availableCount(), activeCount(), maxUsedCount(), acquireCount, returnCount}, buffer, null ).append( nl );
        new MessageFormat( FORMAT_3, Locale.ROOT ).format( new Object[]{avgCreationMs, creationTimeMax().toMillis(), creationTimeTotal().toMillis()}, buffer, null ).append( nl );
        new MessageFormat( FORMAT_4, Locale.ROOT ).format( new Object[]{avgBlockingMs, blockingTimeMax().toMillis(), blockingTimeTotal().toMillis()}, buffer, null ).append( nl );
        new MessageFormat( FORMAT_5, Locale.ROOT ).format( new Object[]{awaitingCount()}, buffer, null ).append( nl );
        return buffer.append( "===" ).toString();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy