From 97e6a96624850d7620fc76cac2dab38e809f09a6 Mon Sep 17 00:00:00 2001 From: enricovianello Date: Mon, 2 Aug 2021 14:57:05 +0200 Subject: [PATCH] Fixed database connection pool metrics logging --- .../metrics/InstrumentedBasicDataSource.java | 64 +++++++++++++++---- .../storm/metrics/StormMetricsReporter.java | 54 ++++++++++++---- .../pool/DatabaseConnectionPool.java | 17 +++++ .../pool/DefaultDatabaseConnectionPool.java | 20 ------ .../pool/DefaultDatabaseConnector.java | 17 +++++ .../pool/StormBeIsamConnectionPool.java | 17 +++++ .../pool/StormDbConnectionPool.java | 17 +++++ 7 files changed, 160 insertions(+), 46 deletions(-) diff --git a/src/main/java/it/grid/storm/metrics/InstrumentedBasicDataSource.java b/src/main/java/it/grid/storm/metrics/InstrumentedBasicDataSource.java index 27049aa2..195f4a1c 100644 --- a/src/main/java/it/grid/storm/metrics/InstrumentedBasicDataSource.java +++ b/src/main/java/it/grid/storm/metrics/InstrumentedBasicDataSource.java @@ -1,3 +1,20 @@ +/* + * + * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2010. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + package it.grid.storm.metrics; import static com.codahale.metrics.MetricRegistry.name; @@ -10,16 +27,17 @@ import com.codahale.metrics.Gauge; import com.codahale.metrics.JmxReporter; import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.RatioGauge; import com.codahale.metrics.Timer; public class InstrumentedBasicDataSource extends BasicDataSource { - private Timer getConnectionTimer = null; - private JmxReporter reporter = null; + private final Timer getConnectionTimer; + private final JmxReporter reporter; public InstrumentedBasicDataSource(String prefix, MetricRegistry registry) { instrument(prefix, registry, this); - getConnectionTimer = registry.timer(name(prefix, "getconnection")); + getConnectionTimer = registry.timer(name(prefix, "get-connection")); reporter = JmxReporter.forRegistry(registry).build(); reporter.start(); } @@ -28,58 +46,76 @@ public InstrumentedBasicDataSource(String prefix, MetricRegistry registry) { * Instrument the given BasicDataSource instance with a series of timers and gauges. * */ - public static void instrument(String prefix, MetricRegistry registry, final BasicDataSource datasource) { + public static void instrument(String prefix, MetricRegistry registry, + final BasicDataSource datasource) { - registry.register(name(prefix, "initialsize"), new Gauge() { + registry.register(name(prefix, "initial-size"), new Gauge() { public Integer getValue() { return datasource.getInitialSize(); } }); - registry.register(name(prefix, "maxidle"), new Gauge() { + registry.register(name(prefix, "max-idle"), new Gauge() { public Integer getValue() { return datasource.getMaxIdle(); } }); - registry.register(name(prefix, "maxopenpreparedstatements"), new Gauge() { + registry.register(name(prefix, "max-open-prepared-statements"), new Gauge() { public Integer getValue() { return datasource.getMaxOpenPreparedStatements(); } }); - registry.register(name(prefix, "maxwaitmillis"), new Gauge() { + registry.register(name(prefix, "max-wait-millis"), new Gauge() { public Long getValue() { return datasource.getMaxWaitMillis(); } }); - registry.register(name(prefix, "minevictableidletimemillis"), new Gauge() { + registry.register(name(prefix, "min-evictable-idle-time-millis"), new Gauge() { public Long getValue() { return datasource.getMinEvictableIdleTimeMillis(); } }); - registry.register(name(prefix, "minidle"), new Gauge() { + registry.register(name(prefix, "min-idle"), new Gauge() { public Integer getValue() { return datasource.getMinIdle(); } }); - registry.register(name(prefix, "numactive"), new Gauge() { + registry.register(name(prefix, "num-active"), new Gauge() { public Integer getValue() { return datasource.getNumActive(); } }); - registry.register(name(prefix, "numidle"), new Gauge() { + registry.register(name(prefix, "max-total"), new Gauge() { + public Integer getValue() { + return datasource.getMaxTotal(); + } + }); + registry.register(name(prefix, "num-idle"), new Gauge() { public Integer getValue() { return datasource.getNumIdle(); } }); - registry.register(name(prefix, "numtestsperevictionrun"), new Gauge() { + registry.register(name(prefix, "num-tests-per-eviction-run"), new Gauge() { public Integer getValue() { return datasource.getNumTestsPerEvictionRun(); } }); - registry.register(name(prefix, "timebetweenevictionrunsmillis"), new Gauge() { + registry.register(name(prefix, "time-between-eviction-runs-millis"), new Gauge() { public Long getValue() { return datasource.getTimeBetweenEvictionRunsMillis(); } }); + registry.register(name(prefix, "percent-idle"), new RatioGauge() { + @Override + protected Ratio getRatio() { + return Ratio.of(datasource.getNumIdle(), datasource.getMaxIdle()); + } + }); + registry.register(name(prefix, "percent-active"), new RatioGauge() { + @Override + protected Ratio getRatio() { + return Ratio.of(datasource.getNumActive(), datasource.getMaxTotal()); + } + }); } @Override diff --git a/src/main/java/it/grid/storm/metrics/StormMetricsReporter.java b/src/main/java/it/grid/storm/metrics/StormMetricsReporter.java index 4fc40a5d..17a7a858 100644 --- a/src/main/java/it/grid/storm/metrics/StormMetricsReporter.java +++ b/src/main/java/it/grid/storm/metrics/StormMetricsReporter.java @@ -1,9 +1,25 @@ +/* + * + * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2010. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + package it.grid.storm.metrics; -import java.util.Map; +import java.util.Optional; import java.util.SortedMap; import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,8 +36,6 @@ import it.grid.storm.common.OperationType; import it.grid.storm.filesystem.MetricsFilesystemAdapter.FilesystemMetric; -import it.grid.storm.persistence.pool.StormBeIsamConnectionPool; -import it.grid.storm.persistence.pool.StormDbConnectionPool; public class StormMetricsReporter extends ScheduledReporter { @@ -115,17 +129,33 @@ public void report(SortedMap gauges, SortedMap c reportJettyHandlerMetrics("xmlrpc-handler", meters); reportJettyHandlerMetrics("rest-handler", meters); - reportDbPoolMetrics("storm-db", StormDbConnectionPool.getInstance().getMetrics()); - reportDbPoolMetrics("storm-be-isam", StormBeIsamConnectionPool.getInstance().getMetrics()); + reportDbPoolMetrics("storm_db", gauges, timers); + reportDbPoolMetrics("storm_be_ISAM", gauges, timers); } - private void reportDbPoolMetrics(String tpName, Map metrics) { + @SuppressWarnings("rawtypes") + private void reportDbPoolMetrics(String tpName, SortedMap gauges, + SortedMap timers) { - String result = metrics.entrySet() - .stream() - .map(e -> e.getKey() + "=" + e.getValue()) - .collect(Collectors.joining(", ")); - LOG.info("{} [{}]", tpName, result); + String timerName = tpName + ".get-connection"; + Optional.ofNullable(timers.get(timerName)) + .ifPresentOrElse(t -> { + reportMetric(timerName, t); + }, + () -> { + LOG.error("Invalid metric name: {}", timerName); + return; + }); + + int numActive = getIntValue(gauges.get(tpName + ".num-active")); + int maxActive = getIntValue(gauges.get(tpName + ".max-total")); + int numIdle = getIntValue(gauges.get(tpName + ".num-idle")); + int maxIdle = getIntValue(gauges.get(tpName + ".max-idle")); + double percentActive = getDoubleValue(gauges.get(tpName + ".percent-active")); + double percentIdle = getDoubleValue(gauges.get(tpName + ".percent-idle")); + + LOG.info("{} [active-connections={}, max-active-connections={}, percent-active={}, idle-connections={}, max-idle-connections={}. percent-idle={}]", + tpName, numActive, maxActive, percentActive, numIdle, maxIdle, percentIdle); } private void reportMetric(String name, Timer timer) { diff --git a/src/main/java/it/grid/storm/persistence/pool/DatabaseConnectionPool.java b/src/main/java/it/grid/storm/persistence/pool/DatabaseConnectionPool.java index 58d58c0f..49fba858 100644 --- a/src/main/java/it/grid/storm/persistence/pool/DatabaseConnectionPool.java +++ b/src/main/java/it/grid/storm/persistence/pool/DatabaseConnectionPool.java @@ -1,3 +1,20 @@ +/* + * + * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2010. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + package it.grid.storm.persistence.pool; public interface DatabaseConnectionPool { diff --git a/src/main/java/it/grid/storm/persistence/pool/DefaultDatabaseConnectionPool.java b/src/main/java/it/grid/storm/persistence/pool/DefaultDatabaseConnectionPool.java index 15feffa3..754ab401 100644 --- a/src/main/java/it/grid/storm/persistence/pool/DefaultDatabaseConnectionPool.java +++ b/src/main/java/it/grid/storm/persistence/pool/DefaultDatabaseConnectionPool.java @@ -17,18 +17,12 @@ package it.grid.storm.persistence.pool; -import static java.lang.String.valueOf; - import java.sql.Connection; import java.sql.SQLException; -import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.codahale.metrics.MetricRegistry; -import com.google.common.collect.Maps; - import it.grid.storm.metrics.InstrumentedBasicDataSource; import it.grid.storm.metrics.StormMetricRegistry; @@ -86,20 +80,6 @@ public Connection getConnection() throws SQLException { return bds.getConnection(); } - public Map getMetrics() { - - Map metrics = Maps.newHashMap(); - metrics.put("max-total", valueOf(bds.getMaxTotal())); - metrics.put("min-idle", valueOf(bds.getMinIdle())); - metrics.put("test-on-borrow", valueOf(bds.getTestOnBorrow())); - metrics.put("test-while-idle", valueOf(bds.getTestWhileIdle())); - metrics.put("num-active", valueOf(bds.getNumActive())); - metrics.put("num-idle", valueOf(bds.getNumIdle())); - metrics.put("max-conn-lifetime-millis", valueOf(bds.getMaxConnLifetimeMillis())); - metrics.put("max-idle", valueOf(bds.getMaxIdle())); - return metrics; - } - @Override public int getMaxTotal() { return maxTotal; diff --git a/src/main/java/it/grid/storm/persistence/pool/DefaultDatabaseConnector.java b/src/main/java/it/grid/storm/persistence/pool/DefaultDatabaseConnector.java index 5aa6b02b..3bb0a9dd 100644 --- a/src/main/java/it/grid/storm/persistence/pool/DefaultDatabaseConnector.java +++ b/src/main/java/it/grid/storm/persistence/pool/DefaultDatabaseConnector.java @@ -1,3 +1,20 @@ +/* + * + * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2010. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + package it.grid.storm.persistence.pool; import static java.lang.String.format; diff --git a/src/main/java/it/grid/storm/persistence/pool/StormBeIsamConnectionPool.java b/src/main/java/it/grid/storm/persistence/pool/StormBeIsamConnectionPool.java index cef6a190..9d794f01 100644 --- a/src/main/java/it/grid/storm/persistence/pool/StormBeIsamConnectionPool.java +++ b/src/main/java/it/grid/storm/persistence/pool/StormBeIsamConnectionPool.java @@ -1,3 +1,20 @@ +/* + * + * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2010. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + package it.grid.storm.persistence.pool; import it.grid.storm.config.Configuration; diff --git a/src/main/java/it/grid/storm/persistence/pool/StormDbConnectionPool.java b/src/main/java/it/grid/storm/persistence/pool/StormDbConnectionPool.java index 957cc70d..ae68c75e 100644 --- a/src/main/java/it/grid/storm/persistence/pool/StormDbConnectionPool.java +++ b/src/main/java/it/grid/storm/persistence/pool/StormDbConnectionPool.java @@ -1,3 +1,20 @@ +/* + * + * Copyright (c) Istituto Nazionale di Fisica Nucleare (INFN). 2006-2010. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + package it.grid.storm.persistence.pool; import it.grid.storm.config.Configuration;