From 5ae5356717d39fc322571f1f94fd04c2925bd7b9 Mon Sep 17 00:00:00 2001 From: Shawn Pearce Date: Thu, 12 Nov 2015 18:38:08 -0800 Subject: [PATCH] Add sql/connection_pool/connections metric Export the number of active (true) and idle (false) connections inside of the connection pool, if the connection pool was enabled. Change-Id: I42f4f24a27883a63730f6fe9e3649b93f59ebfc8 --- .../java/com/google/gerrit/pgm/Daemon.java | 3 +-- .../gerrit/pgm/util/BatchProgramModule.java | 3 --- .../SiteLibraryBasedDataSourceProvider.java | 4 ++- .../google/gerrit/pgm/util/SiteProgram.java | 22 ++++++++++++++- .../server/schema/DataSourceProvider.java | 27 +++++++++++++++++++ .../gerrit/httpd/WebAppInitializer.java | 2 +- 6 files changed, 53 insertions(+), 8 deletions(-) diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java index ebbb7658de..c9da6ddbe2 100644 --- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java +++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/Daemon.java @@ -276,7 +276,7 @@ public class Daemon extends SiteProgram { @VisibleForTesting public void start() throws IOException { if (dbInjector == null) { - dbInjector = createDbInjector(MULTI_USER); + dbInjector = createDbInjector(true /* enableMetrics */, MULTI_USER); } cfgInjector = createCfgInjector(); config = cfgInjector.getInstance( @@ -325,7 +325,6 @@ public class Daemon extends SiteProgram { private Injector createSysInjector() { final List modules = new ArrayList<>(); modules.add(SchemaVersionCheck.module()); - modules.add(new DropWizardMetricMaker.ApiModule()); modules.add(new DropWizardMetricMaker.RestModule()); modules.add(new LogFileCompressor.Module()); modules.add(new WorkQueue.Module()); diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/BatchProgramModule.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/BatchProgramModule.java index ba8c28f931..b6539f1331 100644 --- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/BatchProgramModule.java +++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/BatchProgramModule.java @@ -20,8 +20,6 @@ import com.google.common.cache.Cache; import com.google.gerrit.extensions.config.FactoryModule; import com.google.gerrit.extensions.registration.DynamicMap; import com.google.gerrit.extensions.registration.DynamicSet; -import com.google.gerrit.metrics.DisabledMetricMaker; -import com.google.gerrit.metrics.MetricMaker; import com.google.gerrit.reviewdb.client.AccountGroup; import com.google.gerrit.rules.PrologModule; import com.google.gerrit.server.CurrentUser; @@ -91,7 +89,6 @@ public class BatchProgramModule extends FactoryModule { install(reviewDbModule); install(new DiffExecutorModule()); install(PatchListCacheImpl.module()); - bind(MetricMaker.class).to(DisabledMetricMaker.class); // Plugins are not loaded and we're just running through each change // once, so don't worry about cache removal. diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteLibraryBasedDataSourceProvider.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteLibraryBasedDataSourceProvider.java index 048c2eed12..7f6313dd15 100644 --- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteLibraryBasedDataSourceProvider.java +++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteLibraryBasedDataSourceProvider.java @@ -15,6 +15,7 @@ package com.google.gerrit.pgm.util; import com.google.gerrit.common.SiteLibraryLoaderUtil; +import com.google.gerrit.metrics.MetricMaker; import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.schema.DataSourceProvider; @@ -37,9 +38,10 @@ public class SiteLibraryBasedDataSourceProvider extends DataSourceProvider { @Inject SiteLibraryBasedDataSourceProvider(SitePaths site, @GerritServerConfig Config cfg, + MetricMaker metrics, DataSourceProvider.Context ctx, DataSourceType dst) { - super(cfg, ctx, dst); + super(cfg, metrics, ctx, dst); libdir = site.lib_dir; } diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteProgram.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteProgram.java index a6f1f93d09..bf69d9bcbc 100644 --- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteProgram.java +++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/util/SiteProgram.java @@ -22,6 +22,9 @@ import com.google.common.collect.Lists; import com.google.gerrit.common.Die; import com.google.gerrit.extensions.events.LifecycleListener; import com.google.gerrit.lifecycle.LifecycleModule; +import com.google.gerrit.metrics.DisabledMetricMaker; +import com.google.gerrit.metrics.MetricMaker; +import com.google.gerrit.metrics.dropwizard.DropWizardMetricMaker; import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfigModule; import com.google.gerrit.server.config.SitePath; @@ -93,7 +96,13 @@ public abstract class SiteProgram extends AbstractProgram { } /** @return provides database connectivity and site path. */ - protected Injector createDbInjector(final DataSourceProvider.Context context) { + protected Injector createDbInjector(DataSourceProvider.Context context) { + return createDbInjector(false, context); + } + + /** @return provides database connectivity and site path. */ + protected Injector createDbInjector(final boolean enableMetrics, + final DataSourceProvider.Context context) { final Path sitePath = getSitePath(); final List modules = new ArrayList<>(); @@ -107,6 +116,17 @@ public abstract class SiteProgram extends AbstractProgram { }; modules.add(sitePathModule); + if (enableMetrics) { + modules.add(new DropWizardMetricMaker.ApiModule()); + } else { + modules.add(new AbstractModule() { + @Override + protected void configure() { + bind(MetricMaker.class).to(DisabledMetricMaker.class); + } + }); + } + modules.add(new LifecycleModule() { @Override protected void configure() { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/DataSourceProvider.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/DataSourceProvider.java index 30ebaa72fe..e0482f9be8 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/DataSourceProvider.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/DataSourceProvider.java @@ -20,6 +20,10 @@ import static java.util.concurrent.TimeUnit.SECONDS; import com.google.common.base.Strings; import com.google.gerrit.extensions.events.LifecycleListener; import com.google.gerrit.extensions.persistence.DataSourceInterceptor; +import com.google.gerrit.metrics.CallbackMetric1; +import com.google.gerrit.metrics.Description; +import com.google.gerrit.metrics.Field; +import com.google.gerrit.metrics.MetricMaker; import com.google.gerrit.server.config.ConfigSection; import com.google.gerrit.server.config.ConfigUtil; import com.google.gerrit.server.config.GerritServerConfig; @@ -46,15 +50,18 @@ public class DataSourceProvider implements Provider, public static final int DEFAULT_POOL_LIMIT = 8; private final Config cfg; + private final MetricMaker metrics; private final Context ctx; private final DataSourceType dst; private DataSource ds; @Inject protected DataSourceProvider(@GerritServerConfig Config cfg, + MetricMaker metrics, Context ctx, DataSourceType dst) { this.cfg = cfg; + this.metrics = metrics; this.ctx = ctx; this.dst = dst; } @@ -126,6 +133,7 @@ public class DataSourceProvider implements Provider, ds.setMaxWait(ConfigUtil.getTimeUnit(cfg, "database", null, "poolmaxwait", MILLISECONDS.convert(30, SECONDS), MILLISECONDS)); ds.setInitialSize(ds.getMinIdle()); + exportPoolMetrics(ds); return intercept(interceptor, ds); } else { @@ -148,6 +156,25 @@ public class DataSourceProvider implements Provider, } } + private void exportPoolMetrics(final BasicDataSource pool) { + final CallbackMetric1 cnt = metrics.newCallbackMetric( + "sql/connection_pool/connections", + Integer.class, + new Description("SQL database connections") + .setGauge() + .setUnit("connections"), + Field.ofBoolean("active")); + metrics.newTrigger(cnt, new Runnable() { + @Override + public void run() { + synchronized (pool) { + cnt.set(true, pool.getNumActive()); + cnt.set(false, pool.getNumIdle()); + } + } + }); + } + private DataSource intercept(String interceptor, DataSource ds) { if (interceptor == null) { return ds; diff --git a/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java b/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java index 10e3f9c482..2ce42184cc 100644 --- a/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java +++ b/gerrit-war/src/main/java/com/google/gerrit/httpd/WebAppInitializer.java @@ -261,6 +261,7 @@ public class WebAppInitializer extends GuiceServletContextListener }); } modules.add(new DatabaseModule()); + modules.add(new DropWizardMetricMaker.ApiModule()); return Guice.createInjector(PRODUCTION, modules); } @@ -289,7 +290,6 @@ public class WebAppInitializer extends GuiceServletContextListener private Injector createSysInjector() { final List modules = new ArrayList<>(); - modules.add(new DropWizardMetricMaker.ApiModule()); modules.add(new DropWizardMetricMaker.RestModule()); modules.add(new WorkQueue.Module()); modules.add(new ChangeHookRunner.Module());