This is an automated email from the ASF dual-hosted git repository.
jshao pushed a commit to branch branch-1.0
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/branch-1.0 by this push:
new c67f8903b6 [#8558] fix(metrics): fix missing backend connection pool
metrics (#8573)
c67f8903b6 is described below
commit c67f8903b6cc3f4d28e047193642ca3e87530e8f
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Wed Sep 17 13:54:29 2025 +0800
[#8558] fix(metrics): fix missing backend connection pool metrics (#8573)
### What changes were proposed in this pull request?
fix missing backend connection pool metrics
### Why are the changes needed?
Fix: #8558
### Does this PR introduce _any_ user-facing change?
no
### How was this patch tested?
CI pass
Co-authored-by: mchades <[email protected]>
Co-authored-by: fanng <[email protected]>
---
.../org/apache/gravitino/metrics/MetricNames.java | 9 +-
.../apache/gravitino/metrics/MetricsSystem.java | 11 ++-
.../gravitino/metrics/source/MetricsSource.java | 1 +
.../source/RelationDatasourceMetricsSource.java | 13 +--
.../session/SqlSessionFactoryHelper.java | 109 +++++++++++----------
.../metrics/TestExtractMetricNameAndLabel.java | 27 +++--
.../gravitino/metrics/TestMetricsSystem.java | 25 ++++-
7 files changed, 112 insertions(+), 83 deletions(-)
diff --git a/core/src/main/java/org/apache/gravitino/metrics/MetricNames.java
b/core/src/main/java/org/apache/gravitino/metrics/MetricNames.java
index 3a26c20b4b..d6d09ec13b 100644
--- a/core/src/main/java/org/apache/gravitino/metrics/MetricNames.java
+++ b/core/src/main/java/org/apache/gravitino/metrics/MetricNames.java
@@ -22,12 +22,9 @@ package org.apache.gravitino.metrics;
public class MetricNames {
public static final String HTTP_PROCESS_DURATION =
"http-request-duration-seconds";
public static final String SERVER_IDLE_THREAD_NUM =
"http-server.idle-thread.num";
- public static final String
ENTITY_STORE_RELATION_DATASOURCE_ACTIVE_CONNECTIONS =
- "entity-store.relation-datasource.active-connections";
- public static final String ENTITY_STORE_RELATION_DATASOURCE_IDLE_CONNECTIONS
=
- "entity-store.relation-datasource.idle-connections";
- public static final String ENTITY_STORE_RELATION_DATASOURCE_MAX_CONNECTIONS =
- "entity-store.relation-datasource.max-connections";
+ public static final String DATASOURCE_ACTIVE_CONNECTIONS =
"datasource.active-connections";
+ public static final String DATASOURCE_IDLE_CONNECTIONS =
"datasource.idle-connections";
+ public static final String DATASOURCE_MAX_CONNECTIONS =
"datasource.max-connections";
private MetricNames() {}
}
diff --git a/core/src/main/java/org/apache/gravitino/metrics/MetricsSystem.java
b/core/src/main/java/org/apache/gravitino/metrics/MetricsSystem.java
index 6e30d55b2a..bcd86ad530 100644
--- a/core/src/main/java/org/apache/gravitino/metrics/MetricsSystem.java
+++ b/core/src/main/java/org/apache/gravitino/metrics/MetricsSystem.java
@@ -24,6 +24,7 @@ import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.Reporter;
import com.codahale.metrics.jmx.JmxReporter;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.dropwizard.DropwizardExports;
@@ -77,7 +78,15 @@ public class MetricsSystem implements Closeable {
public synchronized void register(MetricsSource metricsSource) {
LOG.info("Register {} to metrics system {}",
metricsSource.getMetricsSourceName(), name);
if (metricSources.containsKey(metricsSource.getMetricsSourceName())) {
- unregister(metricSources.get(metricsSource.getMetricsSourceName()));
+ MetricsSource originalMetricsSource =
metricSources.get(metricsSource.getMetricsSourceName());
+ // In case different MetricsSource use the same name
+ Preconditions.checkState(
+
metricsSource.getClass().getName().equals(originalMetricsSource.getClass().getName()),
+ "Metrics source name %s is already registered, and it's class name
is %s, but the new metrics source class name is %s",
+ metricsSource.getMetricsSourceName(),
+ originalMetricsSource.getClass().getName(),
+ metricsSource.getClass().getName());
+ unregister(originalMetricsSource);
}
this.metricSources.put(metricsSource.getMetricsSourceName(),
metricsSource);
metricRegistry.register(
diff --git
a/core/src/main/java/org/apache/gravitino/metrics/source/MetricsSource.java
b/core/src/main/java/org/apache/gravitino/metrics/source/MetricsSource.java
index 68d0b32949..049e8194cd 100644
--- a/core/src/main/java/org/apache/gravitino/metrics/source/MetricsSource.java
+++ b/core/src/main/java/org/apache/gravitino/metrics/source/MetricsSource.java
@@ -40,6 +40,7 @@ public abstract class MetricsSource {
// metrics source name
public static final String ICEBERG_REST_SERVER_METRIC_NAME =
"iceberg-rest-server";
public static final String GRAVITINO_SERVER_METRIC_NAME = "gravitino-server";
+ public static final String GRAVITINO_RELATIONAL_STORE_METRIC_NAME =
"gravitino-relational-store";
public static final String JVM_METRIC_NAME = "jvm";
private final MetricRegistry metricRegistry;
private final String metricsSourceName;
diff --git
a/core/src/main/java/org/apache/gravitino/metrics/source/RelationDatasourceMetricsSource.java
b/core/src/main/java/org/apache/gravitino/metrics/source/RelationDatasourceMetricsSource.java
index 31582776e2..ee98d27153 100644
---
a/core/src/main/java/org/apache/gravitino/metrics/source/RelationDatasourceMetricsSource.java
+++
b/core/src/main/java/org/apache/gravitino/metrics/source/RelationDatasourceMetricsSource.java
@@ -26,15 +26,10 @@ import org.apache.gravitino.metrics.MetricNames;
public class RelationDatasourceMetricsSource extends MetricsSource {
public RelationDatasourceMetricsSource(BasicDataSource dataSource) {
- super(MetricsSource.GRAVITINO_SERVER_METRIC_NAME);
+ super(MetricsSource.GRAVITINO_RELATIONAL_STORE_METRIC_NAME);
registerGauge(
- MetricNames.ENTITY_STORE_RELATION_DATASOURCE_ACTIVE_CONNECTIONS,
- (Gauge<Integer>) dataSource::getNumActive);
- registerGauge(
- MetricNames.ENTITY_STORE_RELATION_DATASOURCE_IDLE_CONNECTIONS,
- (Gauge<Integer>) dataSource::getNumIdle);
- registerGauge(
- MetricNames.ENTITY_STORE_RELATION_DATASOURCE_MAX_CONNECTIONS,
- (Gauge<Integer>) dataSource::getMaxTotal);
+ MetricNames.DATASOURCE_ACTIVE_CONNECTIONS, (Gauge<Integer>)
dataSource::getNumActive);
+ registerGauge(MetricNames.DATASOURCE_IDLE_CONNECTIONS, (Gauge<Integer>)
dataSource::getNumIdle);
+ registerGauge(MetricNames.DATASOURCE_MAX_CONNECTIONS, (Gauge<Integer>)
dataSource::getMaxTotal);
}
}
diff --git
a/core/src/main/java/org/apache/gravitino/storage/relational/session/SqlSessionFactoryHelper.java
b/core/src/main/java/org/apache/gravitino/storage/relational/session/SqlSessionFactoryHelper.java
index e31cf1683a..bc406af3b5 100644
---
a/core/src/main/java/org/apache/gravitino/storage/relational/session/SqlSessionFactoryHelper.java
+++
b/core/src/main/java/org/apache/gravitino/storage/relational/session/SqlSessionFactoryHelper.java
@@ -62,61 +62,68 @@ public class SqlSessionFactoryHelper {
*/
@SuppressWarnings("deprecation")
public void init(Config config) {
- // Initialize the data source
- BasicDataSource dataSource = new BasicDataSource();
- String jdbcUrl = config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_URL);
- String driverClass =
config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_DRIVER);
- JdbcUrlUtils.validateJdbcConfig(driverClass, jdbcUrl,
config.getAllConfig());
-
- JDBCBackendType jdbcType = JDBCBackendType.fromURI(jdbcUrl);
- dataSource.setUrl(jdbcUrl);
- dataSource.setDriverClassName(driverClass);
-
dataSource.setUsername(config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_USER));
-
dataSource.setPassword(config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_PASSWORD));
- // Close the auto commit, so that we can control the transaction manual
commit
- dataSource.setDefaultAutoCommit(false);
- dataSource.setMaxWaitMillis(
- config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_WAIT_MILLISECONDS));
-
dataSource.setMaxTotal(config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_MAX_CONNECTIONS));
- dataSource.setMaxIdle(5);
- dataSource.setMinIdle(0);
- dataSource.setLogAbandoned(true);
- dataSource.setRemoveAbandonedOnBorrow(true);
- dataSource.setRemoveAbandonedTimeout(60);
- dataSource.setTimeBetweenEvictionRunsMillis(Duration.ofMillis(10 * 60 *
1000L).toMillis());
- dataSource.setTestOnBorrow(true);
- dataSource.setTestWhileIdle(true);
- dataSource.setMinEvictableIdleTimeMillis(1000);
-
dataSource.setNumTestsPerEvictionRun(BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN);
- dataSource.setTestOnReturn(BaseObjectPoolConfig.DEFAULT_TEST_ON_RETURN);
- dataSource.setSoftMinEvictableIdleTimeMillis(
- BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME.toMillis());
- dataSource.setLifo(BaseObjectPoolConfig.DEFAULT_LIFO);
- MetricsSystem metricsSystem = GravitinoEnv.getInstance().metricsSystem();
- // Add null check to avoid NPE when metrics system is not initialized in
test environments
- if (metricsSystem != null) {
- // Register connection pool metrics when metrics system is available
- metricsSystem.register(new RelationDatasourceMetricsSource(dataSource));
+ // Create the SqlSessionFactory object, it is a singleton object
+ if (sqlSessionFactory != null) {
+ return;
}
- // Create the transaction factory and env
- TransactionFactory transactionFactory = new JdbcTransactionFactory();
- Environment environment = new Environment("development",
transactionFactory, dataSource);
- // Initialize the configuration
- Configuration configuration = new Configuration(environment);
- configuration.setDatabaseId(jdbcType.name().toLowerCase());
- ServiceLoader<MapperPackageProvider> loader =
ServiceLoader.load(MapperPackageProvider.class);
- for (MapperPackageProvider provider : loader) {
- provider.getMapperClasses().forEach(configuration::addMapper);
- }
+ synchronized (SqlSessionFactoryHelper.class) {
+ if (sqlSessionFactory != null) {
+ return;
+ }
- // Create the SqlSessionFactory object, it is a singleton object
- if (sqlSessionFactory == null) {
- synchronized (SqlSessionFactoryHelper.class) {
- if (sqlSessionFactory == null) {
- sqlSessionFactory = new
SqlSessionFactoryBuilder().build(configuration);
- }
+ // Initialize the data source
+ BasicDataSource dataSource = new BasicDataSource();
+ String jdbcUrl = config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_URL);
+ String driverClass =
config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_DRIVER);
+ JdbcUrlUtils.validateJdbcConfig(driverClass, jdbcUrl,
config.getAllConfig());
+
+ JDBCBackendType jdbcType = JDBCBackendType.fromURI(jdbcUrl);
+ dataSource.setUrl(jdbcUrl);
+ dataSource.setDriverClassName(driverClass);
+
dataSource.setUsername(config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_USER));
+
dataSource.setPassword(config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_PASSWORD));
+ // Close the auto commit, so that we can control the transaction manual
commit
+ dataSource.setDefaultAutoCommit(false);
+ dataSource.setMaxWaitMillis(
+
config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_WAIT_MILLISECONDS));
+
dataSource.setMaxTotal(config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_MAX_CONNECTIONS));
+ dataSource.setMaxIdle(5);
+ dataSource.setMinIdle(0);
+ dataSource.setLogAbandoned(true);
+ dataSource.setRemoveAbandonedOnBorrow(true);
+ dataSource.setRemoveAbandonedTimeout(60);
+ dataSource.setTimeBetweenEvictionRunsMillis(Duration.ofMillis(10 * 60 *
1000L).toMillis());
+ dataSource.setTestOnBorrow(true);
+ dataSource.setTestWhileIdle(true);
+ dataSource.setMinEvictableIdleTimeMillis(1000);
+
dataSource.setNumTestsPerEvictionRun(BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN);
+ dataSource.setTestOnReturn(BaseObjectPoolConfig.DEFAULT_TEST_ON_RETURN);
+ dataSource.setSoftMinEvictableIdleTimeMillis(
+
BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME.toMillis());
+ dataSource.setLifo(BaseObjectPoolConfig.DEFAULT_LIFO);
+
+ // Create the transaction factory and env
+ TransactionFactory transactionFactory = new JdbcTransactionFactory();
+ Environment environment = new Environment("development",
transactionFactory, dataSource);
+
+ // Initialize the configuration
+ Configuration configuration = new Configuration(environment);
+ configuration.setDatabaseId(jdbcType.name().toLowerCase());
+ ServiceLoader<MapperPackageProvider> loader =
ServiceLoader.load(MapperPackageProvider.class);
+ for (MapperPackageProvider provider : loader) {
+ provider.getMapperClasses().forEach(configuration::addMapper);
}
+
+ MetricsSystem metricsSystem = GravitinoEnv.getInstance().metricsSystem();
+ // Add null check to avoid NPE when metrics system is not initialized in
test environments
+ if (metricsSystem != null) {
+ // Register connection pool metrics when metrics system is available
+ metricsSystem.register(new
RelationDatasourceMetricsSource(dataSource));
+ }
+
+ // Create the SqlSessionFactory object, it is a singleton object
+ sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
}
}
diff --git
a/core/src/test/java/org/apache/gravitino/metrics/TestExtractMetricNameAndLabel.java
b/core/src/test/java/org/apache/gravitino/metrics/TestExtractMetricNameAndLabel.java
index 1d6e8b74e2..4f3a1feba2 100644
---
a/core/src/test/java/org/apache/gravitino/metrics/TestExtractMetricNameAndLabel.java
+++
b/core/src/test/java/org/apache/gravitino/metrics/TestExtractMetricNameAndLabel.java
@@ -81,33 +81,30 @@ public class TestExtractMetricNameAndLabel {
ImmutableMap.of("operation", "update-table"));
checkResult(
- MetricsSource.GRAVITINO_SERVER_METRIC_NAME
+ MetricsSource.GRAVITINO_RELATIONAL_STORE_METRIC_NAME
+ "."
- + MetricNames.ENTITY_STORE_RELATION_DATASOURCE_ACTIVE_CONNECTIONS,
-
Collector.sanitizeMetricName(MetricsSource.GRAVITINO_SERVER_METRIC_NAME)
+ + MetricNames.DATASOURCE_ACTIVE_CONNECTIONS,
+
Collector.sanitizeMetricName(MetricsSource.GRAVITINO_RELATIONAL_STORE_METRIC_NAME)
+ "_"
- + Collector.sanitizeMetricName(
-
MetricNames.ENTITY_STORE_RELATION_DATASOURCE_ACTIVE_CONNECTIONS),
+ +
Collector.sanitizeMetricName(MetricNames.DATASOURCE_ACTIVE_CONNECTIONS),
ImmutableMap.of());
checkResult(
- MetricsSource.GRAVITINO_SERVER_METRIC_NAME
+ MetricsSource.GRAVITINO_RELATIONAL_STORE_METRIC_NAME
+ "."
- + MetricNames.ENTITY_STORE_RELATION_DATASOURCE_IDLE_CONNECTIONS,
-
Collector.sanitizeMetricName(MetricsSource.GRAVITINO_SERVER_METRIC_NAME)
+ + MetricNames.DATASOURCE_IDLE_CONNECTIONS,
+
Collector.sanitizeMetricName(MetricsSource.GRAVITINO_RELATIONAL_STORE_METRIC_NAME)
+ "_"
- + Collector.sanitizeMetricName(
- MetricNames.ENTITY_STORE_RELATION_DATASOURCE_IDLE_CONNECTIONS),
+ +
Collector.sanitizeMetricName(MetricNames.DATASOURCE_IDLE_CONNECTIONS),
ImmutableMap.of());
checkResult(
- MetricsSource.GRAVITINO_SERVER_METRIC_NAME
+ MetricsSource.GRAVITINO_RELATIONAL_STORE_METRIC_NAME
+ "."
- + MetricNames.ENTITY_STORE_RELATION_DATASOURCE_MAX_CONNECTIONS,
-
Collector.sanitizeMetricName(MetricsSource.GRAVITINO_SERVER_METRIC_NAME)
+ + MetricNames.DATASOURCE_MAX_CONNECTIONS,
+
Collector.sanitizeMetricName(MetricsSource.GRAVITINO_RELATIONAL_STORE_METRIC_NAME)
+ "_"
- + Collector.sanitizeMetricName(
- MetricNames.ENTITY_STORE_RELATION_DATASOURCE_MAX_CONNECTIONS),
+ +
Collector.sanitizeMetricName(MetricNames.DATASOURCE_MAX_CONNECTIONS),
ImmutableMap.of());
}
}
diff --git
a/core/src/test/java/org/apache/gravitino/metrics/TestMetricsSystem.java
b/core/src/test/java/org/apache/gravitino/metrics/TestMetricsSystem.java
index 588e939f8d..35ff879c9e 100644
--- a/core/src/test/java/org/apache/gravitino/metrics/TestMetricsSystem.java
+++ b/core/src/test/java/org/apache/gravitino/metrics/TestMetricsSystem.java
@@ -19,6 +19,7 @@
package org.apache.gravitino.metrics;
+import org.apache.gravitino.metrics.source.MetricsSource;
import org.apache.gravitino.metrics.source.TestMetricsSource;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -26,8 +27,30 @@ import org.junit.jupiter.api.Test;
public class TestMetricsSystem {
private MetricsSystem metricsSystem = new MetricsSystem();
+ private static class MockMetricsSource extends MetricsSource {
+ public MockMetricsSource(String metricsSourceName) {
+ super(metricsSourceName);
+ }
+ }
+
+ private static class Mock2MetricsSource extends MetricsSource {
+ public Mock2MetricsSource(String metricsSourceName) {
+ super(metricsSourceName);
+ }
+ }
+
+ @Test
+ void testRegisterMetricsWithSameMetricsSourceName() {
+ MockMetricsSource metricsSource = new MockMetricsSource("a");
+ Mock2MetricsSource metricsSource2 = new Mock2MetricsSource("a");
+ metricsSystem.register(metricsSource);
+ Assertions.assertThrowsExactly(
+ IllegalStateException.class, () ->
metricsSystem.register(metricsSource2));
+ Assertions.assertDoesNotThrow(() -> metricsSystem.register(metricsSource));
+ }
+
@Test
- void testRegisterMetricsSource() {
+ void testRegisterMetricsSourceInRaceCondition() {
TestMetricsSource metricsSource = new TestMetricsSource();
metricsSystem.register(metricsSource);
metricsSource.incCounter("a.b");