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
This commit is contained in:
Shawn Pearce 2015-11-12 18:38:08 -08:00
parent a093f127d4
commit 5ae5356717
6 changed files with 53 additions and 8 deletions

View File

@ -276,7 +276,7 @@ public class Daemon extends SiteProgram {
@VisibleForTesting @VisibleForTesting
public void start() throws IOException { public void start() throws IOException {
if (dbInjector == null) { if (dbInjector == null) {
dbInjector = createDbInjector(MULTI_USER); dbInjector = createDbInjector(true /* enableMetrics */, MULTI_USER);
} }
cfgInjector = createCfgInjector(); cfgInjector = createCfgInjector();
config = cfgInjector.getInstance( config = cfgInjector.getInstance(
@ -325,7 +325,6 @@ public class Daemon extends SiteProgram {
private Injector createSysInjector() { private Injector createSysInjector() {
final List<Module> modules = new ArrayList<>(); final List<Module> modules = new ArrayList<>();
modules.add(SchemaVersionCheck.module()); modules.add(SchemaVersionCheck.module());
modules.add(new DropWizardMetricMaker.ApiModule());
modules.add(new DropWizardMetricMaker.RestModule()); modules.add(new DropWizardMetricMaker.RestModule());
modules.add(new LogFileCompressor.Module()); modules.add(new LogFileCompressor.Module());
modules.add(new WorkQueue.Module()); modules.add(new WorkQueue.Module());

View File

@ -20,8 +20,6 @@ import com.google.common.cache.Cache;
import com.google.gerrit.extensions.config.FactoryModule; import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.extensions.registration.DynamicMap; import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.registration.DynamicSet; 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.reviewdb.client.AccountGroup;
import com.google.gerrit.rules.PrologModule; import com.google.gerrit.rules.PrologModule;
import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.CurrentUser;
@ -91,7 +89,6 @@ public class BatchProgramModule extends FactoryModule {
install(reviewDbModule); install(reviewDbModule);
install(new DiffExecutorModule()); install(new DiffExecutorModule());
install(PatchListCacheImpl.module()); install(PatchListCacheImpl.module());
bind(MetricMaker.class).to(DisabledMetricMaker.class);
// Plugins are not loaded and we're just running through each change // Plugins are not loaded and we're just running through each change
// once, so don't worry about cache removal. // once, so don't worry about cache removal.

View File

@ -15,6 +15,7 @@
package com.google.gerrit.pgm.util; package com.google.gerrit.pgm.util;
import com.google.gerrit.common.SiteLibraryLoaderUtil; 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.GerritServerConfig;
import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.schema.DataSourceProvider; import com.google.gerrit.server.schema.DataSourceProvider;
@ -37,9 +38,10 @@ public class SiteLibraryBasedDataSourceProvider extends DataSourceProvider {
@Inject @Inject
SiteLibraryBasedDataSourceProvider(SitePaths site, SiteLibraryBasedDataSourceProvider(SitePaths site,
@GerritServerConfig Config cfg, @GerritServerConfig Config cfg,
MetricMaker metrics,
DataSourceProvider.Context ctx, DataSourceProvider.Context ctx,
DataSourceType dst) { DataSourceType dst) {
super(cfg, ctx, dst); super(cfg, metrics, ctx, dst);
libdir = site.lib_dir; libdir = site.lib_dir;
} }

View File

@ -22,6 +22,9 @@ import com.google.common.collect.Lists;
import com.google.gerrit.common.Die; import com.google.gerrit.common.Die;
import com.google.gerrit.extensions.events.LifecycleListener; import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.lifecycle.LifecycleModule; 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.GerritServerConfig;
import com.google.gerrit.server.config.GerritServerConfigModule; import com.google.gerrit.server.config.GerritServerConfigModule;
import com.google.gerrit.server.config.SitePath; import com.google.gerrit.server.config.SitePath;
@ -93,7 +96,13 @@ public abstract class SiteProgram extends AbstractProgram {
} }
/** @return provides database connectivity and site path. */ /** @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 Path sitePath = getSitePath();
final List<Module> modules = new ArrayList<>(); final List<Module> modules = new ArrayList<>();
@ -107,6 +116,17 @@ public abstract class SiteProgram extends AbstractProgram {
}; };
modules.add(sitePathModule); 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() { modules.add(new LifecycleModule() {
@Override @Override
protected void configure() { protected void configure() {

View File

@ -20,6 +20,10 @@ import static java.util.concurrent.TimeUnit.SECONDS;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.gerrit.extensions.events.LifecycleListener; import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.extensions.persistence.DataSourceInterceptor; 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.ConfigSection;
import com.google.gerrit.server.config.ConfigUtil; import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.GerritServerConfig;
@ -46,15 +50,18 @@ public class DataSourceProvider implements Provider<DataSource>,
public static final int DEFAULT_POOL_LIMIT = 8; public static final int DEFAULT_POOL_LIMIT = 8;
private final Config cfg; private final Config cfg;
private final MetricMaker metrics;
private final Context ctx; private final Context ctx;
private final DataSourceType dst; private final DataSourceType dst;
private DataSource ds; private DataSource ds;
@Inject @Inject
protected DataSourceProvider(@GerritServerConfig Config cfg, protected DataSourceProvider(@GerritServerConfig Config cfg,
MetricMaker metrics,
Context ctx, Context ctx,
DataSourceType dst) { DataSourceType dst) {
this.cfg = cfg; this.cfg = cfg;
this.metrics = metrics;
this.ctx = ctx; this.ctx = ctx;
this.dst = dst; this.dst = dst;
} }
@ -126,6 +133,7 @@ public class DataSourceProvider implements Provider<DataSource>,
ds.setMaxWait(ConfigUtil.getTimeUnit(cfg, "database", null, ds.setMaxWait(ConfigUtil.getTimeUnit(cfg, "database", null,
"poolmaxwait", MILLISECONDS.convert(30, SECONDS), MILLISECONDS)); "poolmaxwait", MILLISECONDS.convert(30, SECONDS), MILLISECONDS));
ds.setInitialSize(ds.getMinIdle()); ds.setInitialSize(ds.getMinIdle());
exportPoolMetrics(ds);
return intercept(interceptor, ds); return intercept(interceptor, ds);
} else { } else {
@ -148,6 +156,25 @@ public class DataSourceProvider implements Provider<DataSource>,
} }
} }
private void exportPoolMetrics(final BasicDataSource pool) {
final CallbackMetric1<Boolean, Integer> 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) { private DataSource intercept(String interceptor, DataSource ds) {
if (interceptor == null) { if (interceptor == null) {
return ds; return ds;

View File

@ -261,6 +261,7 @@ public class WebAppInitializer extends GuiceServletContextListener
}); });
} }
modules.add(new DatabaseModule()); modules.add(new DatabaseModule());
modules.add(new DropWizardMetricMaker.ApiModule());
return Guice.createInjector(PRODUCTION, modules); return Guice.createInjector(PRODUCTION, modules);
} }
@ -289,7 +290,6 @@ public class WebAppInitializer extends GuiceServletContextListener
private Injector createSysInjector() { private Injector createSysInjector() {
final List<Module> modules = new ArrayList<>(); final List<Module> modules = new ArrayList<>();
modules.add(new DropWizardMetricMaker.ApiModule());
modules.add(new DropWizardMetricMaker.RestModule()); modules.add(new DropWizardMetricMaker.RestModule());
modules.add(new WorkQueue.Module()); modules.add(new WorkQueue.Module());
modules.add(new ChangeHookRunner.Module()); modules.add(new ChangeHookRunner.Module());