Skip to content

Commit

Permalink
Fixed database connection pool metrics logging
Browse files Browse the repository at this point in the history
  • Loading branch information
enricovianello committed Aug 2, 2021
1 parent ae257f7 commit 97e6a96
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 46 deletions.
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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();
}
Expand All @@ -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<Integer>() {
registry.register(name(prefix, "initial-size"), new Gauge<Integer>() {
public Integer getValue() {
return datasource.getInitialSize();
}
});
registry.register(name(prefix, "maxidle"), new Gauge<Integer>() {
registry.register(name(prefix, "max-idle"), new Gauge<Integer>() {
public Integer getValue() {
return datasource.getMaxIdle();
}
});
registry.register(name(prefix, "maxopenpreparedstatements"), new Gauge<Integer>() {
registry.register(name(prefix, "max-open-prepared-statements"), new Gauge<Integer>() {
public Integer getValue() {
return datasource.getMaxOpenPreparedStatements();
}
});
registry.register(name(prefix, "maxwaitmillis"), new Gauge<Long>() {
registry.register(name(prefix, "max-wait-millis"), new Gauge<Long>() {
public Long getValue() {
return datasource.getMaxWaitMillis();
}
});
registry.register(name(prefix, "minevictableidletimemillis"), new Gauge<Long>() {
registry.register(name(prefix, "min-evictable-idle-time-millis"), new Gauge<Long>() {
public Long getValue() {
return datasource.getMinEvictableIdleTimeMillis();
}
});
registry.register(name(prefix, "minidle"), new Gauge<Integer>() {
registry.register(name(prefix, "min-idle"), new Gauge<Integer>() {
public Integer getValue() {
return datasource.getMinIdle();
}
});
registry.register(name(prefix, "numactive"), new Gauge<Integer>() {
registry.register(name(prefix, "num-active"), new Gauge<Integer>() {
public Integer getValue() {
return datasource.getNumActive();
}
});
registry.register(name(prefix, "numidle"), new Gauge<Integer>() {
registry.register(name(prefix, "max-total"), new Gauge<Integer>() {
public Integer getValue() {
return datasource.getMaxTotal();
}
});
registry.register(name(prefix, "num-idle"), new Gauge<Integer>() {
public Integer getValue() {
return datasource.getNumIdle();
}
});
registry.register(name(prefix, "numtestsperevictionrun"), new Gauge<Integer>() {
registry.register(name(prefix, "num-tests-per-eviction-run"), new Gauge<Integer>() {
public Integer getValue() {
return datasource.getNumTestsPerEvictionRun();
}
});
registry.register(name(prefix, "timebetweenevictionrunsmillis"), new Gauge<Long>() {
registry.register(name(prefix, "time-between-eviction-runs-millis"), new Gauge<Long>() {
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
Expand Down
54 changes: 42 additions & 12 deletions src/main/java/it/grid/storm/metrics/StormMetricsReporter.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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 {

Expand Down Expand Up @@ -115,17 +129,33 @@ public void report(SortedMap<String, Gauge> gauges, SortedMap<String, Counter> 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<String, String> metrics) {
@SuppressWarnings("rawtypes")
private void reportDbPoolMetrics(String tpName, SortedMap<String, Gauge> gauges,
SortedMap<String, Timer> 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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -86,20 +80,6 @@ public Connection getConnection() throws SQLException {
return bds.getConnection();
}

public Map<String, String> getMetrics() {

Map<String, String> 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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down

0 comments on commit 97e6a96

Please sign in to comment.