diff --git a/plume-db/src/main/java/com/coreoz/plume/db/transaction/HikariDataSources.java b/plume-db/src/main/java/com/coreoz/plume/db/transaction/HikariDataSources.java index 99d1c56..717c928 100644 --- a/plume-db/src/main/java/com/coreoz/plume/db/transaction/HikariDataSources.java +++ b/plume-db/src/main/java/com/coreoz/plume/db/transaction/HikariDataSources.java @@ -16,12 +16,12 @@ public class HikariDataSources { public static DataSource fromConfig(Config config, String prefix) { - return initializeFromProperties(readConfig(config, prefix)); + return new HikariDataSource(createHikariConfig(config, prefix)); } - private static HikariDataSource initializeFromProperties(Map properties) { - return new HikariDataSource(new HikariConfig(mapToProperties(properties))); - } + public static HikariConfig createHikariConfig(Config config, String prefix) { + return new HikariConfig(mapToProperties(readConfig(config, prefix))); + } private static Properties mapToProperties(Map mapProperties) { Properties properties = new Properties(); diff --git a/plume-web-jersey-monitoring/pom.xml b/plume-web-jersey-monitoring/pom.xml index 93648aa..306b3b2 100644 --- a/plume-web-jersey-monitoring/pom.xml +++ b/plume-web-jersey-monitoring/pom.xml @@ -35,6 +35,11 @@ com.coreoz plume-web-jersey + + org.glassfish.jersey.containers + jersey-container-grizzly2-http + true + com.coreoz plume-db diff --git a/plume-web-jersey-monitoring/src/main/java/com/coreoz/plume/jersey/monitoring/utils/metrics/MetricsCheckBuilder.java b/plume-web-jersey-monitoring/src/main/java/com/coreoz/plume/jersey/monitoring/utils/metrics/MetricsCheckBuilder.java index 88db257..2f57d72 100644 --- a/plume-web-jersey-monitoring/src/main/java/com/coreoz/plume/jersey/monitoring/utils/metrics/MetricsCheckBuilder.java +++ b/plume-web-jersey-monitoring/src/main/java/com/coreoz/plume/jersey/monitoring/utils/metrics/MetricsCheckBuilder.java @@ -1,10 +1,13 @@ package com.coreoz.plume.jersey.monitoring.utils.metrics; +import com.codahale.metrics.Gauge; import com.codahale.metrics.Metric; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.MetricSet; import com.codahale.metrics.jvm.MemoryUsageGaugeSet; import com.codahale.metrics.jvm.ThreadStatesGaugeSet; +import com.coreoz.plume.jersey.grizzly.GrizzlyThreadPoolProbe; +import com.zaxxer.hikari.HikariDataSource; import javax.inject.Provider; import java.util.Map; @@ -27,6 +30,20 @@ public MetricsCheckBuilder registerJvmMetrics() { return this; } + public MetricsCheckBuilder registerGrizzlyMetrics(GrizzlyThreadPoolProbe grizzlyThreadPoolProbe) { + this.metricRegistry.register("http-pool.max-size", (Gauge) grizzlyThreadPoolProbe::getPoolMaxSize); + this.metricRegistry.register("http-pool.current-size", (Gauge) grizzlyThreadPoolProbe::getTasksWaitingSize); + this.metricRegistry.register("http-pool.waiting-size", (Gauge) grizzlyThreadPoolProbe::getTasksWaitingSize); + this.metricRegistry.register("http-pool.usage-size", (Gauge) grizzlyThreadPoolProbe::getPoolUsageSize); + this.metricRegistry.register("http-pool.usage", (Gauge) () -> ((float) grizzlyThreadPoolProbe.getPoolUsageSize()) / ((float)grizzlyThreadPoolProbe.getPoolMaxSize())); + return this; + } + + public MetricsCheckBuilder registerHikariMetrics(HikariDataSource hikariDataSource) { + hikariDataSource.setMetricRegistry(this.metricRegistry); + return this; + } + public Provider> build() { return this::getMetrics; } diff --git a/plume-web-jersey/src/main/java/com/coreoz/plume/jersey/grizzly/GrizzlyThreadPoolProbe.java b/plume-web-jersey/src/main/java/com/coreoz/plume/jersey/grizzly/GrizzlyThreadPoolProbe.java new file mode 100644 index 0000000..3bce005 --- /dev/null +++ b/plume-web-jersey/src/main/java/com/coreoz/plume/jersey/grizzly/GrizzlyThreadPoolProbe.java @@ -0,0 +1,92 @@ +package com.coreoz.plume.jersey.grizzly; + +import org.glassfish.grizzly.threadpool.AbstractThreadPool; +import org.glassfish.grizzly.threadpool.ThreadPoolProbe; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.inject.Singleton; +import java.util.concurrent.atomic.AtomicInteger; + +@Singleton +public class GrizzlyThreadPoolProbe implements ThreadPoolProbe { + private static final Logger logger = LoggerFactory.getLogger(GrizzlyThreadPoolProbe.class); + + private final AtomicInteger tasksWaitingSize = new AtomicInteger(0); + private final AtomicInteger poolUsageSize = new AtomicInteger(0); + + private int poolMaxSize = 0; + private int poolCurrentSize = 0; + + /* Stats accessors */ + + public int getPoolMaxSize() { + return poolMaxSize; + } + + public int getPoolCurrentSize() { + return poolCurrentSize; + } + + public int getPoolUsageSize() { + return poolUsageSize.get(); + } + + public int getTasksWaitingSize() { + return tasksWaitingSize.get(); + } + + /* Implements ThreadPoolProbe */ + + @Override + public void onThreadPoolStartEvent(AbstractThreadPool threadPool) { + poolMaxSize = threadPool.getConfig().getMaxPoolSize(); + poolCurrentSize = threadPool.getSize(); + } + + @Override + public void onThreadPoolStopEvent(AbstractThreadPool threadPool) { + // Not used + } + + @Override + public void onThreadAllocateEvent(AbstractThreadPool threadPool, Thread thread) { + poolCurrentSize = threadPool.getSize(); + } + + @Override + public void onThreadReleaseEvent(AbstractThreadPool threadPool, Thread thread) { + poolCurrentSize = threadPool.getSize(); + } + + @Override + public void onMaxNumberOfThreadsEvent(AbstractThreadPool threadPool, int maxNumberOfThreads) { + // Not used + } + + @Override + public void onTaskQueueEvent(AbstractThreadPool threadPool, Runnable task) { + tasksWaitingSize.incrementAndGet(); + } + + @Override + public void onTaskDequeueEvent(AbstractThreadPool threadPool, Runnable task) { + tasksWaitingSize.decrementAndGet(); + poolUsageSize.incrementAndGet(); + } + + @Override + public void onTaskCancelEvent(AbstractThreadPool threadPool, Runnable task) { + tasksWaitingSize.decrementAndGet(); + } + + @Override + public void onTaskCompleteEvent(AbstractThreadPool threadPool, Runnable task) { + poolUsageSize.decrementAndGet(); + } + + @Override + public void onTaskQueueOverflowEvent(AbstractThreadPool threadPool) { + logger.error("Grizzly queue overflow"); + } +}